From 22447ae54bcb8ca94ed994cad103074a24e66781 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 15 Dec 2010 08:51:02 +0000 Subject: [PATCH] Add fixups for Thumb LDR/STR instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121858 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMAsmBackend.cpp | 4 ++++ lib/Target/ARM/ARMFixupKinds.h | 3 +++ lib/Target/ARM/ARMMCCodeEmitter.cpp | 16 +++++++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/Target/ARM/ARMAsmBackend.cpp b/lib/Target/ARM/ARMAsmBackend.cpp index e4acd667307..67f2c710571 100644 --- a/lib/Target/ARM/ARMAsmBackend.cpp +++ b/lib/Target/ARM/ARMAsmBackend.cpp @@ -237,6 +237,9 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { // 'off by 4' is implicitly handled by the half-word ordering of the // Thumb encoding, so we only need to adjust by 2 here. return ((Value - 2) >> 2) & 0xff; + case ARM::fixup_arm_thumb_ldst: + // Offset by 4. + return ((Value - 4) & 0x1f) << 6; case ARM::fixup_arm_thumb_cb: { // Offset by 4 and don't encode the lower bit, which is always 0. uint32_t Binary = (Value - 4) >> 1; @@ -365,6 +368,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { case ARM::fixup_arm_thumb_br: case ARM::fixup_arm_thumb_cb: + case ARM::fixup_arm_thumb_ldst: return 2; case ARM::fixup_arm_ldst_pcrel_12: diff --git a/lib/Target/ARM/ARMFixupKinds.h b/lib/Target/ARM/ARMFixupKinds.h index 3e0bd0e7b7a..f1683732b28 100644 --- a/lib/Target/ARM/ARMFixupKinds.h +++ b/lib/Target/ARM/ARMFixupKinds.h @@ -65,6 +65,9 @@ enum Fixups { // fixup_arm_thumb_cp - Fixup for Thumb load/store from constant pool instrs. fixup_arm_thumb_cp, + // fixup_arm_thumb_ldst - Fixup for Thumb load/store instrs. + fixup_arm_thumb_ldst, + // fixup_arm_thumb_bcc - Fixup for Thumb conditional branching instructions. fixup_arm_thumb_bcc, diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index c633825adfe..db68f359a2c 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -68,6 +68,7 @@ public: { "fixup_arm_thumb_blx", 7, 21, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_cp", 1, 8, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_thumb_ldst", 1, 8, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_bcc", 1, 8, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_movt_hi16", 0, 16, 0 }, { "fixup_arm_movw_lo16", 0, 16, 0 }, @@ -213,7 +214,7 @@ public: /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl &) const; + SmallVectorImpl &Fixups) const; /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands. uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx, @@ -817,14 +818,23 @@ getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx, /// getAddrModeISOpValue - Encode the t_addrmode_is# operands. uint32_t ARMMCCodeEmitter:: getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl &) const { + SmallVectorImpl &Fixups) const { // [Rn, #imm] // {7-3} = imm5 // {2-0} = Rn const MCOperand &MO = MI.getOperand(OpIdx); const MCOperand &MO1 = MI.getOperand(OpIdx + 1); unsigned Rn = getARMRegisterNumbering(MO.getReg()); - unsigned Imm5 = MO1.getImm(); + unsigned Imm5 = 0; + + if (MO1.isExpr()) { + const MCExpr *Expr = MO.getExpr(); + MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_thumb_ldst); + Fixups.push_back(MCFixup::Create(0, Expr, Kind)); + } else { + Imm5 = MO1.getImm(); + } + return ((Imm5 & 0x1f) << 3) | Rn; }