From fb20d890756b75d6ccfa7ab17f170a877d425dc6 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 9 Dec 2010 00:27:41 +0000 Subject: [PATCH] Fix Thumb2 BCC encoding and fixups. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121329 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMAsmBackend.cpp | 16 ++++++++++++++++ lib/Target/ARM/ARMFixupKinds.h | 5 ++++- lib/Target/ARM/ARMInstrThumb2.td | 17 ++++++++++------- lib/Target/ARM/ARMMCCodeEmitter.cpp | 4 ++++ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/lib/Target/ARM/ARMAsmBackend.cpp b/lib/Target/ARM/ARMAsmBackend.cpp index 1754870b95c..00cd4e79de9 100644 --- a/lib/Target/ARM/ARMAsmBackend.cpp +++ b/lib/Target/ARM/ARMAsmBackend.cpp @@ -127,6 +127,21 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { // These values don't encode the low two bits since they're always zero. // Offset by 8 just as above. return 0xffffff & ((Value - 8) >> 2); + case ARM::fixup_t2_branch: { + Value = Value - 6; + Value >>= 1; // Low bit is not encoded. + + uint64_t out = 0; + Value |= (Value & 0x80000) << 7; // S bit + Value |= (Value & 0x40000) >> 7; // J2 bit + Value |= (Value & 0x20000) >> 4; // J1 bit + Value |= (Value & 0x1F800) << 5; // imm6 field + Value |= (Value & 0x007FF); // imm11 field + + uint64_t swapped = (out & 0xFFFF0000) >> 16; + swapped |= (out & 0x0000FFFF) << 16; + return swapped; + } case ARM::fixup_arm_thumb_bl: { // The value doesn't encode the low bit (always zero) and is offset by // four. The value is encoded into disjoint bit positions in the destination @@ -273,6 +288,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) { return 3; case FK_Data_4: + case ARM::fixup_t2_branch: case ARM::fixup_t2_pcrel_10: case ARM::fixup_arm_thumb_bl: return 4; diff --git a/lib/Target/ARM/ARMFixupKinds.h b/lib/Target/ARM/ARMFixupKinds.h index 1c7435fd7d2..c18d84861e2 100644 --- a/lib/Target/ARM/ARMFixupKinds.h +++ b/lib/Target/ARM/ARMFixupKinds.h @@ -23,7 +23,7 @@ enum Fixups { // (so it's encoded as an 8-bit immediate). fixup_arm_pcrel_10, // fixup_t2_pcrel_10 - Equivalent to fixup_arm_pcrel_10, accounting for - // the byteswapped encoding of Thumb2 instructions. + // the short-swapped encoding of Thumb2 instructions. fixup_t2_pcrel_10, // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR // instruction. @@ -31,6 +31,9 @@ enum Fixups { // fixup_arm_branch - 24-bit PC relative relocation for direct branch // instructions. fixup_arm_branch, + // fixup_t2_branch - 20-bit PC relative relocation for Thumb2 direct branch + // instructions. + fixup_t2_branch, // fixup_arm_thumb_bl - Fixup for Thumb BL/BLX instructions. fixup_arm_thumb_bl, diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 2614a61f1a3..d94b5c0c0d3 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3023,13 +3023,16 @@ def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, let Inst{31-27} = 0b11110; let Inst{15-14} = 0b10; let Inst{12} = 0; - - bits<20> target; - let Inst{26} = target{19}; - let Inst{11} = target{18}; - let Inst{13} = target{17}; - let Inst{21-16} = target{16-11}; - let Inst{10-0} = target{10-0}; + + bits<4> p; + let Inst{25-22} = p; + + bits<21> target; + let Inst{26} = target{20}; + let Inst{11} = target{19}; + let Inst{13} = target{18}; + let Inst{21-16} = target{17-12}; + let Inst{10-0} = target{11-1}; } diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index ef9fac436c7..ebcab8b8d33 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -51,6 +51,7 @@ public: { "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_t2_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_arm_thumb_cp", 1, 8, MCFixupKindInfo::FKF_IsPCRel }, @@ -454,6 +455,9 @@ getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx, uint32_t ARMMCCodeEmitter:: getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const { + const ARMSubtarget &Subtarget = TM.getSubtarget(); + if (Subtarget.isThumb2()) + return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_branch, Fixups); return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_branch, Fixups); } -- 2.34.1