diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-12-01 19:47:31 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-12-01 19:47:31 +0000 |
commit | 5d14f9be7ba64162c7b996f36d419b11d8cdbe9a (patch) | |
tree | a82d935cfa230eaea3ce02a255dc58e15688d277 | |
parent | bee0c38f595f52d424161dc1db9c0bfe61421957 (diff) | |
download | external_llvm-5d14f9be7ba64162c7b996f36d419b11d8cdbe9a.zip external_llvm-5d14f9be7ba64162c7b996f36d419b11d8cdbe9a.tar.gz external_llvm-5d14f9be7ba64162c7b996f36d419b11d8cdbe9a.tar.bz2 |
Refactor LEApcrelJT as a pseudo-instructionlowered to a cannonical ADR
instruction at MC lowering. Add binary encoding information for the ADR,
including fixup data for the label operand.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120594 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 15 | ||||
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 48 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMCCodeEmitter.cpp | 23 | ||||
-rw-r--r-- | utils/TableGen/EDEmitter.cpp | 1 |
5 files changed, 73 insertions, 16 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 51d576c..de6e068 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -726,6 +726,21 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } return; } + 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::ADRadd); + TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); + TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); + // Add predicate operands. + TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + TmpInst.addOperand(MCOperand::CreateReg(0)); + OutStreamer.EmitInstruction(TmpInst); + return; + } case ARM::MOVPCRX: { MCInst TmpInst; TmpInst.setOpcode(ARM::MOVr); diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index ab554f3..797bedd 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -167,6 +167,8 @@ namespace { const { return 0; } unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val) const { return 0; } + unsigned getAdrLabelOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getCCOutOpValue(const MachineInstr &MI, unsigned Op) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 9b291df..a78cf7e 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -338,6 +338,11 @@ def pclabel : Operand<i32> { let PrintMethod = "printPCLabel"; } +// ADR instruction labels. +def adrlabel : Operand<i32> { + let EncoderMethod = "getAdrLabelOpValue"; +} + def neon_vcvt_imm32 : Operand<i32> { let EncoderMethod = "getNEONVcvtImm32OpValue"; } @@ -1178,28 +1183,39 @@ def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), // LEApcrel - Load a pc-relative address into a register without offending the // assembler. let neverHasSideEffects = 1, isReMaterializable = 1 in -// FIXME: We want one cannonical LEApcrel instruction and to express one or -// both of these as pseudo-instructions that get expanded to it. In particular, -// the cannonical "adr" pattern should take a single label operand, and the -// JT version should be a pseudo that when lowered to MC, xforms the insn -// to the canonical form referencing the correct symbol. -def LEApcrel : AXI1<0, (outs GPR:$Rd), (ins i32imm:$label, pred:$p), - MiscFrm, IIC_iALUi, - "adr${p}\t$Rd, #$label", []>; - -def LEApcrelJT : AXI1<0b0100, (outs GPR:$Rd), - (ins i32imm:$label, nohash_imm:$id, pred:$p), - MiscFrm, IIC_iALUi, - "adr${p}\t$Rd, #${label}_${id}", []> { - bits<4> p; +// The 'adr' mnemonic encodes differently if the label is before or after +// the instruction. +def ADRadd : AI1<0b0100, (outs GPR:$Rd), (ins adrlabel:$label), + MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> { bits<4> Rd; - let Inst{31-28} = p; + bits<12> label; let Inst{27-25} = 0b001; let Inst{20} = 0; let Inst{19-16} = 0b1111; let Inst{15-12} = Rd; - // FIXME: Add label encoding/fixup + let Inst{11-0} = label; } +def ADRsub : AI1<0b0010, (outs GPR:$Rd), (ins adrlabel:$label), + MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> { + bits<4> Rd; + bits<12> label; + let Inst{27-25} = 0b001; + let Inst{20} = 0; + let Inst{19-16} = 0b1111; + let Inst{15-12} = Rd; + let Inst{11-0} = label; +} + +// FIXME: This should be a pseudo lowered to one of the above at MC lowering +// time. It may be interesting determining which of the two. Perhaps a fixup +// will be needed to do so? That would be kinda fugly. +def LEApcrel : AXI1<0, (outs GPR:$Rd), (ins i32imm:$label, pred:$p), + MiscFrm, IIC_iALUi, + "adr${p}\t$Rd, #$label", []>; + +def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd), + (ins i32imm:$label, nohash_imm:$id, pred:$p), + Size4Bytes, IIC_iALUi, []>; //===----------------------------------------------------------------------===// // Control Flow Instructions. diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 207332f..d35a1c6 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -85,6 +85,11 @@ public: uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups) const; + /// getAdrLabelOpValue - Return encoding info for 12-bit immediate + /// ADR label target. + uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups) const; + /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' /// operand. uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, @@ -395,6 +400,24 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, return 0; } +/// getAdrLabelOpValue - Return encoding info for 12-bit immediate +/// ADR label target. +uint32_t ARMMCCodeEmitter:: +getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups) const { + const MCOperand &MO = MI.getOperand(OpIdx); + + // If the destination is an immediate, we have nothing to do. + if (MO.isImm()) return MO.getImm(); + assert (MO.isExpr() && "Unexpected branch target type!"); + const MCExpr *Expr = MO.getExpr(); + MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_12); + Fixups.push_back(MCFixup::Create(0, Expr, Kind)); + + // All of the information is in the fixup. + return 0; +} + /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. uint32_t ARMMCCodeEmitter:: getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 61d4ccd..f3056e0 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -582,6 +582,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("jt2block_operand"); IMM("t_imm_s4"); IMM("pclabel"); + IMM("adrlabel"); IMM("shift_imm"); IMM("neon_vcvt_imm32"); |