diff options
author | Owen Anderson <resistor@mac.com> | 2010-12-14 00:36:49 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2010-12-14 00:36:49 +0000 |
commit | a838a25d59838adfa91463f6a918ae3adeb352c1 (patch) | |
tree | 2993f422e346bd2efa6a917c95c6a2b55bfcaccf | |
parent | 2d9220e8f5b45390d64e943fa4eef1562b87f04b (diff) | |
download | external_llvm-a838a25d59838adfa91463f6a918ae3adeb352c1.zip external_llvm-a838a25d59838adfa91463f6a918ae3adeb352c1.tar.gz external_llvm-a838a25d59838adfa91463f6a918ae3adeb352c1.tar.bz2 |
Second attempt at make Thumb2 LEAs pseudos. This time, perform the lowering much later, which makes the entire
process cleaner.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121735 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMAsmBackend.cpp | 20 | ||||
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 12 | ||||
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMFixupKinds.h | 3 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 41 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMCCodeEmitter.cpp | 15 | ||||
-rw-r--r-- | utils/TableGen/EDEmitter.cpp | 1 |
7 files changed, 75 insertions, 19 deletions
diff --git a/lib/Target/ARM/ARMAsmBackend.cpp b/lib/Target/ARM/ARMAsmBackend.cpp index cb0c543..789bae0 100644 --- a/lib/Target/ARM/ARMAsmBackend.cpp +++ b/lib/Target/ARM/ARMAsmBackend.cpp @@ -136,6 +136,25 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { // Encode the immediate and shift the opcode into place. return ARM_AM::getSOImmVal(Value) | (opc << 21); } + + case ARM::fixup_t2_adr_pcrel_12: { + Value -= 4; + unsigned opc = 0; + if ((int64_t)Value < 0) { + Value = -Value; + opc = 5; + } + + uint32_t out = (opc << 21); + out |= (Value & 0x800) << 14; + out |= (Value & 0x700) << 4; + out |= (Value & 0x0FF); + + uint64_t swapped = (out & 0xFFFF0000) >> 16; + swapped |= (out & 0x0000FFFF) << 16; + return swapped; + } + case ARM::fixup_arm_branch: // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. @@ -356,6 +375,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { case ARM::fixup_t2_condbranch: case ARM::fixup_t2_uncondbranch: case ARM::fixup_t2_pcrel_10: + case ARM::fixup_t2_adr_pcrel_12: case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: return 4; diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 09124e4..b211167 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -734,6 +734,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } return; } + case ARM::t2LEApcrel: case ARM::LEApcrel: { // FIXME: Need to also handle globals and externals assert (MI->getOperand(1).isCPI()); @@ -741,7 +742,10 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCSymbol *Sym = GetCPISymbol(LabelId); const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Sym, OutContext); MCInst TmpInst; - TmpInst.setOpcode(ARM::ADR); + if (MI->getOpcode() == ARM::LEApcrel) + TmpInst.setOpcode(ARM::ADR); + else + TmpInst.setOpcode(ARM::t2ADR); TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); // Add predicate operands. @@ -750,13 +754,17 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { OutStreamer.EmitInstruction(TmpInst); return; } + case ARM::t2LEApcrelJT: case ARM::LEApcrelJT: { unsigned JTI = MI->getOperand(1).getIndex(); unsigned Id = MI->getOperand(2).getImm(); MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, Id); const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(JTISymbol, OutContext); MCInst TmpInst; - TmpInst.setOpcode(ARM::ADR); + if (MI->getOpcode() == ARM::LEApcrelJT) + TmpInst.setOpcode(ARM::ADR); + else + TmpInst.setOpcode(ARM::t2ADR); TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); // Add predicate operands. diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 101c07b..5e302ae 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -213,6 +213,8 @@ namespace { const { return 0; } unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op) diff --git a/lib/Target/ARM/ARMFixupKinds.h b/lib/Target/ARM/ARMFixupKinds.h index 48d4953..f535608 100644 --- a/lib/Target/ARM/ARMFixupKinds.h +++ b/lib/Target/ARM/ARMFixupKinds.h @@ -33,6 +33,9 @@ enum Fixups { // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR // instruction. fixup_arm_adr_pcrel_12, + // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR + // instruction. + fixup_t2_adr_pcrel_12, // fixup_arm_branch - 24-bit PC relative relocation for direct branch // instructions. fixup_arm_branch, diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 2fedb53..faa143d 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -131,6 +131,12 @@ def t2addrmode_imm12 : Operand<i32>, let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } +// ADR instruction labels. +def t2adrlabel : Operand<i32> { + let EncoderMethod = "getT2AdrLabelOpValue"; +} + + // t2addrmode_imm8 := reg +/- imm8 def t2addrmode_imm8 : Operand<i32>, ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { @@ -1128,10 +1134,9 @@ class T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin, // LEApcrel - Load a pc-relative address into a register without offending the // assembler. -let neverHasSideEffects = 1 in { -let isReMaterializable = 1 in -def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi, - "adr${p}.w\t$Rd, #$label", []> { +def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd), + (ins t2adrlabel:$addr, pred:$p), + IIC_iALUi, "adr{$p}.w\t$Rd, #$addr", []> { let Inst{31-27} = 0b11110; let Inst{25-24} = 0b10; // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) @@ -1139,21 +1144,23 @@ def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), II let Inst{20} = 0; let Inst{19-16} = 0b1111; // Rn let Inst{15} = 0; - - + + bits<4> Rd; + bits<13> addr; + let Inst{11-8} = Rd; + let Inst{23} = addr{12}; + let Inst{21} = addr{12}; + let Inst{26} = addr{11}; + let Inst{14-12} = addr{10-8}; + let Inst{7-0} = addr{7-0}; } -} // neverHasSideEffects -def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd), + +let neverHasSideEffects = 1, isReMaterializable = 1 in +def t2LEApcrel : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), + IIC_iALUi, []>; +def t2LEApcrelJT : PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi, - "adr${p}.w\t$Rd, #${label}_${id}", []> { - let Inst{31-27} = 0b11110; - let Inst{25-24} = 0b10; - // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) - let Inst{22} = 0; - let Inst{20} = 0; - let Inst{19-16} = 0b1111; // Rn - let Inst{15} = 0; -} + []>; // FIXME: None of these add/sub SP special instructions should be necessary diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 7f34ee9..8dca2c3 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -56,6 +56,8 @@ public: { "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAligned}, { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | + MCFixupKindInfo::FKF_IsAligned}, { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, @@ -133,6 +135,9 @@ public: /// ADR label target. uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups) const; + uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups) const; + /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' /// operand. @@ -544,6 +549,16 @@ getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, Fixups); } +/// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label +/// target. +uint32_t ARMMCCodeEmitter:: +getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups) const { + assert(MI.getOperand(OpIdx).isExpr() && "Unexpected adr target type!"); + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12, + Fixups); +} + /// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand. uint32_t ARMMCCodeEmitter:: getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index dede4b0..9c27515 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("t2adrlabel"); IMM("shift_imm"); IMM("neon_vcvt_imm32"); |