[llvm] r252090 - Slightly saner handling of thumb branches.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 4 15:00:39 PST 2015
Author: rafael
Date: Wed Nov 4 17:00:39 2015
New Revision: 252090
URL: http://llvm.org/viewvc/llvm-project?rev=252090&view=rev
Log:
Slightly saner handling of thumb branches.
The generic infrastructure already did a lot of work to decide if the
fixup value is know or not. It doesn't make sense to reimplement a very
basic case: same fragment.
Added:
llvm/trunk/test/MC/ARM/thumb-branches-err.s
llvm/trunk/test/MC/ARM/thumb-branches.s
Modified:
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp?rev=252090&r1=252089&r2=252090&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp Wed Nov 4 17:00:39 2015
@@ -620,6 +620,7 @@ void ARMAsmBackend::processFixupValue(co
const MCValue &Target, uint64_t &Value,
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 &&
@@ -628,18 +629,23 @@ void ARMAsmBackend::processFixupValue(co
(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) {
- if (A) {
- const MCSymbol &Sym = A->getSymbol();
- if (Asm.isThumbFunc(&Sym))
+ if (Sym) {
+ if (Asm.isThumbFunc(Sym))
Value |= 1;
}
}
- // For Thumb1 BL instruction, it is possible to be a long jump between
- // the basic blocks of the same function. Thus, we would like to resolve
- // the offset when the destination has the same MCFragment.
- if (A && (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) {
- const MCSymbol &Sym = A->getSymbol();
- IsResolved = (Sym.getFragment() == DF);
+ if (IsResolved && (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) {
+ assert(Sym && "How did we resolve this?");
+
+ // If the symbol is external the linker will handle it.
+ // FIXME: Should we handle it as an optimization?
+ if (Sym->isExternal()) {
+ IsResolved = false;
+ } else {
+ if (Value >= 0x400004)
+ Asm.getContext().reportFatalError(Fixup.getLoc(),
+ "out of range for branch");
+ }
}
// We must always generate a relocation for BL/BLX instructions if we have
// a symbol to reference, as the linker relies on knowing the destination
Added: llvm/trunk/test/MC/ARM/thumb-branches-err.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb-branches-err.s?rev=252090&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb-branches-err.s (added)
+++ llvm/trunk/test/MC/ARM/thumb-branches-err.s Wed Nov 4 17:00:39 2015
@@ -0,0 +1,7 @@
+@ RUN: not llvm-mc < %s -triple thumbv5-linux-gnueabi -filetype=obj -o %t 2>&1 | FileCheck %s
+
+ bl end
+ .space 0x400000
+end:
+
+@ CHECK: out of range for branch
Added: llvm/trunk/test/MC/ARM/thumb-branches.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb-branches.s?rev=252090&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb-branches.s (added)
+++ llvm/trunk/test/MC/ARM/thumb-branches.s Wed Nov 4 17:00:39 2015
@@ -0,0 +1,20 @@
+@ RUN: llvm-mc < %s -triple thumbv5-linux-gnueabi -filetype=obj -o - \
+@ RUN: | llvm-readobj -r | FileCheck %s
+
+
+ bl end
+ .space 0x3fffff
+end:
+
+ bl end2
+ .space 0x3fffff
+ .global end2
+end2:
+
+ bl end3
+ .space 0x400000
+ .global end3
+end3:
+
+@ CHECK: 0x400003 R_ARM_THM_CALL end2 0x0
+@ CHECK: 0x800006 R_ARM_THM_CALL end3 0x0
More information about the llvm-commits
mailing list