mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-24 21:00:36 +00:00
Support for microMIPS jump instructions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193623 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
54328c772c
commit
1aaf43c2a2
@ -881,6 +881,7 @@ enum {
|
|||||||
R_MIPS_GLOB_DAT = 51,
|
R_MIPS_GLOB_DAT = 51,
|
||||||
R_MIPS_COPY = 126,
|
R_MIPS_COPY = 126,
|
||||||
R_MIPS_JUMP_SLOT = 127,
|
R_MIPS_JUMP_SLOT = 127,
|
||||||
|
R_MICROMIPS_26_S1 = 133,
|
||||||
R_MICROMIPS_HI16 = 134,
|
R_MICROMIPS_HI16 = 134,
|
||||||
R_MICROMIPS_LO16 = 135,
|
R_MICROMIPS_LO16 = 135,
|
||||||
R_MICROMIPS_GOT16 = 138,
|
R_MICROMIPS_GOT16 = 138,
|
||||||
|
@ -161,6 +161,7 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) {
|
|||||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT);
|
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT);
|
||||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY);
|
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY);
|
||||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT);
|
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT);
|
||||||
|
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_26_S1);
|
||||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_HI16);
|
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_HI16);
|
||||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_LO16);
|
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_LO16);
|
||||||
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT16);
|
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT16);
|
||||||
|
@ -205,6 +205,13 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst,
|
|||||||
uint64_t Address,
|
uint64_t Address,
|
||||||
const void *Decoder);
|
const void *Decoder);
|
||||||
|
|
||||||
|
// DecodeJumpTargetMM - Decode microMIPS jump target, which is
|
||||||
|
// shifted left by 1 bit.
|
||||||
|
static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
|
||||||
|
unsigned Insn,
|
||||||
|
uint64_t Address,
|
||||||
|
const void *Decoder);
|
||||||
|
|
||||||
static DecodeStatus DecodeMem(MCInst &Inst,
|
static DecodeStatus DecodeMem(MCInst &Inst,
|
||||||
unsigned Insn,
|
unsigned Insn,
|
||||||
uint64_t Address,
|
uint64_t Address,
|
||||||
@ -744,6 +751,14 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst,
|
|||||||
return MCDisassembler::Success;
|
return MCDisassembler::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
|
||||||
|
unsigned Insn,
|
||||||
|
uint64_t Address,
|
||||||
|
const void *Decoder) {
|
||||||
|
unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
|
||||||
|
Inst.addOperand(MCOperand::CreateImm(JumpOffset));
|
||||||
|
return MCDisassembler::Success;
|
||||||
|
}
|
||||||
|
|
||||||
static DecodeStatus DecodeSimm16(MCInst &Inst,
|
static DecodeStatus DecodeSimm16(MCInst &Inst,
|
||||||
unsigned Insn,
|
unsigned Insn,
|
||||||
|
@ -81,6 +81,9 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
|
|||||||
// Get the 4th 16-bits.
|
// Get the 4th 16-bits.
|
||||||
Value = ((Value + 0x800080008000LL) >> 48) & 0xffff;
|
Value = ((Value + 0x800080008000LL) >> 48) & 0xffff;
|
||||||
break;
|
break;
|
||||||
|
case Mips::fixup_MICROMIPS_26_S1:
|
||||||
|
Value >>= 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Value;
|
return Value;
|
||||||
@ -194,6 +197,7 @@ public:
|
|||||||
{ "fixup_Mips_GOT_LO16", 0, 16, 0 },
|
{ "fixup_Mips_GOT_LO16", 0, 16, 0 },
|
||||||
{ "fixup_Mips_CALL_HI16", 0, 16, 0 },
|
{ "fixup_Mips_CALL_HI16", 0, 16, 0 },
|
||||||
{ "fixup_Mips_CALL_LO16", 0, 16, 0 },
|
{ "fixup_Mips_CALL_LO16", 0, 16, 0 },
|
||||||
|
{ "fixup_MICROMIPS_26_S1", 0, 26, 0 },
|
||||||
{ "fixup_MICROMIPS_HI16", 0, 16, 0 },
|
{ "fixup_MICROMIPS_HI16", 0, 16, 0 },
|
||||||
{ "fixup_MICROMIPS_LO16", 0, 16, 0 },
|
{ "fixup_MICROMIPS_LO16", 0, 16, 0 },
|
||||||
{ "fixup_MICROMIPS_GOT16", 0, 16, 0 },
|
{ "fixup_MICROMIPS_GOT16", 0, 16, 0 },
|
||||||
|
@ -183,6 +183,9 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
|
|||||||
case Mips::fixup_Mips_CALL_LO16:
|
case Mips::fixup_Mips_CALL_LO16:
|
||||||
Type = ELF::R_MIPS_CALL_LO16;
|
Type = ELF::R_MIPS_CALL_LO16;
|
||||||
break;
|
break;
|
||||||
|
case Mips::fixup_MICROMIPS_26_S1:
|
||||||
|
Type = ELF::R_MICROMIPS_26_S1;
|
||||||
|
break;
|
||||||
case Mips::fixup_MICROMIPS_HI16:
|
case Mips::fixup_MICROMIPS_HI16:
|
||||||
Type = ELF::R_MICROMIPS_HI16;
|
Type = ELF::R_MICROMIPS_HI16;
|
||||||
break;
|
break;
|
||||||
|
@ -128,6 +128,9 @@ namespace Mips {
|
|||||||
// resulting in - R_MIPS_CALL_LO16
|
// resulting in - R_MIPS_CALL_LO16
|
||||||
fixup_Mips_CALL_LO16,
|
fixup_Mips_CALL_LO16,
|
||||||
|
|
||||||
|
// resulting in - R_MICROMIPS_26_S1
|
||||||
|
fixup_MICROMIPS_26_S1,
|
||||||
|
|
||||||
// resulting in - R_MICROMIPS_HI16
|
// resulting in - R_MICROMIPS_HI16
|
||||||
fixup_MICROMIPS_HI16,
|
fixup_MICROMIPS_HI16,
|
||||||
|
|
||||||
|
@ -84,6 +84,12 @@ public:
|
|||||||
unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
|
unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
|
|
||||||
|
// getBranchJumpOpValueMM - Return binary encoding of the microMIPS jump
|
||||||
|
// target operand. If the machine operand requires relocation,
|
||||||
|
// record the relocation and return zero.
|
||||||
|
unsigned getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
|
||||||
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
|
|
||||||
// getBranchTargetOpValue - Return binary encoding of the branch
|
// getBranchTargetOpValue - Return binary encoding of the branch
|
||||||
// target operand. If the machine operand requires relocation,
|
// target operand. If the machine operand requires relocation,
|
||||||
// record the relocation and return zero.
|
// record the relocation and return zero.
|
||||||
@ -290,6 +296,23 @@ getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned MipsMCCodeEmitter::
|
||||||
|
getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
|
||||||
|
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||||
|
|
||||||
|
const MCOperand &MO = MI.getOperand(OpNo);
|
||||||
|
// If the destination is an immediate, divide by 2.
|
||||||
|
if (MO.isImm()) return MO.getImm() >> 1;
|
||||||
|
|
||||||
|
assert(MO.isExpr() &&
|
||||||
|
"getJumpTargetOpValueMM expects only expressions or an immediate");
|
||||||
|
|
||||||
|
const MCExpr *Expr = MO.getExpr();
|
||||||
|
Fixups.push_back(MCFixup::Create(0, Expr,
|
||||||
|
MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned MipsMCCodeEmitter::
|
unsigned MipsMCCodeEmitter::
|
||||||
getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const {
|
getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const {
|
||||||
int64_t Res;
|
int64_t Res;
|
||||||
|
@ -204,3 +204,37 @@ class EXT_FM_MM<bits<6> funct> : MMArch {
|
|||||||
let Inst{10-6} = pos;
|
let Inst{10-6} = pos;
|
||||||
let Inst{5-0} = funct;
|
let Inst{5-0} = funct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class J_FM_MM<bits<6> op> : MMArch {
|
||||||
|
bits<26> target;
|
||||||
|
|
||||||
|
bits<32> Inst;
|
||||||
|
|
||||||
|
let Inst{31-26} = op;
|
||||||
|
let Inst{25-0} = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
class JR_FM_MM<bits<8> funct> : MMArch {
|
||||||
|
bits<5> rs;
|
||||||
|
|
||||||
|
bits<32> Inst;
|
||||||
|
|
||||||
|
let Inst{31-21} = 0x00;
|
||||||
|
let Inst{20-16} = rs;
|
||||||
|
let Inst{15-14} = 0x0;
|
||||||
|
let Inst{13-6} = funct;
|
||||||
|
let Inst{5-0} = 0x3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
class JALR_FM_MM<bits<10> funct> : MMArch {
|
||||||
|
bits<5> rs;
|
||||||
|
bits<5> rd;
|
||||||
|
|
||||||
|
bits<32> Inst;
|
||||||
|
|
||||||
|
let Inst{31-26} = 0x00;
|
||||||
|
let Inst{25-21} = rd;
|
||||||
|
let Inst{20-16} = rs;
|
||||||
|
let Inst{15-6} = funct;
|
||||||
|
let Inst{5-0} = 0x3c;
|
||||||
|
}
|
||||||
|
@ -12,6 +12,14 @@ def mem_mm_12 : Operand<i32> {
|
|||||||
let OperandType = "OPERAND_MEMORY";
|
let OperandType = "OPERAND_MEMORY";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def jmptarget_mm : Operand<OtherVT> {
|
||||||
|
let EncoderMethod = "getJumpTargetOpValueMM";
|
||||||
|
}
|
||||||
|
|
||||||
|
def calltarget_mm : Operand<iPTR> {
|
||||||
|
let EncoderMethod = "getJumpTargetOpValueMM";
|
||||||
|
}
|
||||||
|
|
||||||
let canFoldAsLoad = 1 in
|
let canFoldAsLoad = 1 in
|
||||||
class LoadLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
|
class LoadLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
|
||||||
Operand MemOpnd> :
|
Operand MemOpnd> :
|
||||||
@ -155,4 +163,18 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
|
|||||||
EXT_FM_MM<0x2c>;
|
EXT_FM_MM<0x2c>;
|
||||||
def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>,
|
def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>,
|
||||||
EXT_FM_MM<0x0c>;
|
EXT_FM_MM<0x0c>;
|
||||||
|
|
||||||
|
/// Jump Instructions
|
||||||
|
let DecoderMethod = "DecodeJumpTargetMM" in {
|
||||||
|
def J_MM : MMRel, JumpFJ<jmptarget_mm, "j", br, bb, "j">,
|
||||||
|
J_FM_MM<0x35>;
|
||||||
|
def JAL_MM : MMRel, JumpLink<"jal", calltarget_mm>, J_FM_MM<0x3d>;
|
||||||
|
def TAILCALL_MM : MMRel, JumpFJ<calltarget_mm, "j", MipsTailCall, imm,
|
||||||
|
"tcall">, J_FM_MM<0x3d>, IsTailCall;
|
||||||
|
}
|
||||||
|
def JR_MM : MMRel, IndirectBranch<"jr", GPR32Opnd>, JR_FM_MM<0x3c>;
|
||||||
|
def JALR_MM : MMRel, JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM_MM<0x03c>;
|
||||||
|
def TAILCALL_R_MM : MMRel, JumpFR<"tcallr", GPR32Opnd, MipsTailCall>,
|
||||||
|
JR_FM_MM<0x3c>, IsTailCall;
|
||||||
|
def RET_MM : MMRel, RetBase<"ret", GPR32Opnd>, JR_FM_MM<0x3c>;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ def SCD : SCBase<"scd", GPR64Opnd>, LW_FM<0x3c>;
|
|||||||
|
|
||||||
/// Jump and Branch Instructions
|
/// Jump and Branch Instructions
|
||||||
let isCodeGenOnly = 1 in {
|
let isCodeGenOnly = 1 in {
|
||||||
def JR64 : IndirectBranch<GPR64Opnd>, MTLO_FM<8>;
|
def JR64 : IndirectBranch<"jr", GPR64Opnd>, MTLO_FM<8>;
|
||||||
def BEQ64 : CBranch<"beq", seteq, GPR64Opnd>, BEQ_FM<4>;
|
def BEQ64 : CBranch<"beq", seteq, GPR64Opnd>, BEQ_FM<4>;
|
||||||
def BNE64 : CBranch<"bne", setne, GPR64Opnd>, BEQ_FM<5>;
|
def BNE64 : CBranch<"bne", setne, GPR64Opnd>, BEQ_FM<5>;
|
||||||
def BGEZ64 : CBranchZero<"bgez", setge, GPR64Opnd>, BGEZ_FM<1, 1>;
|
def BGEZ64 : CBranchZero<"bgez", setge, GPR64Opnd>, BGEZ_FM<1, 1>;
|
||||||
@ -159,7 +159,8 @@ def BLEZ64 : CBranchZero<"blez", setle, GPR64Opnd>, BGEZ_FM<6, 0>;
|
|||||||
def BLTZ64 : CBranchZero<"bltz", setlt, GPR64Opnd>, BGEZ_FM<1, 0>;
|
def BLTZ64 : CBranchZero<"bltz", setlt, GPR64Opnd>, BGEZ_FM<1, 0>;
|
||||||
def JALR64 : JumpLinkReg<"jalr", GPR64Opnd>, JALR_FM;
|
def JALR64 : JumpLinkReg<"jalr", GPR64Opnd>, JALR_FM;
|
||||||
def JALR64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR, RA, GPR32Opnd>;
|
def JALR64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR, RA, GPR32Opnd>;
|
||||||
def TAILCALL64_R : JumpFR<GPR64Opnd, MipsTailCall>, MTLO_FM<8>, IsTailCall;
|
def TAILCALL64_R : JumpFR<"tcallr", GPR64Opnd, MipsTailCall>,
|
||||||
|
MTLO_FM<8>, IsTailCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Multiply and Divide Instructions.
|
/// Multiply and Divide Instructions.
|
||||||
|
@ -105,6 +105,7 @@ private:
|
|||||||
const MachineOperand &MO) const;
|
const MachineOperand &MO) const;
|
||||||
|
|
||||||
unsigned getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
|
unsigned getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
|
unsigned getJumpTargetOpValueMM(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
|
|
||||||
unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
|
unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
@ -187,6 +188,12 @@ unsigned MipsCodeEmitter::getJumpTargetOpValue(const MachineInstr &MI,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned MipsCodeEmitter::getJumpTargetOpValueMM(const MachineInstr &MI,
|
||||||
|
unsigned OpNo) const {
|
||||||
|
llvm_unreachable("Unimplemented function.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
|
unsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
|
||||||
unsigned OpNo) const {
|
unsigned OpNo) const {
|
||||||
MachineOperand MO = MI.getOperand(OpNo);
|
MachineOperand MO = MI.getOperand(OpNo);
|
||||||
|
@ -183,7 +183,7 @@ class BranchBase<bits<6> op, dag outs, dag ins, string asmstr,
|
|||||||
// Format J instruction class in Mips : <|opcode|address|>
|
// Format J instruction class in Mips : <|opcode|address|>
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
class FJ<bits<6> op>
|
class FJ<bits<6> op> : StdArch
|
||||||
{
|
{
|
||||||
bits<26> target;
|
bits<26> target;
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ class LUI_FM : StdArch {
|
|||||||
let Inst{15-0} = imm16;
|
let Inst{15-0} = imm16;
|
||||||
}
|
}
|
||||||
|
|
||||||
class JALR_FM {
|
class JALR_FM : StdArch {
|
||||||
bits<5> rd;
|
bits<5> rd;
|
||||||
bits<5> rs;
|
bits<5> rs;
|
||||||
|
|
||||||
|
@ -541,9 +541,9 @@ class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
|
|||||||
|
|
||||||
// Jump
|
// Jump
|
||||||
class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
|
class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
|
||||||
SDPatternOperator targetoperator> :
|
SDPatternOperator targetoperator, string bopstr> :
|
||||||
InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
|
InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
|
||||||
[(operator targetoperator:$target)], IIBranch, FrmJ> {
|
[(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> {
|
||||||
let isTerminator=1;
|
let isTerminator=1;
|
||||||
let isBarrier=1;
|
let isBarrier=1;
|
||||||
let hasDelaySlot = 1;
|
let hasDelaySlot = 1;
|
||||||
@ -565,17 +565,20 @@ class UncondBranch<Instruction BEQInst> :
|
|||||||
|
|
||||||
// Base class for indirect branch and return instruction classes.
|
// Base class for indirect branch and return instruction classes.
|
||||||
let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
|
let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
|
||||||
class JumpFR<RegisterOperand RO, SDPatternOperator operator = null_frag>:
|
class JumpFR<string opstr, RegisterOperand RO,
|
||||||
InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch, FrmR>;
|
SDPatternOperator operator = null_frag>:
|
||||||
|
InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch,
|
||||||
|
FrmR, opstr>;
|
||||||
|
|
||||||
// Indirect branch
|
// Indirect branch
|
||||||
class IndirectBranch<RegisterOperand RO>: JumpFR<RO, brind> {
|
class IndirectBranch<string opstr, RegisterOperand RO> :
|
||||||
|
JumpFR<opstr, RO, brind> {
|
||||||
let isBranch = 1;
|
let isBranch = 1;
|
||||||
let isIndirectBranch = 1;
|
let isIndirectBranch = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return instruction
|
// Return instruction
|
||||||
class RetBase<RegisterOperand RO>: JumpFR<RO> {
|
class RetBase<string opstr, RegisterOperand RO>: JumpFR<opstr, RO> {
|
||||||
let isReturn = 1;
|
let isReturn = 1;
|
||||||
let isCodeGenOnly = 1;
|
let isCodeGenOnly = 1;
|
||||||
let hasCtrlDep = 1;
|
let hasCtrlDep = 1;
|
||||||
@ -584,9 +587,9 @@ class RetBase<RegisterOperand RO>: JumpFR<RO> {
|
|||||||
|
|
||||||
// Jump and Link (Call)
|
// Jump and Link (Call)
|
||||||
let isCall=1, hasDelaySlot=1, Defs = [RA] in {
|
let isCall=1, hasDelaySlot=1, Defs = [RA] in {
|
||||||
class JumpLink<string opstr> :
|
class JumpLink<string opstr, DAGOperand opnd> :
|
||||||
InstSE<(outs), (ins calltarget:$target), !strconcat(opstr, "\t$target"),
|
InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
|
||||||
[(MipsJmpLink imm:$target)], IIBranch, FrmJ> {
|
[(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> {
|
||||||
let DecoderMethod = "DecodeJumpTarget";
|
let DecoderMethod = "DecodeJumpTarget";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,7 +600,7 @@ let isCall=1, hasDelaySlot=1, Defs = [RA] in {
|
|||||||
|
|
||||||
class JumpLinkReg<string opstr, RegisterOperand RO>:
|
class JumpLinkReg<string opstr, RegisterOperand RO>:
|
||||||
InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
|
InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
|
||||||
[], IIBranch, FrmR>;
|
[], IIBranch, FrmR, opstr>;
|
||||||
|
|
||||||
class BGEZAL_FT<string opstr, RegisterOperand RO> :
|
class BGEZAL_FT<string opstr, RegisterOperand RO> :
|
||||||
InstSE<(outs), (ins RO:$rs, brtarget:$offset),
|
InstSE<(outs), (ins RO:$rs, brtarget:$offset),
|
||||||
@ -988,9 +991,9 @@ def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>;
|
|||||||
def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>;
|
def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>;
|
||||||
|
|
||||||
/// Jump and Branch Instructions
|
/// Jump and Branch Instructions
|
||||||
def J : JumpFJ<jmptarget, "j", br, bb>, FJ<2>,
|
def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
|
||||||
Requires<[RelocStatic, HasStdEnc]>, IsBranch;
|
Requires<[RelocStatic, HasStdEnc]>, IsBranch;
|
||||||
def JR : IndirectBranch<GPR32Opnd>, MTLO_FM<8>;
|
def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
|
||||||
def BEQ : CBranch<"beq", seteq, GPR32Opnd>, BEQ_FM<4>;
|
def BEQ : CBranch<"beq", seteq, GPR32Opnd>, BEQ_FM<4>;
|
||||||
def BNE : CBranch<"bne", setne, GPR32Opnd>, BEQ_FM<5>;
|
def BNE : CBranch<"bne", setne, GPR32Opnd>, BEQ_FM<5>;
|
||||||
def BGEZ : CBranchZero<"bgez", setge, GPR32Opnd>, BGEZ_FM<1, 1>;
|
def BGEZ : CBranchZero<"bgez", setge, GPR32Opnd>, BGEZ_FM<1, 1>;
|
||||||
@ -999,16 +1002,18 @@ def BLEZ : CBranchZero<"blez", setle, GPR32Opnd>, BGEZ_FM<6, 0>;
|
|||||||
def BLTZ : CBranchZero<"bltz", setlt, GPR32Opnd>, BGEZ_FM<1, 0>;
|
def BLTZ : CBranchZero<"bltz", setlt, GPR32Opnd>, BGEZ_FM<1, 0>;
|
||||||
def B : UncondBranch<BEQ>;
|
def B : UncondBranch<BEQ>;
|
||||||
|
|
||||||
def JAL : JumpLink<"jal">, FJ<3>;
|
def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
|
||||||
def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
|
def JALR : MMRel, JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
|
||||||
def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
|
def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
|
||||||
def BGEZAL : BGEZAL_FT<"bgezal", GPR32Opnd>, BGEZAL_FM<0x11>;
|
def BGEZAL : BGEZAL_FT<"bgezal", GPR32Opnd>, BGEZAL_FM<0x11>;
|
||||||
def BLTZAL : BGEZAL_FT<"bltzal", GPR32Opnd>, BGEZAL_FM<0x10>;
|
def BLTZAL : BGEZAL_FT<"bltzal", GPR32Opnd>, BGEZAL_FM<0x10>;
|
||||||
def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
|
def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
|
||||||
def TAILCALL : JumpFJ<calltarget, "j", MipsTailCall, imm>, FJ<2>, IsTailCall;
|
def TAILCALL : MMRel, JumpFJ<calltarget, "j", MipsTailCall, imm, "tcall">,
|
||||||
def TAILCALL_R : JumpFR<GPR32Opnd, MipsTailCall>, MTLO_FM<8>, IsTailCall;
|
FJ<2>, IsTailCall;
|
||||||
|
def TAILCALL_R : MMRel, JumpFR<"tcallr", GPR32Opnd, MipsTailCall>, MTLO_FM<8>,
|
||||||
|
IsTailCall;
|
||||||
|
|
||||||
def RET : RetBase<GPR32Opnd>, MTLO_FM<8>;
|
def RET : MMRel, RetBase<"ret", GPR32Opnd>, MTLO_FM<8>;
|
||||||
|
|
||||||
// Exception handling related node and instructions.
|
// Exception handling related node and instructions.
|
||||||
// The conversion sequence is:
|
// The conversion sequence is:
|
||||||
|
@ -213,3 +213,15 @@
|
|||||||
|
|
||||||
# CHECK: ins $9, $6, 3, 7
|
# CHECK: ins $9, $6, 3, 7
|
||||||
0x01 0x26 0x48 0xcc
|
0x01 0x26 0x48 0xcc
|
||||||
|
|
||||||
|
# CHECK: j 1328
|
||||||
|
0xd4 0x00 0x02 0x98
|
||||||
|
|
||||||
|
# CHECK: jal 1328
|
||||||
|
0xf4 0x00 0x02 0x98
|
||||||
|
|
||||||
|
# CHECK: jalr $ra, $6
|
||||||
|
0x03 0xe6 0x0f 0x3c
|
||||||
|
|
||||||
|
# CHECK: jr $7
|
||||||
|
0x00 0x07 0x0f 0x3c
|
||||||
|
@ -213,3 +213,15 @@
|
|||||||
|
|
||||||
# CHECK: ins $9, $6, 3, 7
|
# CHECK: ins $9, $6, 3, 7
|
||||||
0x26 0x01 0xcc 0x48
|
0x26 0x01 0xcc 0x48
|
||||||
|
|
||||||
|
# CHECK: j 1328
|
||||||
|
0x00 0xd4 0x98 0x02
|
||||||
|
|
||||||
|
# CHECK: jal 1328
|
||||||
|
0x00 0xf4 0x98 0x02
|
||||||
|
|
||||||
|
# CHECK: jalr $ra, $6
|
||||||
|
0xe6 0x03 0x3c 0x0f
|
||||||
|
|
||||||
|
# CHECK: jr $7
|
||||||
|
0x07 0x00 0x3c 0x0f
|
||||||
|
40
test/MC/Mips/micromips-jump-instructions.s
Normal file
40
test/MC/Mips/micromips-jump-instructions.s
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# RUN: llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips \
|
||||||
|
# RUN: | FileCheck %s -check-prefix=CHECK-EL
|
||||||
|
# RUN: llvm-mc %s -triple=mips -show-encoding -mattr=micromips \
|
||||||
|
# RUN: | FileCheck %s -check-prefix=CHECK-EB
|
||||||
|
# Check that the assembler can handle the documented syntax
|
||||||
|
# for jump and branch instructions.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Jump instructions
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Little endian
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# CHECK-EL: j 1328 # encoding: [0x00,0xd4,0x98,0x02]
|
||||||
|
# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
# CHECK-EL: jal 1328 # encoding: [0x00,0xf4,0x98,0x02]
|
||||||
|
# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
# CHECK-EL: jalr $6 # encoding: [0xe6,0x03,0x3c,0x0f]
|
||||||
|
# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
# CHECK-EL: jr $7 # encoding: [0x07,0x00,0x3c,0x0f]
|
||||||
|
# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
# CHECK-EL: jr $7 # encoding: [0x07,0x00,0x3c,0x0f]
|
||||||
|
# CHECK-EL: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Big endian
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# CHECK-EB: j 1328 # encoding: [0xd4,0x00,0x02,0x98]
|
||||||
|
# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
# CHECK-EB: jal 1328 # encoding: [0xf4,0x00,0x02,0x98]
|
||||||
|
# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
# CHECK-EB: jalr $6 # encoding: [0x03,0xe6,0x0f,0x3c]
|
||||||
|
# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
# CHECK-EB: jr $7 # encoding: [0x00,0x07,0x0f,0x3c]
|
||||||
|
# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
# CHECK-EB: jr $7 # encoding: [0x00,0x07,0x0f,0x3c]
|
||||||
|
# CHECK-EB: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
|
||||||
|
j 1328
|
||||||
|
jal 1328
|
||||||
|
jalr $6
|
||||||
|
jr $7
|
||||||
|
j $7
|
23
test/MC/Mips/micromips-jump26.s
Normal file
23
test/MC/Mips/micromips-jump26.s
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding \
|
||||||
|
# RUN: -mattr=micromips | FileCheck %s -check-prefix=CHECK-FIXUP
|
||||||
|
# RUN: llvm-mc %s -filetype=obj -triple=mipsel-unknown-linux \
|
||||||
|
# RUN: -mattr=micromips | llvm-readobj -r \
|
||||||
|
# RUN: | FileCheck %s -check-prefix=CHECK-ELF
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Check that the assembler can handle the documented syntax
|
||||||
|
# for relocations.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# CHECK-FIXUP: foo:
|
||||||
|
# CHECK-FIXUP: jal bar # encoding: [A,0xf4'A',A,0b000000AA]
|
||||||
|
# CHECK-FIXUP: # fixup A - offset: 0,
|
||||||
|
# CHECK-FIXUP: value: bar, kind: fixup_MICROMIPS_26_S1
|
||||||
|
# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Check that the appropriate relocations were created.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# CHECK-ELF: Relocations [
|
||||||
|
# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_26_S1
|
||||||
|
# CHECK-ELF: ]
|
||||||
|
|
||||||
|
foo:
|
||||||
|
jal bar
|
26
test/MC/Mips/micromips-tailr.s
Normal file
26
test/MC/Mips/micromips-tailr.s
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding \
|
||||||
|
# RUN: -mattr=micromips | FileCheck %s -check-prefix=CHECK-FIXUP
|
||||||
|
# RUN: llvm-mc %s -filetype=obj -triple=mipsel-unknown-linux \
|
||||||
|
# RUN: -mattr=micromips | llvm-readobj -r \
|
||||||
|
# RUN: | FileCheck %s -check-prefix=CHECK-ELF
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Check that the assembler can handle the documented syntax
|
||||||
|
# for relocations.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# CHECK-FIXUP: foo:
|
||||||
|
# CHECK-FIXUP: addiu $2, $zero, 1332
|
||||||
|
# CHECK-FIXUP: # encoding: [0x40,0x30,0x34,0x05]
|
||||||
|
# CHECK-FIXUP: j foo # encoding: [A,0xd4'A',A,0b000000AA]
|
||||||
|
# CHECK-FIXUP: # fixup A - offset: 0,
|
||||||
|
# CHECK-FIXUP: value: foo, kind: fixup_MICROMIPS_26_S1
|
||||||
|
# CHECK-FIXUP: nop # encoding: [0x00,0x00,0x00,0x00]
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Check that the appropriate relocations were created.
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# CHECK-ELF: Relocations [
|
||||||
|
# CHECK-ELF: 0x{{[0-9,A-F]+}} R_MICROMIPS_26_S1
|
||||||
|
# CHECK-ELF: ]
|
||||||
|
|
||||||
|
foo:
|
||||||
|
addiu $2, $0, 1332
|
||||||
|
j foo
|
Loading…
x
Reference in New Issue
Block a user