Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 1a47d66

Browse files
committed
Change the ARM assembler to require a :lower16: or :upper16 on non-constant
expressions for mov instructions instead of silently truncating by default. For the ARM assembler, we want to avoid misleadingly allowing something like "mov r0, <symbol>" especially when we turn it into a movw and the expression <symbol> does not have a :lower16: or :upper16" as part of the expression. We don't want the behavior of silently truncating, which can be unexpected and lead to bugs that are difficult to find since this is an easy mistake to make. This does change the previous behavior of llvm but actually matches an older gnu assembler that would not allow this but print less useful errors of like “invalid constant (0x927c0) after fixup” and “unsupported relocation on symbol foo”. The error for llvm is "immediate expression for mov requires :lower16: or :upper16" with correct location information on the operand as shown in the added test cases. rdar://12342160 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206669 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent ad326ae commit 1a47d66

File tree

6 files changed

+55
-12
lines changed

6 files changed

+55
-12
lines changed

lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5863,6 +5863,30 @@ validateInstruction(MCInst &Inst,
58635863
return Error(Operands[Op]->getStartLoc(), "branch target out of range");
58645864
break;
58655865
}
5866+
case ARM::MOVi16:
5867+
case ARM::t2MOVi16:
5868+
case ARM::t2MOVTi16:
5869+
{
5870+
// We want to avoid misleadingly allowing something like "mov r0, <symbol>"
5871+
// especially when we turn it into a movw and the expression <symbol> does
5872+
// not have a :lower16: or :upper16 as part of the expression. We don't
5873+
// want the behavior of silently truncating, which can be unexpected and
5874+
// lead to bugs that are difficult to find since this is an easy mistake
5875+
// to make.
5876+
int i = (Operands[3]->isImm()) ? 3 : 4;
5877+
ARMOperand *Op = static_cast<ARMOperand*>(Operands[i]);
5878+
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
5879+
if (CE) break;
5880+
const MCExpr *E = dyn_cast<MCExpr>(Op->getImm());
5881+
if (!E) break;
5882+
const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(E);
5883+
if (!ARM16Expr || (ARM16Expr->getKind() != ARMMCExpr::VK_ARM_HI16 &&
5884+
ARM16Expr->getKind() != ARMMCExpr::VK_ARM_LO16)) {
5885+
return Error(Op->getStartLoc(),
5886+
"immediate expression for mov requires :lower16: or :upper16");
5887+
break;
5888+
}
5889+
}
58665890
}
58675891

58685892
return false;

lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,12 +1040,12 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
10401040
return 0;
10411041
}
10421042
// If the expression doesn't have :upper16: or :lower16: on it,
1043-
// it's just a plain immediate expression, and those evaluate to
1043+
// it's just a plain immediate expression, previously those evaluated to
10441044
// the lower 16 bits of the expression regardless of whether
1045-
// we have a movt or a movw.
1046-
Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movw_lo16
1047-
: ARM::fixup_arm_movw_lo16);
1048-
Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc()));
1045+
// we have a movt or a movw, but that led to misleadingly results.
1046+
// This is now disallowed in the the AsmParser in validateInstruction()
1047+
// so this should never happen.
1048+
assert(0 && "expression without :upper16: or :lower16:");
10491049
return 0;
10501050
}
10511051

test/MC/ARM/arm_fixups.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
@ CHECK-BE: movt r9, :upper16:_foo @ encoding: [0xe3,0b0100AAAA,0x90'A',A]
2727
@ CHECK-BE: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movt_hi16
2828

29-
mov r2, fred
29+
mov r2, :lower16:fred
3030

31-
@ CHECK: movw r2, fred @ encoding: [A,0x20'A',0b0000AAAA,0xe3]
31+
@ CHECK: movw r2, :lower16:fred @ encoding: [A,0x20'A',0b0000AAAA,0xe3]
3232
@ CHECK: @ fixup A - offset: 0, value: fred, kind: fixup_arm_movw_lo16
33-
@ CHECK-BE: movw r2, fred @ encoding: [0xe3,0b0000AAAA,0x20'A',A]
33+
@ CHECK-BE: movw r2, :lower16:fred @ encoding: [0xe3,0b0000AAAA,0x20'A',A]
3434
@ CHECK-BE: @ fixup A - offset: 0, value: fred, kind: fixup_arm_movw_lo16

test/MC/ARM/complex-operands.s

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,20 @@ return:
2121
.global arm_function
2222
.type arm_function,%function
2323
arm_function:
24-
mov r0, #(.L_table_end - .L_table_begin) >> 2
24+
mov r0, #:lower16:((.L_table_end - .L_table_begin) >> 2)
2525
blx return
2626

2727
@ CHECK-LABEL: arm_function
28-
@ CHECK: movw r0, #(.L_table_end-.L_table_begin)>>2
28+
@ CHECK: movw r0, :lower16:((.L_table_end-.L_table_begin)>>2)
2929
@ CHECK: blx return
3030

3131
.global thumb_function
3232
.type thumb_function,%function
3333
thumb_function:
34-
mov r0, #(.L_table_end - .L_table_begin) >> 2
34+
mov r0, #:lower16:((.L_table_end - .L_table_begin) >> 2)
3535
blx return
3636

3737
@ CHECK-LABEL: thumb_function
38-
@ CHECK: movw r0, #(.L_table_end-.L_table_begin)>>2
38+
@ CHECK: movw r0, :lower16:((.L_table_end-.L_table_begin)>>2)
3939
@ CHECK: blx return
4040

test/MC/ARM/diagnostics.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,3 +465,11 @@
465465
ldm sp!, {r0}^
466466
@ CHECK-ERRORS: error: system STM cannot have writeback register
467467
@ CHECK-ERRORS: error: writeback register only allowed on system LDM if PC in register-list
468+
469+
foo2:
470+
mov r0, foo2
471+
movw r0, foo2
472+
@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
473+
@ CHECK-ERRORS: ^
474+
@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
475+
@ CHECK-ERRORS: ^

test/MC/ARM/thumb2-diagnostics.s

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,14 @@
7070
@ CHECK-ERRORS: error: branch target out of range
7171
@ CHECK-ERRORS: error: branch target out of range
7272
@ CHECK-ERRORS: error: branch target out of range
73+
74+
foo2:
75+
mov r0, foo2
76+
movw r0, foo2
77+
movt r0, foo2
78+
@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
79+
@ CHECK-ERRORS: ^
80+
@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
81+
@ CHECK-ERRORS: ^
82+
@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
83+
@ CHECK-ERRORS: ^

0 commit comments

Comments
 (0)