From: Jim Grosbach Date: Wed, 8 Dec 2010 20:32:07 +0000 (+0000) Subject: Tweak ARM fixup value adjustments for Thumb to better handle the half-word X-Git-Tag: android-x86-6.0-r1~1002^2~2418 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=0c2c217244573cdfb4be8b7fa62670412b4c1e71;p=android-x86%2Fexternal-llvm.git Tweak ARM fixup value adjustments for Thumb to better handle the half-word ordering of thumb mode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121280 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMAsmBackend.cpp b/lib/Target/ARM/ARMAsmBackend.cpp index 28d902a553c..51191c7ff16 100644 --- a/lib/Target/ARM/ARMAsmBackend.cpp +++ b/lib/Target/ARM/ARMAsmBackend.cpp @@ -134,17 +134,24 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { // xxxxxSIIIIIIIIII xxxxxIIIIIIIIIII // Note that the halfwords are stored high first, low second; so we need // to transpose the fixup value here to map properly. + // FIXME: Something isn't quite right with this. Some, but not all, BLX + // instructions are getting the encoded value off by one. uint32_t Binary = 0x3fffff & ((Value - 4) >> 1); 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. - Value = Value - 8; + // Offset by 4, and don't encode the low two bits. Two bytes of that + // '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_pcrel_10: + Value = Value - 6; // ARM fixups offset by an additional word and don't + // need to adjust for the half-word ordering. + // Fall through. + case ARM::fixup_t2_pcrel_10: { + // Offset by 4, adjusted by two due to the half-word ordering of thumb. + Value = Value - 2; bool isAdd = true; if ((int64_t)Value < 0) { Value = -Value; @@ -154,7 +161,7 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { Value >>= 2; assert ((Value < 256) && "Out of range pc-relative fixup value!"); Value |= isAdd << 23; - + // Same addressing mode as fixup_arm_pcrel_10, // but with 16-bit halfwords swapped. if (Kind == ARM::fixup_t2_pcrel_10) { @@ -162,7 +169,7 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { swapped |= (Value & 0x0000FFFF) << 16; return swapped; } - + return Value; } }