diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Object/ELF.cpp | 1 | ||||
-rw-r--r-- | lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 17 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp | 5 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 3 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h | 3 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 28 | ||||
-rw-r--r-- | lib/Target/Mips/MicroMipsInstrFormats.td | 37 | ||||
-rw-r--r-- | lib/Target/Mips/MicroMipsInstrInfo.td | 24 | ||||
-rw-r--r-- | lib/Target/Mips/Mips64InstrInfo.td | 12 | ||||
-rw-r--r-- | lib/Target/Mips/MipsCodeEmitter.cpp | 8 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFormats.td | 6 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 41 |
12 files changed, 159 insertions, 26 deletions
diff --git a/lib/Object/ELF.cpp b/lib/Object/ELF.cpp index 2c62eb1..7c80d41 100644 --- a/lib/Object/ELF.cpp +++ b/lib/Object/ELF.cpp @@ -165,6 +165,7 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) { 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_GOT16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_PC16_S1); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_CALL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT_DISP); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_GOT_PAGE); diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index f9bf1af..b890d3a 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -205,6 +205,13 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst, uint64_t Address, const void *Decoder); +// DecodeBranchTargetMM - Decode microMIPS branch offset, which is +// shifted left by 1 bit. +static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder); + // DecodeJumpTargetMM - Decode microMIPS jump target, which is // shifted left by 1 bit. static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, @@ -751,6 +758,16 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, + unsigned Offset, + uint64_t Address, + const void *Decoder) { + unsigned BranchOffset = Offset & 0xffff; + BranchOffset = SignExtend32<18>(BranchOffset << 1); + Inst.addOperand(MCOperand::CreateImm(BranchOffset)); + return MCDisassembler::Success; +} + static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index b47bff6..3e70b23 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -84,6 +84,10 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { case Mips::fixup_MICROMIPS_26_S1: Value >>= 1; break; + case Mips::fixup_MICROMIPS_PC16_S1: + Value -= 4; + Value >>= 1; + break; } return Value; @@ -201,6 +205,7 @@ public: { "fixup_MICROMIPS_HI16", 0, 16, 0 }, { "fixup_MICROMIPS_LO16", 0, 16, 0 }, { "fixup_MICROMIPS_GOT16", 0, 16, 0 }, + { "fixup_MICROMIPS_PC16_S1", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_MICROMIPS_CALL16", 0, 16, 0 }, { "fixup_MICROMIPS_GOT_DISP", 0, 16, 0 }, { "fixup_MICROMIPS_GOT_PAGE", 0, 16, 0 }, diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 60c9f33..83c7d4b 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -195,6 +195,9 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, case Mips::fixup_MICROMIPS_GOT16: Type = ELF::R_MICROMIPS_GOT16; break; + case Mips::fixup_MICROMIPS_PC16_S1: + Type = ELF::R_MICROMIPS_PC16_S1; + break; case Mips::fixup_MICROMIPS_CALL16: Type = ELF::R_MICROMIPS_CALL16; break; diff --git a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index ab7eead..6ed44b7 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -140,6 +140,9 @@ namespace Mips { // resulting in - R_MICROMIPS_GOT16 fixup_MICROMIPS_GOT16, + // resulting in - R_MICROMIPS_PC16_S1 + fixup_MICROMIPS_PC16_S1, + // resulting in - R_MICROMIPS_CALL16 fixup_MICROMIPS_CALL16, diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index b965d13..79818ec 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -96,6 +96,12 @@ public: unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const; + // getBranchTargetOpValue - Return binary encoding of the microMIPS branch + // target operand. If the machine operand requires relocation, + // record the relocation and return zero. + unsigned getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const; + // getMachineOpValue - Return binary encoding of operand. If the machin // operand requires relocation, record the relocation and return zero. unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO, @@ -276,6 +282,28 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, return 0; } +/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTargetOpValueMM(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() && + "getBranchTargetOpValueMM expects only expressions or immediates"); + + const MCExpr *Expr = MO.getExpr(); + Fixups.push_back(MCFixup::Create(0, Expr, + MCFixupKind(Mips:: + fixup_MICROMIPS_PC16_S1))); + return 0; +} + /// getJumpTargetOpValue - Return binary encoding of the jump /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index 61a3788..4981608 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -238,3 +238,40 @@ class JALR_FM_MM<bits<10> funct> : MMArch { let Inst{15-6} = funct; let Inst{5-0} = 0x3c; } + +class BEQ_FM_MM<bits<6> op> : MMArch { + bits<5> rs; + bits<5> rt; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = op; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-0} = offset; +} + +class BGEZ_FM_MM<bits<5> funct> : MMArch { + bits<5> rs; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = 0x10; + let Inst{25-21} = funct; + let Inst{20-16} = rs; + let Inst{15-0} = offset; +} + +class BGEZAL_FM_MM<bits<5> funct> : MMArch { + bits<5> rs; + bits<16> offset; + + bits<32> Inst; + + let Inst{31-26} = 0x10; + let Inst{25-21} = funct; + let Inst{20-16} = rs; + let Inst{15-0} = offset; +} diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 41273bc..297b838 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -20,6 +20,12 @@ def calltarget_mm : Operand<iPTR> { let EncoderMethod = "getJumpTargetOpValueMM"; } +def brtarget_mm : Operand<OtherVT> { + let EncoderMethod = "getBranchTargetOpValueMM"; + let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeBranchTargetMM"; +} + let canFoldAsLoad = 1 in class LoadLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO, Operand MemOpnd> : @@ -177,4 +183,22 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { 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>; + + /// Branch Instructions + def BEQ_MM : MMRel, CBranch<"beq", brtarget_mm, seteq, GPR32Opnd>, + BEQ_FM_MM<0x25>; + def BNE_MM : MMRel, CBranch<"bne", brtarget_mm, setne, GPR32Opnd>, + BEQ_FM_MM<0x2d>; + def BGEZ_MM : MMRel, CBranchZero<"bgez", brtarget_mm, setge, GPR32Opnd>, + BGEZ_FM_MM<0x2>; + def BGTZ_MM : MMRel, CBranchZero<"bgtz", brtarget_mm, setgt, GPR32Opnd>, + BGEZ_FM_MM<0x6>; + def BLEZ_MM : MMRel, CBranchZero<"blez", brtarget_mm, setle, GPR32Opnd>, + BGEZ_FM_MM<0x4>; + def BLTZ_MM : MMRel, CBranchZero<"bltz", brtarget_mm, setlt, GPR32Opnd>, + BGEZ_FM_MM<0x0>; + def BGEZAL_MM : MMRel, BGEZAL_FT<"bgezal", brtarget_mm, GPR32Opnd>, + BGEZAL_FM_MM<0x03>; + def BLTZAL_MM : MMRel, BGEZAL_FT<"bltzal", brtarget_mm, GPR32Opnd>, + BGEZAL_FM_MM<0x01>; } diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index 3b74ced..15ef654 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -151,12 +151,12 @@ def SCD : SCBase<"scd", GPR64Opnd>, LW_FM<0x3c>; /// Jump and Branch Instructions let isCodeGenOnly = 1 in { def JR64 : IndirectBranch<"jr", GPR64Opnd>, MTLO_FM<8>; -def BEQ64 : CBranch<"beq", seteq, GPR64Opnd>, BEQ_FM<4>; -def BNE64 : CBranch<"bne", setne, GPR64Opnd>, BEQ_FM<5>; -def BGEZ64 : CBranchZero<"bgez", setge, GPR64Opnd>, BGEZ_FM<1, 1>; -def BGTZ64 : CBranchZero<"bgtz", setgt, GPR64Opnd>, BGEZ_FM<7, 0>; -def BLEZ64 : CBranchZero<"blez", setle, GPR64Opnd>, BGEZ_FM<6, 0>; -def BLTZ64 : CBranchZero<"bltz", setlt, GPR64Opnd>, BGEZ_FM<1, 0>; +def BEQ64 : CBranch<"beq", brtarget, seteq, GPR64Opnd>, BEQ_FM<4>; +def BNE64 : CBranch<"bne", brtarget, setne, GPR64Opnd>, BEQ_FM<5>; +def BGEZ64 : CBranchZero<"bgez", brtarget, setge, GPR64Opnd>, BGEZ_FM<1, 1>; +def BGTZ64 : CBranchZero<"bgtz", brtarget, setgt, GPR64Opnd>, BGEZ_FM<7, 0>; +def BLEZ64 : CBranchZero<"blez", brtarget, setle, GPR64Opnd>, BGEZ_FM<6, 0>; +def BLTZ64 : CBranchZero<"bltz", brtarget, setlt, GPR64Opnd>, BGEZ_FM<1, 0>; def JALR64 : JumpLinkReg<"jalr", GPR64Opnd>, JALR_FM; def JALR64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR, RA, GPR32Opnd>; def TAILCALL64_R : JumpFR<"tcallr", GPR64Opnd, MipsTailCall>, diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp index 3c737e6..f4e1e18 100644 --- a/lib/Target/Mips/MipsCodeEmitter.cpp +++ b/lib/Target/Mips/MipsCodeEmitter.cpp @@ -106,6 +106,8 @@ private: unsigned getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const; unsigned getJumpTargetOpValueMM(const MachineInstr &MI, unsigned OpNo) const; + unsigned getBranchTargetOpValueMM(const MachineInstr &MI, + unsigned OpNo) const; unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const; unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const; @@ -194,6 +196,12 @@ unsigned MipsCodeEmitter::getJumpTargetOpValueMM(const MachineInstr &MI, return 0; } +unsigned MipsCodeEmitter::getBranchTargetOpValueMM(const MachineInstr &MI, + unsigned OpNo) const { + llvm_unreachable("Unimplemented function."); + return 0; +} + unsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const { MachineOperand MO = MI.getOperand(OpNo); diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index c46706b..8f67b2e 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -272,7 +272,7 @@ class SRLV_FM<bits<6> funct, bit rotate> : StdArch { let Inst{5-0} = funct; } -class BEQ_FM<bits<6> op> { +class BEQ_FM<bits<6> op> : StdArch { bits<5> rs; bits<5> rt; bits<16> offset; @@ -285,7 +285,7 @@ class BEQ_FM<bits<6> op> { let Inst{15-0} = offset; } -class BGEZ_FM<bits<6> op, bits<5> funct> { +class BGEZ_FM<bits<6> op, bits<5> funct> : StdArch { bits<5> rs; bits<16> offset; @@ -389,7 +389,7 @@ class JALR_FM : StdArch { let Inst{5-0} = 9; } -class BGEZAL_FM<bits<5> funct> { +class BGEZAL_FM<bits<5> funct> : StdArch { bits<5> rs; bits<16> offset; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index f5a519d..400bee6 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -504,21 +504,24 @@ class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO, } // Conditional Branch -class CBranch<string opstr, PatFrag cond_op, RegisterOperand RO> : - InstSE<(outs), (ins RO:$rs, RO:$rt, brtarget:$offset), +class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op, + RegisterOperand RO> : + InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset), !strconcat(opstr, "\t$rs, $rt, $offset"), [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch, - FrmI> { + FrmI, opstr> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; let Defs = [AT]; } -class CBranchZero<string opstr, PatFrag cond_op, RegisterOperand RO> : - InstSE<(outs), (ins RO:$rs, brtarget:$offset), +class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op, + RegisterOperand RO> : + InstSE<(outs), (ins RO:$rs, opnd:$offset), !strconcat(opstr, "\t$rs, $offset"), - [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, FrmI> { + [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, + FrmI, opstr> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; @@ -602,9 +605,9 @@ let isCall=1, hasDelaySlot=1, Defs = [RA] in { InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), [], IIBranch, FrmR, opstr>; - class BGEZAL_FT<string opstr, RegisterOperand RO> : - InstSE<(outs), (ins RO:$rs, brtarget:$offset), - !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI>; + class BGEZAL_FT<string opstr, DAGOperand opnd, RegisterOperand RO> : + InstSE<(outs), (ins RO:$rs, opnd:$offset), + !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>; } @@ -994,19 +997,23 @@ def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>; def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>, Requires<[RelocStatic, HasStdEnc]>, IsBranch; def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>; -def BEQ : CBranch<"beq", seteq, GPR32Opnd>, BEQ_FM<4>; -def BNE : CBranch<"bne", setne, GPR32Opnd>, BEQ_FM<5>; -def BGEZ : CBranchZero<"bgez", setge, GPR32Opnd>, BGEZ_FM<1, 1>; -def BGTZ : CBranchZero<"bgtz", setgt, GPR32Opnd>, BGEZ_FM<7, 0>; -def BLEZ : CBranchZero<"blez", setle, GPR32Opnd>, BGEZ_FM<6, 0>; -def BLTZ : CBranchZero<"bltz", setlt, GPR32Opnd>, BGEZ_FM<1, 0>; +def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>; +def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>; +def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>, + BGEZ_FM<1, 1>; +def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>, + BGEZ_FM<7, 0>; +def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>, + BGEZ_FM<6, 0>; +def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>, + BGEZ_FM<1, 0>; def B : UncondBranch<BEQ>; def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>; def JALR : MMRel, JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM; def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>; -def BGEZAL : BGEZAL_FT<"bgezal", GPR32Opnd>, BGEZAL_FM<0x11>; -def BLTZAL : BGEZAL_FT<"bltzal", GPR32Opnd>, BGEZAL_FM<0x10>; +def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>; +def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>; def BAL_BR : BAL_BR_Pseudo<BGEZAL>; def TAILCALL : MMRel, JumpFJ<calltarget, "j", MipsTailCall, imm, "tcall">, FJ<2>, IsTailCall; |