Skip to content

Commit

Permalink
[MC][ARM] Correct Thumb BL instruction range
Browse files Browse the repository at this point in the history
The Thumb BL range is + or - either 16 Megabytes or 4 Megabytes depending
on whether the CPU supports Thumb2 or the v8-m baseline ops. The existing
check for BL range is incorrectly set at +- 32 Megabytes. This change
corrects the higher range and uses the lower range if the featurebits
don't have the necessary support for it.

Differential Revision: https://reviews.llvm.org/D46305

llvm-svn: 333991
  • Loading branch information
smithp35 committed Jun 5, 2018
1 parent 964b27f commit 0aafe0c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 15 deletions.
8 changes: 5 additions & 3 deletions llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,9 +518,11 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
return swapHalfWords(out, Endian == support::little);
}
case ARM::fixup_arm_thumb_bl: {
// FIXME: We get both thumb1 and thumb2 in here, so we can only check for
// the less strict thumb2 value.
if (!isInt<26>(Value - 4)) {
if (!isInt<25>(Value - 4) ||
(!STI.getFeatureBits()[ARM::FeatureThumb2] &&
!STI.getFeatureBits()[ARM::HasV8MBaselineOps] &&
!STI.getFeatureBits()[ARM::HasV6MOps] &&
!isInt<23>(Value - 4))) {
Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
return 0;
}
Expand Down
52 changes: 40 additions & 12 deletions llvm/test/MC/ARM/thumb-branches.s
Original file line number Diff line number Diff line change
@@ -1,43 +1,71 @@
@ RUN: not llvm-mc %s -triple thumbv5-linux-gnueabi -filetype=obj -o /dev/null 2>&1 | FileCheck %s
@ RUN: not llvm-mc %s -triple thumbv7-linux-gnueabi -filetype=obj -o /dev/null 2>&1 | FileCheck %s
@ RUN: not llvm-mc %s -triple thumbv8-m.baseline-none-eabi -filetype=obj -o /dev/null 2>&1 | FileCheck %s
@ RUN: not llvm-mc %s -triple thumbv8-m.mainline-none-eabi -filetype=obj -o /dev/null 2>&1 | FileCheck %s
@ RUN: not llvm-mc %s -triple thumbv6m-none-eabi -filetype=obj -o /dev/null 2>&1 | FileCheck %s
@ RUN: not llvm-mc %s -triple thumbv5-linux-gnueabi -filetype=obj -o /dev/null 2>&1 | FileCheck -check-prefix=CHECKSHORT %s

// Thumb BL has range +- 4 Megabytes if CPU does not support Thumb2 or does not
// have v8-M baseline ops, it is +- 16 Megabytes otherwise.

.code 16
bl shortend
.space 0x3fffff
shortend:
// CHECKSHORT-NOT: error
// CHECKSHORT: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range
bl shortend2
.space 0x400000
shortend2:

// CHECKSHORT: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range
bl end
.space 0x1ffffff
.space 0xffffff
end:

bl end2
.space 0x1ffffff
.space 0xffffff
.global end2
end2:

bl end3
.space 0x2000000
.space 0x1000000
.global end3
end3:

// CHECK-NOT: error
// CHECKSHORT-NOT: error
// CHECKSHORT: [[@LINE+2]]:{{[0-9]}}: error: Relocation out of range
// CHECK: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range
bl end4
// CHECK-NOT: error
.space 0x2000000
.space 0x1000000
end4:

shortstart1:
.space 0x3ffffc
bl shortstart1

shortstart2:
.space 0x400000
// CHECKSHORT: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range
bl shortstart2

start1:
.space 0x1fffffc
.space 0xfffffc
// CHECKSHORT: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range
bl start1

.global start2
start2:
.space 0x1fffffc
.space 0xfffffc
bl start2

.global start3
start3:
.space 0x1fffffd
.space 0xfffffd
bl start3

// CHECK-NOT: error
start4:
.space 0x1fffffd
// CHECK: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range
.space 0xfffffd
// CHECK: [[@LINE+2]]:{{[0-9]}}: error: Relocation out of range
// CHECKSHORT: [[@LINE+1]]:{{[0-9]}}: error: Relocation out of range
bl start4

0 comments on commit 0aafe0c

Please sign in to comment.