summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2014-04-18 23:06:39 +0000
committerKevin Enderby <enderby@apple.com>2014-04-18 23:06:39 +0000
commit1a47d664964d238323c0cad6f9c29b06d1274b12 (patch)
tree3e418204275220729a2a9ee4f8628d05044ebd57
parentad326ae3f6ac0be8b95fd41288b0e0d68b775774 (diff)
downloadllvm-1a47d664964d238323c0cad6f9c29b06d1274b12.tar.gz
llvm-1a47d664964d238323c0cad6f9c29b06d1274b12.tar.bz2
llvm-1a47d664964d238323c0cad6f9c29b06d1274b12.tar.xz
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
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp24
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp10
-rw-r--r--test/MC/ARM/arm_fixups.s6
-rw-r--r--test/MC/ARM/complex-operands.s8
-rw-r--r--test/MC/ARM/diagnostics.s8
-rw-r--r--test/MC/ARM/thumb2-diagnostics.s11
6 files changed, 55 insertions, 12 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index a22d03e20b..0e5fd1f6e0 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -5863,6 +5863,30 @@ validateInstruction(MCInst &Inst,
return Error(Operands[Op]->getStartLoc(), "branch target out of range");
break;
}
+ case ARM::MOVi16:
+ case ARM::t2MOVi16:
+ case ARM::t2MOVTi16:
+ {
+ // 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.
+ int i = (Operands[3]->isImm()) ? 3 : 4;
+ ARMOperand *Op = static_cast<ARMOperand*>(Operands[i]);
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
+ if (CE) break;
+ const MCExpr *E = dyn_cast<MCExpr>(Op->getImm());
+ if (!E) break;
+ const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(E);
+ if (!ARM16Expr || (ARM16Expr->getKind() != ARMMCExpr::VK_ARM_HI16 &&
+ ARM16Expr->getKind() != ARMMCExpr::VK_ARM_LO16)) {
+ return Error(Op->getStartLoc(),
+ "immediate expression for mov requires :lower16: or :upper16");
+ break;
+ }
+ }
}
return false;
diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
index 5564e0a8c1..c0857e128e 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
@@ -1040,12 +1040,12 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
return 0;
}
// If the expression doesn't have :upper16: or :lower16: on it,
- // it's just a plain immediate expression, and those evaluate to
+ // it's just a plain immediate expression, previously those evaluated to
// the lower 16 bits of the expression regardless of whether
- // we have a movt or a movw.
- Kind = MCFixupKind(isThumb2(STI) ? ARM::fixup_t2_movw_lo16
- : ARM::fixup_arm_movw_lo16);
- Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc()));
+ // we have a movt or a movw, but that led to misleadingly results.
+ // This is now disallowed in the the AsmParser in validateInstruction()
+ // so this should never happen.
+ assert(0 && "expression without :upper16: or :lower16:");
return 0;
}
diff --git a/test/MC/ARM/arm_fixups.s b/test/MC/ARM/arm_fixups.s
index bd6906bae7..1f56e12852 100644
--- a/test/MC/ARM/arm_fixups.s
+++ b/test/MC/ARM/arm_fixups.s
@@ -26,9 +26,9 @@
@ CHECK-BE: movt r9, :upper16:_foo @ encoding: [0xe3,0b0100AAAA,0x90'A',A]
@ CHECK-BE: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movt_hi16
- mov r2, fred
+ mov r2, :lower16:fred
-@ CHECK: movw r2, fred @ encoding: [A,0x20'A',0b0000AAAA,0xe3]
+@ CHECK: movw r2, :lower16:fred @ encoding: [A,0x20'A',0b0000AAAA,0xe3]
@ CHECK: @ fixup A - offset: 0, value: fred, kind: fixup_arm_movw_lo16
-@ CHECK-BE: movw r2, fred @ encoding: [0xe3,0b0000AAAA,0x20'A',A]
+@ CHECK-BE: movw r2, :lower16:fred @ encoding: [0xe3,0b0000AAAA,0x20'A',A]
@ CHECK-BE: @ fixup A - offset: 0, value: fred, kind: fixup_arm_movw_lo16
diff --git a/test/MC/ARM/complex-operands.s b/test/MC/ARM/complex-operands.s
index 2a721c4e10..72f8f88d2a 100644
--- a/test/MC/ARM/complex-operands.s
+++ b/test/MC/ARM/complex-operands.s
@@ -21,20 +21,20 @@ return:
.global arm_function
.type arm_function,%function
arm_function:
- mov r0, #(.L_table_end - .L_table_begin) >> 2
+ mov r0, #:lower16:((.L_table_end - .L_table_begin) >> 2)
blx return
@ CHECK-LABEL: arm_function
-@ CHECK: movw r0, #(.L_table_end-.L_table_begin)>>2
+@ CHECK: movw r0, :lower16:((.L_table_end-.L_table_begin)>>2)
@ CHECK: blx return
.global thumb_function
.type thumb_function,%function
thumb_function:
- mov r0, #(.L_table_end - .L_table_begin) >> 2
+ mov r0, #:lower16:((.L_table_end - .L_table_begin) >> 2)
blx return
@ CHECK-LABEL: thumb_function
-@ CHECK: movw r0, #(.L_table_end-.L_table_begin)>>2
+@ CHECK: movw r0, :lower16:((.L_table_end-.L_table_begin)>>2)
@ CHECK: blx return
diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s
index 3c26f6d645..62d7daea28 100644
--- a/test/MC/ARM/diagnostics.s
+++ b/test/MC/ARM/diagnostics.s
@@ -465,3 +465,11 @@
ldm sp!, {r0}^
@ CHECK-ERRORS: error: system STM cannot have writeback register
@ CHECK-ERRORS: error: writeback register only allowed on system LDM if PC in register-list
+
+foo2:
+ mov r0, foo2
+ movw r0, foo2
+@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
+@ CHECK-ERRORS: ^
+@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
+@ CHECK-ERRORS: ^
diff --git a/test/MC/ARM/thumb2-diagnostics.s b/test/MC/ARM/thumb2-diagnostics.s
index 6ac2db02cc..bb96db05b9 100644
--- a/test/MC/ARM/thumb2-diagnostics.s
+++ b/test/MC/ARM/thumb2-diagnostics.s
@@ -70,3 +70,14 @@
@ CHECK-ERRORS: error: branch target out of range
@ CHECK-ERRORS: error: branch target out of range
@ CHECK-ERRORS: error: branch target out of range
+
+foo2:
+ mov r0, foo2
+ movw r0, foo2
+ movt r0, foo2
+@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
+@ CHECK-ERRORS: ^
+@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
+@ CHECK-ERRORS: ^
+@ CHECK-ERRORS: error: immediate expression for mov requires :lower16: or :upper16
+@ CHECK-ERRORS: ^