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 | |
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
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 29 | ||||
-rw-r--r-- | test/MC/MachO/ARM/relax-thumb-ldr-literal.s | 13 |
2 files changed, 33 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 { diff --git a/test/MC/MachO/ARM/relax-thumb-ldr-literal.s b/test/MC/MachO/ARM/relax-thumb-ldr-literal.s new file mode 100644 index 0000000000..8d26f6d2e2 --- /dev/null +++ b/test/MC/MachO/ARM/relax-thumb-ldr-literal.s @@ -0,0 +1,13 @@ +@ RUN: llvm-mc -n -triple thumbv7-apple-darwin10 %s -filetype=obj -o %t.obj +@ RUN: macho-dump --dump-section-data < %t.obj > %t.dump +@ RUN: FileCheck < %t.dump %s + + .syntax unified + .text + .thumb + .thumb_func _foo +_foo: + ldr r2, (_foo - 4) + +@ CHECK: ('num_reloc', 0) +@ CHECK: ('_section_data', '5ff80820') |