summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp21
-rw-r--r--llvm/test/MC/ARM/aligned-blx.s2
-rw-r--r--llvm/test/MC/ARM/macho-word-reloc-thumb.s29
3 files changed, 42 insertions, 10 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 5342669f3d8..a58d5b34131 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -541,7 +541,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
//
// Note that the halfwords are stored high first, low second; so we need
// to transpose the fixup value here to map properly.
- if (Ctx && Value % 4 != 0) {
+ if (Ctx && Value % 4 != 0) {
Ctx->reportError(Fixup.getLoc(), "misaligned ARM call destination");
return 0;
}
@@ -703,15 +703,16 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,
bool &IsResolved) {
const MCSymbolRefExpr *A = Target.getSymA();
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
- // Some fixups to thumb function symbols need the low bit (thumb bit)
- // twiddled.
- if ((unsigned)Fixup.getKind() != ARM::fixup_arm_ldst_pcrel_12 &&
- (unsigned)Fixup.getKind() != ARM::fixup_t2_ldst_pcrel_12 &&
- (unsigned)Fixup.getKind() != ARM::fixup_arm_adr_pcrel_12 &&
- (unsigned)Fixup.getKind() != ARM::fixup_thumb_adr_pcrel_10 &&
- (unsigned)Fixup.getKind() != ARM::fixup_t2_adr_pcrel_12 &&
- (unsigned)Fixup.getKind() != ARM::fixup_arm_thumb_cp &&
- (unsigned)Fixup.getKind() != ARM::fixup_arm_thumb_cb) {
+ // MachO (the only user of "Value") tries to make .o files that look vaguely
+ // pre-linked, so for MOVW/MOVT and .word relocations they put the Thumb bit
+ // into the addend if possible. Other relocation types don't want this bit
+ // though (branches couldn't encode it if it *was* present, and no other
+ // relocations exist) and it can interfere with checking valid expressions.
+ if ((unsigned)Fixup.getKind() == FK_Data_4 ||
+ (unsigned)Fixup.getKind() == ARM::fixup_arm_movw_lo16 ||
+ (unsigned)Fixup.getKind() == ARM::fixup_arm_movt_hi16 ||
+ (unsigned)Fixup.getKind() == ARM::fixup_t2_movw_lo16 ||
+ (unsigned)Fixup.getKind() == ARM::fixup_t2_movt_hi16) {
if (Sym) {
if (Asm.isThumbFunc(Sym))
Value |= 1;
diff --git a/llvm/test/MC/ARM/aligned-blx.s b/llvm/test/MC/ARM/aligned-blx.s
index 562eaac0467..39f335934c4 100644
--- a/llvm/test/MC/ARM/aligned-blx.s
+++ b/llvm/test/MC/ARM/aligned-blx.s
@@ -27,8 +27,10 @@ _test:
blx _aligned @ PC=0 (mod 4)
movs r0, r0
blx _aligned @ PC=2 (mod 4)
+ blx _f1
@ CHECK: blx _elsewhere
@ CHECK: ff f7 fa ef blx _aligned
@ CHECK: ff f7 f8 ef blx _aligned
@ CHECK: ff f7 f6 ef blx _aligned
+@ CHECK: ff f7 f2 ef blx _f1
diff --git a/llvm/test/MC/ARM/macho-word-reloc-thumb.s b/llvm/test/MC/ARM/macho-word-reloc-thumb.s
new file mode 100644
index 00000000000..1ccc45b7457
--- /dev/null
+++ b/llvm/test/MC/ARM/macho-word-reloc-thumb.s
@@ -0,0 +1,29 @@
+@ RUN: llvm-mc -triple thumbv7-apple-ios %s -filetype=obj -o %t
+@ RUN: llvm-objdump -macho -d %t -triple thumbv7-apple-ios | FileCheck %s
+
+@ ARM relocatable object files try to look like they're pre-linked, so the
+@ offsets in the instructions are a best-guess. I suspect the "-3" should b
+
+@ CHECK: movw r1, :lower16:((_bar-8)-3)
+@ [...]
+@ CHECK: .long {{[0-9]*[13579]}}
+
+ .thumb
+ .thumb_func _foo
+_foo:
+ movw r1, :lower16:(_bar-(LPC2_0+4))
+ movt r1, :upper16:(_bar-(LPC2_0+4))
+LPC2_0:
+ add r1, pc
+ ldr r0, Lconstpool
+ bx lr
+Lconstpool:
+ .data_region
+ .word _bar
+ .end_data_region
+
+ .thumb_func _bar
+_bar:
+ bx lr
+
+ .subsections_via_symbols
OpenPOWER on IntegriCloud