From 256ba4f42a16da2b3ffc757aa7bf191890765580 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Jan 2012 21:54:16 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 29 +++++++++++++------ test/MC/MachO/ARM/relax-thumb-ldr-literal.s | 13 +++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 test/MC/MachO/ARM/relax-thumb-ldr-literal.s diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index d24265a817c..adedc208d0e 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 00000000000..8d26f6d2e2d --- /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')