diff --git a/lib/Target/ARM/ARMAsmBackend.cpp b/lib/Target/ARM/ARMAsmBackend.cpp index 096d340a626..e4acd667307 100644 --- a/lib/Target/ARM/ARMAsmBackend.cpp +++ b/lib/Target/ARM/ARMAsmBackend.cpp @@ -123,6 +123,8 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { return Value; } + case ARM::fixup_thumb_adr_pcrel_10: + return ((Value - 4) >> 2) & 0xff; case ARM::fixup_arm_adr_pcrel_12: { // ARM PC-relative values are offset by 8. Value -= 8; @@ -358,6 +360,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { case ARM::fixup_arm_thumb_bcc: case ARM::fixup_arm_thumb_cp: + case ARM::fixup_thumb_adr_pcrel_10: return 1; case ARM::fixup_arm_thumb_br: diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 572d691afe0..267c5ddf0df 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -747,11 +747,13 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { return; } case ARM::LEApcrel: + case ARM::tLEApcrel: case ARM::t2LEApcrel: { // FIXME: Need to also handle globals and externals MCInst TmpInst; - TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel - ? ARM::t2ADR : ARM::ADR); + TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR + : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR + : ARM::ADR)); populateADROperands(TmpInst, MI->getOperand(0).getReg(), GetCPISymbol(MI->getOperand(1).getIndex()), MI->getOperand(2).getImm(), MI->getOperand(3).getReg(), @@ -759,11 +761,13 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { OutStreamer.EmitInstruction(TmpInst); return; } - case ARM::t2LEApcrelJT: - case ARM::LEApcrelJT: { + case ARM::LEApcrelJT: + case ARM::tLEApcrelJT: + case ARM::t2LEApcrelJT: { MCInst TmpInst; - TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT - ? ARM::t2ADR : ARM::ADR); + TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR + : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR + : ARM::ADR)); populateADROperands(TmpInst, MI->getOperand(0).getReg(), GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), MI->getOperand(2).getImm()), diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 0c403a9a059..38386b81bdb 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -171,6 +171,8 @@ namespace { const { return 0; } unsigned getAdrLabelOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getThumbAdrLabelOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getThumbBLTargetOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getThumbBLXTargetOpValue(const MachineInstr &MI, unsigned Op) diff --git a/lib/Target/ARM/ARMFixupKinds.h b/lib/Target/ARM/ARMFixupKinds.h index eb568da38ef..3e0bd0e7b7a 100644 --- a/lib/Target/ARM/ARMFixupKinds.h +++ b/lib/Target/ARM/ARMFixupKinds.h @@ -30,6 +30,10 @@ enum Fixups { // fixup_t2_pcrel_10 - Equivalent to fixup_arm_pcrel_10, accounting for // the short-swapped encoding of Thumb2 instructions. fixup_t2_pcrel_10, + // fixup_thumb_adr_pcrel_10 - 10-bit PC relative relocation for symbol + // addresses where the lower 2 bits are not encoded (so it's encoded as an + // 8-bit immediate). + fixup_thumb_adr_pcrel_10, // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR // instruction. fixup_arm_adr_pcrel_12, diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 2bbdb87b36c..7dcb1d7ec3d 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -67,6 +67,11 @@ def thumb_immshifted_shamt : SDNodeXFormgetTargetConstant(V, MVT::i32); }]>; +// ADR instruction labels. +def t_adrlabel : Operand { + let EncoderMethod = "getThumbAdrLabelOpValue"; +} + // Scaled 4 immediate. def t_imm_s4 : Operand { let PrintMethod = "printThumbS4ImmOperand"; @@ -1303,25 +1308,23 @@ def tMOVCCi : T1pIt<(outs tGPR:$Rdn), (ins tGPR:$Rn, i32imm:$Rm), IIC_iCMOVi, // tLEApcrel - Load a pc-relative address into a register without offending the // assembler. -let neverHasSideEffects = 1, isReMaterializable = 1 in -def tLEApcrel : T1I<(outs tGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi, - "adr${p}\t$Rd, #$label", []>, - T1Encoding<{1,0,1,0,0,?}> { - // A6.2 & A8.6.10 + +def tADR : T1I<(outs tGPR:$Rd), (ins t_adrlabel:$addr, pred:$p), + IIC_iALUi, "adr{$p}\t$Rd, #$addr", []>, + T1Encoding<{1,0,1,0,0,?}> { bits<3> Rd; + bits<8> addr; let Inst{10-8} = Rd; - // FIXME: Add label encoding/fixup + let Inst{7-0} = addr; } -def tLEApcrelJT : T1I<(outs tGPR:$Rd), - (ins i32imm:$label, nohash_imm:$id, pred:$p), - IIC_iALUi, "adr${p}\t$Rd, #${label}_${id}", []>, - T1Encoding<{1,0,1,0,0,?}> { - // A6.2 & A8.6.10 - bits<3> Rd; - let Inst{10-8} = Rd; - // FIXME: Add label encoding/fixup -} +let neverHasSideEffects = 1, isReMaterializable = 1 in +def tLEApcrel : tPseudoInst<(outs tGPR:$Rd), (ins i32imm:$label, pred:$p), + Size2Bytes, IIC_iALUi, []>; + +def tLEApcrelJT : tPseudoInst<(outs tGPR:$Rd), + (ins i32imm:$label, nohash_imm:$id, pred:$p), + Size2Bytes, IIC_iALUi, []>; //===----------------------------------------------------------------------===// // TLS Instructions diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 0924591a60c..2770d6e5a50 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -55,6 +55,7 @@ public: { "fixup_arm_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAligned}, +{ "fixup_thumb_adr_pcrel_10",0, 8, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAligned}, @@ -135,6 +136,8 @@ public: /// ADR label target. uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const; + uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const; uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const; @@ -559,6 +562,16 @@ getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, Fixups); } +/// getAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label +/// target. +uint32_t ARMMCCodeEmitter:: +getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const { + assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10, + Fixups); +} + /// getThumbAddrModeRegRegOpValue - Return encoding info for 'reg + reg' /// operand. uint32_t ARMMCCodeEmitter:: diff --git a/utils/TableGen/ARMDecoderEmitter.cpp b/utils/TableGen/ARMDecoderEmitter.cpp index 10e507f603b..0c88a316580 100644 --- a/utils/TableGen/ARMDecoderEmitter.cpp +++ b/utils/TableGen/ARMDecoderEmitter.cpp @@ -1679,12 +1679,8 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI, if (Name == "tTPsoft" || Name == "t2TPsoft") return false; - // Ignore tLEApcrel and tLEApcrelJT, prefer tADDrPCi. - if (Name == "tLEApcrel" || Name == "tLEApcrelJT") - return false; - - // Ignore t2LEApcrel, prefer the generic t2ADD* for disassembly printing. - if (Name == "t2LEApcrel") + // Ignore tADR, prefer tADDrPCi. + if (Name == "tADR") return false; // Ignore tADDrSP, tADDspr, and tPICADD, prefer the generic tADDhirr. @@ -1711,13 +1707,12 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI, // tSpill conflicts with tSTRspi // tLDRcp conflicts with tLDRspi // tRestore conflicts with tLDRspi - // t2LEApcrelJT conflicts with t2LEApcrel // t2MOVCCi16 conflicts with tMOVi16 if (Name == "tBfar" || Name == "tPOP_RET" || Name == "t2LDMIA_RET" || Name == "tMOVCCi" || Name == "tMOVCCr" || Name == "tSpill" || Name == "tLDRcp" || Name == "tRestore" || - Name == "t2LEApcrelJT" || Name == "t2MOVCCi16") + Name == "t2MOVCCi16") return false; } diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 8e37519af0e..7ee1019194a 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -584,6 +584,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("t_imm_s4"); IMM("pclabel"); IMM("adrlabel"); + IMM("t_adrlabel"); IMM("t2adrlabel"); IMM("shift_imm"); IMM("neon_vcvt_imm32");