diff options
author | Jim Grosbach <grosbach@apple.com> | 2012-01-18 21:54:16 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2012-01-18 21:54:16 +0000 |
commit | 256ba4f42a16da2b3ffc757aa7bf191890765580 (patch) | |
tree | 480705dad56b993a5f93afa9f21bdd00e854e3b4 /lib | |
parent | ec4ceb797a963b2d24b02d40fad6cc456fac3e5b (diff) |
Thumb2 relaxation for LDR(literal).
If the fixup is out of range for the Thumb1 instruction, relax it
to the Thumb2 encoding instead.
rdar://10711829
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148424 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index d24265a817..adedc208d0 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -152,7 +152,8 @@ public: static unsigned getRelaxedOpcode(unsigned Op) { switch (Op) { default: return Op; - case ARM::tBcc: return ARM::t2Bcc; + case ARM::tBcc: return ARM::t2Bcc; + case ARM::tLDRpciASM: return ARM::t2LDRpci; } } @@ -166,14 +167,24 @@ bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCInstFragment *DF, const MCAsmLayout &Layout) const { - // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the - // low bit being an implied zero. There's an implied +4 offset for the - // branch, so we adjust the other way here to determine what's - // encodable. - // - // Relax if the value is too big for a (signed) i8. - int64_t Offset = int64_t(Value) - 4; - return Offset > 254 || Offset < -256; + switch (Fixup.getKind()) { + default: assert(0 && "Unexpected fixup kind in fixupNeedsRelaxation()!"); + case ARM::fixup_arm_thumb_bcc: { + // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the + // low bit being an implied zero. There's an implied +4 offset for the + // branch, so we adjust the other way here to determine what's + // encodable. + // + // Relax if the value is too big for a (signed) i8. + int64_t Offset = int64_t(Value) - 4; + return Offset > 254 || Offset < -256; + } + case ARM::fixup_arm_thumb_cp: { + int64_t Offset = int64_t(Value) - 4; + return Offset > 4095 || Offset < 0; + } + } + llvm_unreachable("Invalid switch/cash!?"); } void ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { |