diff options
author | Bill Wendling <isanbard@gmail.com> | 2010-12-08 01:57:09 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2010-12-08 01:57:09 +0000 |
commit | b8958b031ec5163261f490f131780c5dc3d823d6 (patch) | |
tree | 0ba2c5f719017b8d47891046bc3e111bef276b60 | |
parent | 43c249cf1e417083ec8cbdfb4866a42861a7f638 (diff) | |
download | external_llvm-b8958b031ec5163261f490f131780c5dc3d823d6.zip external_llvm-b8958b031ec5163261f490f131780c5dc3d823d6.tar.gz external_llvm-b8958b031ec5163261f490f131780c5dc3d823d6.tar.bz2 |
Add support for loading from a constant pool.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121226 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/MC/ELFObjectWriter.cpp | 1 | ||||
-rw-r--r-- | lib/Target/ARM/ARMAsmBackend.cpp | 11 | ||||
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMFixupKinds.h | 3 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 24 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMCCodeEmitter.cpp | 30 | ||||
-rw-r--r-- | utils/TableGen/EDEmitter.cpp | 2 |
7 files changed, 63 insertions, 10 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index b51e508..c9e8074 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -1549,6 +1549,7 @@ unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target, case ARM::fixup_arm_pcrel_10: case ARM::fixup_arm_adr_pcrel_12: case ARM::fixup_arm_thumb_bl: + case ARM::fixup_arm_thumb_cp: assert(0 && "Unimplemented"); break; case ARM::fixup_arm_branch: return ELF::R_ARM_CALL; break; diff --git a/lib/Target/ARM/ARMAsmBackend.cpp b/lib/Target/ARM/ARMAsmBackend.cpp index 90b181e..f5ac33a 100644 --- a/lib/Target/ARM/ARMAsmBackend.cpp +++ b/lib/Target/ARM/ARMAsmBackend.cpp @@ -138,6 +138,9 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { Binary = ((Binary & 0x7ff) << 16) | (Binary >> 11); return Binary; } + case ARM::fixup_arm_thumb_cp: + // Offset by 4, and don't encode the low two bits. + return ((Value - 4) >> 2) & 0xff; case ARM::fixup_t2_pcrel_10: case ARM::fixup_arm_pcrel_10: { // Offset by 8 just as above. @@ -243,13 +246,17 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { switch (Kind) { default: llvm_unreachable("Unknown fixup kind!"); - case FK_Data_4: - return 4; + + case ARM::fixup_arm_thumb_cp: + return 1; + case ARM::fixup_arm_ldst_pcrel_12: case ARM::fixup_arm_pcrel_10: case ARM::fixup_arm_adr_pcrel_12: case ARM::fixup_arm_branch: return 3; + + case FK_Data_4: case ARM::fixup_t2_pcrel_10: case ARM::fixup_arm_thumb_bl: return 4; diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 2e2570c..4dd1524 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -255,6 +255,8 @@ namespace { const { return 0; } uint32_t getAddrModeS1OpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + uint32_t getAddrModePCOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const { // {17-13} = reg // {12} = (U)nsigned (add == '1', sub == '0') diff --git a/lib/Target/ARM/ARMFixupKinds.h b/lib/Target/ARM/ARMFixupKinds.h index 0136e0c..b05e116 100644 --- a/lib/Target/ARM/ARMFixupKinds.h +++ b/lib/Target/ARM/ARMFixupKinds.h @@ -34,6 +34,9 @@ enum Fixups { // fixup_arm_thumb_bl - Fixup for Thumb BL/BLX instructions. fixup_arm_thumb_bl, + // fixup_arm_thumb_cp - Fixup for Thumb load/store from constant pool instrs. + fixup_arm_thumb_cp, + // The next two are for the movt/movw pair // the 16bit imm field are split into imm{15-12} and imm{11-0} // Fixme: We need new ones for Thumb. diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index c17e042..cfe4e39 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -134,6 +134,13 @@ def t_addrmode_sp : Operand<i32>, let ParserMatchClass = MemModeThumbAsmOperand; } +// t_addrmode_pc := <label> => pc + imm8 * 4 +// +def t_addrmode_pc : Operand<i32> { + let EncoderMethod = "getAddrModePCOpValue"; + let ParserMatchClass = MemModeThumbAsmOperand; +} + //===----------------------------------------------------------------------===// // Miscellaneous Instructions. // @@ -622,22 +629,29 @@ def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad_i, // Load tconstpool // FIXME: Use ldr.n to work around a Darwin assembler bug. let canFoldAsLoad = 1, isReMaterializable = 1 in -def tLDRpci : T1pIs<(outs tGPR:$Rt), (ins i32imm:$addr), IIC_iLoad_i, +def tLDRpci : T1pIs<(outs tGPR:$Rt), (ins t_addrmode_pc:$addr), IIC_iLoad_i, "ldr", ".n\t$Rt, $addr", [(set tGPR:$Rt, (load (ARMWrapper tconstpool:$addr)))]>, T1Encoding<{0,1,0,0,1,?}> { // A6.2 & A8.6.59 bits<3> Rt; + bits<8> addr; let Inst{10-8} = Rt; - // FIXME: Finish for the addr. + let Inst{7-0} = addr; } // Special LDR for loads from non-pc-relative constpools. let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1, isReMaterializable = 1 in -def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad_i, - "ldr", "\t$dst, $addr", []>, - T1LdStSP<{1,?,?}>; +def tLDRcp : T1pIs<(outs tGPR:$Rt), (ins i32imm:$addr), IIC_iLoad_i, + "ldr", "\t$Rt, $addr", []>, + T1LdStSP<{1,?,?}> { + // A6.2 & A8.6.57 T2 + bits<3> Rt; + bits<8> addr; + let Inst{10-8} = Rt; + let Inst{7-0} = addr; +} def tSTR : // A8.6.194 T1pILdStEncode<0b000, (outs), (ins tGPR:$src, t_addrmode_s4:$addr), diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index ba1f6d3..d6c3b50 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -52,6 +52,7 @@ public: { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_arm_thumb_cp", 1, 8, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_movt_hi16", 0, 16, 0 }, { "fixup_arm_movw_lo16", 0, 16, 0 }, }; @@ -174,6 +175,10 @@ public: uint32_t getAddrModeS1OpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups) const; + /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. + uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups) const; + /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand. uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups) const; @@ -662,15 +667,17 @@ getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx, return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13); } -/// getAddrModeThumbSPOpValue- Encode the t_addrmode_sp operands. +/// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands. uint32_t ARMMCCodeEmitter:: getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups) const { // [SP, #imm] // {7-0} = imm8 const MCOperand &MO1 = MI.getOperand(OpIdx + 1); - assert (MI.getOperand(OpIdx).getReg() == ARM::SP && - "Unexpected base register!"); +#if 0 // FIXME: This crashes2003-05-14-initialize-string.c + assert(MI.getOperand(OpIdx).getReg() == ARM::SP && + "Unexpected base register!"); +#endif // The immediate is already shifted for the implicit zeroes, so no change // here. return MO1.getImm() & 0xff; @@ -720,6 +727,23 @@ getAddrModeS1OpValue(const MCInst &MI, unsigned OpIdx, return getAddrModeSOpValue(MI, OpIdx, 1); } +/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. +uint32_t ARMMCCodeEmitter:: +getAddrModePCOpValue(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_thumb_cp); + Fixups.push_back(MCFixup::Create(0, Expr, Kind)); + + // All of the information is in the fixup. + return 0; +} + /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand. uint32_t ARMMCCodeEmitter:: getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx, diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 68568c8..9cf5be6 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -627,6 +627,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("t_addrmode_s4", "kOperandTypeThumbAddrModeS4"); // R, I, R MISC("t_addrmode_rr", "kOperandTypeThumbAddrModeRR"); // R, R MISC("t_addrmode_sp", "kOperandTypeThumbAddrModeSP"); // R, I + MISC("t_addrmode_pc", "kOperandTypeThumbAddrModePC"); // R, I return 1; } @@ -838,6 +839,7 @@ static void emitCommonEnums(raw_ostream &o, unsigned int &i) { operandTypes.addEntry("kOperandTypeThumbAddrModeS4"); operandTypes.addEntry("kOperandTypeThumbAddrModeRR"); operandTypes.addEntry("kOperandTypeThumbAddrModeSP"); + operandTypes.addEntry("kOperandTypeThumbAddrModePC"); operandTypes.addEntry("kOperandTypeThumb2SoReg"); operandTypes.addEntry("kOperandTypeThumb2SoImm"); operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8"); |