aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Smith <peter.smith@arm.com>2016-05-12 15:10:45 +0100
committerPeter Smith <peter.smith@arm.com>2016-05-12 15:10:45 +0100
commit9118d2aaba8589b9ef3192859600cedf699826f0 (patch)
treec8bcc2dfd351dd7f01335ce6452286ad7cb6427c
parentc79f16a640c8e32ae20079800f1f4ed595393560 (diff)
[ARM] PR25722 Support and tests for transform of LDR rt, = to MOVlinaro-local/TCWG-468-ALT
This change implements the transformation in processInstruction() for the LDR rt, =expression to MOV rt, expression when the expression can be evaluated and can fit into the immediate field of the MOV or a MVN. Across the ARM and Thumb instruction sets there are several cases to consider, each with a different range of representatble constants. In ARM we have: - Modified immediate (All ARM architectures) - MOVW (v6t2 and above) In Thumb we have: - Modified immediate (v6t2, v7m and v8m.mainline) - MOVW (v6t2, v7m, v8.mainline and v8m.baseline) - Narrow Thumb MOV that can be used in an IT block (non flag-setting) If the immediate fits any of the available alternatives then we make the transformation. Change-Id: Ic2c6981b48af5d7ce535cfbe9860a6d7fc1d90d4 Conflicts: lib/Target/ARM/AsmParser/ARMAsmParser.cpp Conflicts: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp71
-rw-r--r--test/MC/ARM/ldr-pseudo-cond-darwin.s55
-rw-r--r--test/MC/ARM/ldr-pseudo-cond.s55
-rw-r--r--test/MC/ARM/ldr-pseudo-darwin.s101
-rw-r--r--test/MC/ARM/ldr-pseudo-unpredictable.s21
-rw-r--r--test/MC/ARM/ldr-pseudo.s101
6 files changed, 391 insertions, 13 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index bb2628ef724..8b231d3f7d1 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -257,9 +257,15 @@ class ARMAsmParser : public MCTargetAsmParser {
bool hasThumb() const {
return getSTI().getFeatureBits()[ARM::HasV4TOps];
}
+ bool hasThumb2() const {
+ return getSTI().getFeatureBits()[ARM::FeatureThumb2];
+ }
bool hasV6Ops() const {
return getSTI().getFeatureBits()[ARM::HasV6Ops];
}
+ bool hasV6T2Ops() const {
+ return getSTI().getFeatureBits()[ARM::HasV6T2Ops];
+ }
bool hasV6MOps() const {
return getSTI().getFeatureBits()[ARM::HasV6MOps];
}
@@ -5247,7 +5253,6 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
S = Parser.getTok().getLoc();
if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
return Error(S, "unexpected token in operand");
-
Parser.Lex(); // Eat '='
const MCExpr *SubExprVal;
if (getParser().parseExpression(SubExprVal))
@@ -6870,10 +6875,10 @@ bool ARMAsmParser::processInstruction(MCInst &Inst,
return true;
case ARM::LDRConstPool:
case ARM::tLDRConstPool:
- case ARM::t2LDRConstPool: {
- // Handle the pseudo instruction for ldr rn,=
- // For now we always create the constant pool entry and load from it
- // FIXME: Use a MOV or MVN when the immediate will fit
+ case ARM::t2LDRConstPool: {
+ // Pseudo instruction ldr rt, =immediate is converted to a
+ // MOV rt, immediate if immediate is known and representable
+ // otherwise we create a constant pool entry that we load from.
MCInst TmpInst;
if (Inst.getOpcode() == ARM::LDRConstPool)
TmpInst.setOpcode(ARM::LDRi12);
@@ -6884,6 +6889,62 @@ bool ARMAsmParser::processInstruction(MCInst &Inst,
const ARMOperand &PoolOperand =
static_cast<ARMOperand &>(*Operands[3]);
const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
+ // If SubExprVal is a constant we may be able to use a MOV
+ if (isa<MCConstantExpr>(SubExprVal) &&
+ Inst.getOperand(0).getReg() != ARM::PC &&
+ Inst.getOperand(0).getReg() != ARM::SP) {
+ int64_t Value =
+ (int64_t) (cast<MCConstantExpr>(SubExprVal))->getValue();
+ bool UseMov = true;
+ bool MovHasS = true;
+ if (Inst.getOpcode() == ARM::LDRConstPool) {
+ // ARM Constant
+ if (ARM_AM::getSOImmVal(Value) != -1) {
+ Value = ARM_AM::getSOImmVal(Value);
+ TmpInst.setOpcode(ARM::MOVi);
+ }
+ else if (ARM_AM::getSOImmVal(~Value) != -1) {
+ Value = ARM_AM::getSOImmVal(~Value);
+ TmpInst.setOpcode(ARM::MVNi);
+ }
+ else if (hasV6T2Ops() &&
+ Value >=0 && Value < 65536) {
+ TmpInst.setOpcode(ARM::MOVi16);
+ MovHasS = false;
+ }
+ else
+ UseMov = false;
+ }
+ else {
+ // Thumb/Thumb2 Constant
+ if (hasThumb2() &&
+ ARM_AM::getT2SOImmVal(Value) != -1)
+ TmpInst.setOpcode(ARM::t2MOVi);
+ else if (hasThumb2() &&
+ ARM_AM::getT2SOImmVal(~Value) != -1) {
+ TmpInst.setOpcode(ARM::t2MVNi);
+ Value = ~Value;
+ }
+ else if (hasV8MBaseline() &&
+ Value >=0 && Value < 65536) {
+ TmpInst.setOpcode(ARM::t2MOVi16);
+ MovHasS = false;
+ }
+ else
+ UseMov = false;
+ }
+ if (UseMov) {
+ TmpInst.addOperand(Inst.getOperand(0)); // Rt
+ TmpInst.addOperand(MCOperand::createImm(Value)); // Immediate
+ TmpInst.addOperand(Inst.getOperand(2)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+ if (MovHasS)
+ TmpInst.addOperand(MCOperand::createReg(0)); // S
+ Inst = TmpInst;
+ return true;
+ }
+ }
+ // No opportunity to use MOV/MVN create constant pool
const MCExpr *CPLoc =
getTargetStreamer().addConstantPoolEntry(SubExprVal,
PoolOperand.getStartLoc());
diff --git a/test/MC/ARM/ldr-pseudo-cond-darwin.s b/test/MC/ARM/ldr-pseudo-cond-darwin.s
new file mode 100644
index 00000000000..542b060d1e2
--- /dev/null
+++ b/test/MC/ARM/ldr-pseudo-cond-darwin.s
@@ -0,0 +1,55 @@
+@RUN: llvm-mc -triple armv7-base-apple-darwin %s | FileCheck --check-prefix=CHECK-ARM --check-prefix=CHECK %s
+@RUN: llvm-mc -triple thumbv7-base-apple-darwin %s | FileCheck --check-prefix=CHECK-THUMB2 --check-prefix=CHECK %s
+
+@
+@ Check that ldr to constant pool correctly transfers the condition codes
+@
+@ simple test
+.section __TEXT,a,regular,pure_instructions
+@ CHECK-LABEL: f0:
+f0:
+ it eq
+ ldreq r0, =0x10002
+@ CHECK: ldreq r0, Ltmp0
+
+@ loading multiple constants
+.section __TEXT,b,regular,pure_instructions
+@ CHECK-LABEL: f1:
+f1:
+ ite eq
+ ldreq r0, =0x10003
+@ CHECK: ldreq r0, Ltmp1
+ ldrne r0, =0x10004
+@ CHECK: ldrne r0, Ltmp2
+
+@ transformation to mov
+.section __TEXT,d,regular,pure_instructions
+@ CHECK-LABEL: f2:
+f2:
+@ Can use the narrow Thumb mov as it does not set flags in an IT block
+ it eq
+ ldreq r1, =0x1
+@ CHECK: moveq r1, #1
+
+@ Must use the wide Thumb mov if the constant can't be represented
+ ite eq
+ ldreq r2, = 0x1f000000
+@ CHECK-ARM moveq r2, #520093696
+@ CHECK-THUMB2 moveq.w r2, #520093696
+ ldrne r3, = 0x00001234
+@ CHECK movwne r2, #4660
+
+@
+@ Constant Pools
+@
+@ CHECK: .section __TEXT,a,regular,pure_instructions
+@ CHECK: .p2align 2
+@ CHECK: Ltmp0:
+@ CHECK: .long 65538
+
+@ CHECK: .section __TEXT,b,regular,pure_instructions
+@ CHECK: .p2align 2
+@ CHECK: Ltmp1:
+@ CHECK: .long 65539
+@ CHECK: Ltmp2:
+@ CHECK: .long 65540
diff --git a/test/MC/ARM/ldr-pseudo-cond.s b/test/MC/ARM/ldr-pseudo-cond.s
new file mode 100644
index 00000000000..f8d17f6c46b
--- /dev/null
+++ b/test/MC/ARM/ldr-pseudo-cond.s
@@ -0,0 +1,55 @@
+@RUN: llvm-mc -triple armv7-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-ARM --check-prefix=CHECK %s
+@RUN: llvm-mc -triple thumbv7-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-THUMB2 --check-prefix=CHECK %s
+
+@
+@ Check that ldr to constant pool correctly transfers the condition codes
+@
+@ simple test
+.section a,"ax",%progbits
+@ CHECK-LABEL: f0:
+f0:
+ it eq
+ ldreq r0, =0x10002
+@ CHECK: ldreq r0, .Ltmp[[TMP0:[0-9]+]]
+
+@ loading multiple constants
+.section b,"ax",%progbits
+@ CHECK-LABEL: f1:
+f1:
+ ite eq
+ ldreq r0, =0x10003
+@ CHECK: ldreq r0, .Ltmp[[TMP1:[0-9]+]]
+ ldrne r0, =0x10004
+@ CHECK: ldrne r0, .Ltmp[[TMP2:[0-9]+]]
+
+@ transformation to mov
+.section c, "ax", %progbits
+@ CHECK-LABEL: f2:
+f2:
+@ Can use the narrow Thumb mov as it does not set flags in an IT block
+ it eq
+ ldreq r1, =0x1
+@ CHECK: moveq r1, #1
+
+@ Must use the wide Thumb mov if the constant can't be represented
+ ite eq
+ ldreq r2, = 0x1f000000
+@ CHECK-ARM moveq r2, #520093696
+@ CHECK-THUMB2 moveq.w r2, #520093696
+ ldrne r3, = 0x00001234
+@ CHECK movwne r2, #4660
+
+@
+@ Constant Pools
+@
+@ CHECK: .section a,"ax",%progbits
+@ CHECK: .p2align 2
+@ CHECK: .Ltmp[[TMP0]]
+@ CHECK: .long 65538
+
+@ CHECK: .section b,"ax",%progbits
+@ CHECK: .p2align 2
+@ CHECK: .Ltmp[[TMP1]]
+@ CHECK: .long 65539
+@ CHECK: .Ltmp[[TMP2]]
+@ CHECK: .long 65540
diff --git a/test/MC/ARM/ldr-pseudo-darwin.s b/test/MC/ARM/ldr-pseudo-darwin.s
index 2395e1ad2c9..4972cf389e0 100644
--- a/test/MC/ARM/ldr-pseudo-darwin.s
+++ b/test/MC/ARM/ldr-pseudo-darwin.s
@@ -4,10 +4,11 @@
@ between darwin and linux. Any tests added here should have a matching
@ test added there.
-@RUN: llvm-mc -triple armv7-apple-darwin %s | FileCheck %s
-@RUN: llvm-mc -triple thumbv5-apple-darwin %s | FileCheck %s
-@RUN: llvm-mc -triple thumbv7-apple-darwin %s | FileCheck %s
-
+@RUN: llvm-mc -triple armv7-base-apple-darwin %s | FileCheck --check-prefix=CHECK-ARM --check-prefix=CHECK %s
+@RUN: llvm-mc -triple armv5-base-apple-darwin %s | FileCheck --check-prefix=CHECK-ARMV5 --check-prefix=CHECK %s
+@RUN: llvm-mc -triple thumbv5-base-apple-darwin %s | FileCheck --check-prefix=CHECK-THUMB --check-prefix=CHECK %s
+@RUN: llvm-mc -triple thumbv7-base-apple-darwin %s | FileCheck --check-prefix=CHECK-THUMB2 --check-prefix=CHECK %s
+@RUN: llvm-mc -triple thumbv8m.base-base-apple-darwin %s | FileCheck --check-prefix=CHECK-BASELINE --check-prefix=CHECK %s
@
@ Check that large constants are converted to ldr from constant pool
@
@@ -152,6 +153,98 @@ f15:
@ CHECK: ldr r0, Ltmp15
adds r0, r0, #1
+@ transformation to mov
+.section __TEXT,m,regular,pure_instructions
+@ CHECK-LABEL: f16:
+f16:
+
+@ Representable in ARM, and Thumb with support mov.w or movw
+ ldr r1, =0x1
+@ CHECK-ARM: mov r1, #1
+@ CHECK-ARMV5: mov r1, #1
+@ CHECK-THUMB: ldr r1, Ltmp16
+@ CHECK-THUMB2: mov.w r1, #1
+@ CHECK-BASELINE: movw r1, #1
+
+@ Immediate is representable in A1 and T2 modified immediate only not movw
+ ldr r2, =0x120000
+@ CHECK-ARM: mov r2, #1179648
+@ CHECK-ARMV5: mov r2, #1179648
+@ CHECK-THUMB: ldr r2, Ltmp17
+@ CHECK-THUMB2: mov.w r2, #1179648
+@ CHECK-BASELINE: ldr r2, Ltmp16
+
+@ Immediate can be represented only with movw instruction
+ ldr r3, =0x1234
+@ CHECK-ARM: movw r3, #4660
+@ CHECK-ARMV5: ldr r3, Ltmp16
+@ CHECK-THUMB: ldr r3, Ltmp18
+@ CHECK-THUMB2: movw r3, #4660
+@ CHECK-BASELINE: movw r3, #4660
+
+@ Immediate can be represented only with T2 modified immediate
+ ldr r4, =0xabababab
+@ CHECK-ARM: ldr r4, Ltmp16
+@ CHECK-ARMV5: ldr r4, Ltmp17
+@ CHECK-THUMB: ldr r4, Ltmp19
+@ CHECK-THUMB2: mov.w r4, #2880154539
+@ CHECK-BASELINE: ldr r4, Ltmp17
+
+@ Immediate can be represented only with A1 modified immediate
+ ldr r5, =0x1000000b
+@ CHECK-ARM: mov r5, #268435467
+@ CHECK-ARMV5: mov r5, #268435467
+@ CHECK-THUMB: ldr r5, Ltmp20
+@ CHECK-THUMB2: ldr r5, Ltmp16
+@ CHECK-BASELINE: ldr r5, Ltmp18
+
+@ Negative numbers can be used with MVN or in Thumb2 with modified immediate
+ ldr r6, =-1
+@ CHECK-ARM: mvn r6, #0
+@ CHECK-ARMV5: mvn r6, #0
+@ CHECK-THUMB: ldr r6, Ltmp21
+@ CHECK-THUMB2: mov.w r6, #-1
+@ CHECK-BASELINE: ldr r6, Ltmp19
+ ldr r7, =-0x100
+@ CHECK-ARM: mvn r7, #255
+@ CHECK-ARMV5: mvn r7, #255
+@ CHECK-THUMB: ldr r7, Ltmp22
+@ CHECK-THUMB2: mvn r7, #255
+@ CHECK-BASELINE: ldr r7, Ltmp20
+
+@ Constant expressions can be used
+ .equ expr, 0x10 + 0x10
+ ldr r0, = expr
+@ CHECK-ARM: mov r0, #32
+@ CHECK-ARMV5: mov r0, #32
+@ CHECK-THUMB: ldr r0, Ltmp23
+@ CHECK-THUMB2: mov.w r0, #32
+@ CHECK-BASELINE: movw r0, #32
+ ldr r1, = expr - 0x10
+@ CHECK-ARM: mov r1, #16
+@ CHECK-ARMV5: mov r1, #16
+@ CHECK-THUMB: ldr r1, Ltmp24
+@ CHECK-THUMB2: mov.w r1, #16
+@ CHECK-BASELINE: movw r1, #16
+
+@ usage of translation in macro
+.macro usemov_in_a_macro
+ ldr r2, =0x3
+ ldr r3, =expr
+.endm
+@ CHECK-LABEL: f17:
+f17:
+ usemov_in_a_macro
+@ CHECK-ARM: mov r2, #3
+@ CHECK-ARM: mov r3, #32
+@ CHECK-ARMV5: mov r2, #3
+@ CHECK-ARMV5: mov r3, #32
+@ CHECK-THUMB: ldr r2, Ltmp25
+@ CHECK-THUMB: ldr r3, Ltmp26
+@ CHECK-THUMB2: mov.w r2, #3
+@ CHECK-THUMB2: mov.w r3, #32
+@ CHECK-BASELINE: movw r2, #3
+@ CHECK-BASELINE: movw r3, #32
@
@ Constant Pools
@
diff --git a/test/MC/ARM/ldr-pseudo-unpredictable.s b/test/MC/ARM/ldr-pseudo-unpredictable.s
new file mode 100644
index 00000000000..b275dc71ab4
--- /dev/null
+++ b/test/MC/ARM/ldr-pseudo-unpredictable.s
@@ -0,0 +1,21 @@
+@RUN: llvm-mc -triple armv5-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-ARM %s
+@RUN: not llvm-mc -triple thumbv7-unknown-linux-gnueabi %s 2>&1 | FileCheck --check-prefix=CHECK-SP %s
+@RUN: not llvm-mc -triple thumbv5-unknown-linux-gnueabi %s 2>&1 | FileCheck --check-prefix=CHECK-NONE %s
+@RUN: llvm-mc -triple armv5-base-apple-darwin %s | FileCheck --check-prefix=CHECK-DARWIN-ARM %s
+@RUN: not llvm-mc -triple thumbv7-base-apple-darwin %s 2>&1 | FileCheck --check-prefix=CHECK-DARWIN-SP %s
+@RUN: not llvm-mc -triple thumbv5-base.apple.darwin %s 2>&1 | FileCheck --check-prefix=CHECK-NONE %s
+
+@ We dont't do the transformation for rt = sp or pc
+@ as it is unpredictable for many of the MOV encondings
+ ldr pc, = 0x4
+@ CHECK-ARM: ldr pc, .Ltmp[[TMP0:[0-9]+]]
+@ CHECK-DARWIN-ARM: ldr pc, Ltmp0
+@ CHECK-SP: error: instruction requires: arm-mode
+@ CHECK-DARWIN-SP: error: instruction requires: arm-mode
+@ CHECK-NONE: error: instruction requires: arm-mode
+ ldr sp, = 0x8
+@ CHECK-ARM: ldr sp, .Ltmp[[TMP1:[0-9]+]]
+@ CHECK-DARWIN-ARM: ldr sp, Ltmp1
+@ CHECK-SP: ldr.w sp, .Ltmp[[TMP0:[0-9]+]]
+@ CHECK-DARWIN-SP: ldr.w sp, Ltmp0
+@ CHECK-NONE: error: instruction requires: arm-mode
diff --git a/test/MC/ARM/ldr-pseudo.s b/test/MC/ARM/ldr-pseudo.s
index 57bf6e77329..2358c483295 100644
--- a/test/MC/ARM/ldr-pseudo.s
+++ b/test/MC/ARM/ldr-pseudo.s
@@ -4,10 +4,11 @@
@ between darwin and linux. Any tests added here should have a matching
@ test added there.
-@RUN: llvm-mc -triple armv7-unknown-linux-gnueabi %s | FileCheck %s
-@RUN: llvm-mc -triple thumbv5-unknown-linux-gnueabi %s | FileCheck %s
-@RUN: llvm-mc -triple thumbv7-unknown-linux-gnueabi %s | FileCheck %s
-
+@RUN: llvm-mc -triple armv7-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-ARM --check-prefix=CHECK %s
+@RUN: llvm-mc -triple armv5-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-ARMV5 --check-prefix=CHECK %s
+@RUN: llvm-mc -triple thumbv5-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-THUMB --check-prefix=CHECK %s
+@RUN: llvm-mc -triple thumbv7-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-THUMB2 --check-prefix=CHECK %s
+@RUN: llvm-mc -triple thumbv8m.base-unknown-linux-gnueabi %s | FileCheck --check-prefix=CHECK-BASELINE --check-prefix=CHECK %s
@
@ Check that large constants are converted to ldr from constant pool
@
@@ -152,6 +153,98 @@ f15:
@ CHECK: ldr r0, .Ltmp[[TMP15:[0-9]+]]
adds r0, r0, #1
+@ transformation to mov
+.section m, "ax", %progbits
+@ CHECK-LABEL: f16:
+f16:
+
+@ Representable in ARM, and Thumb with support mov.w or movw
+ ldr r1, =0x1
+@ CHECK-ARM: mov r1, #1
+@ CHECK-ARMV5: mov r1, #1
+@ CHECK-THUMB: ldr r1, .Ltmp[[TMP16:[0-9]+]]
+@ CHECK-THUMB2: mov.w r1, #1
+@ CHECK-BASELINE: movw r1, #1
+
+@ Immediate is representable in A1 and T2 modified immediate only not movw
+ ldr r2, =0x120000
+@ CHECK-ARM: mov r2, #1179648
+@ CHECK-ARMV5: mov r2, #1179648
+@ CHECK-THUMB: ldr r2, .Ltmp[[TMP17:[0-9]+]]
+@ CHECK-THUMB2: mov.w r2, #1179648
+@ CHECK-BASELINE: ldr r2, .Ltmp[[TMP16:[0-9]+]]
+
+@ Immediate can be represented only with movw instruction
+ ldr r3, =0x1234
+@ CHECK-ARM: movw r3, #4660
+@ CHECK-ARMV5: ldr r3, .Ltmp[[TMP16:[0-9]+]]
+@ CHECK-THUMB: ldr r3, .Ltmp[[TMP18:[0-9]+]]
+@ CHECK-THUMB2: movw r3, #4660
+@ CHECK-BASELINE: movw r3, #4660
+
+@ Immediate can be represented only with T2 modified immediate
+ ldr r4, =0xabababab
+@ CHECK-ARM: ldr r4, .Ltmp[[TMP16:[0-9]+]]
+@ CHECK-ARMV5: ldr r4, .Ltmp[[TMP17:[0-9]+]]
+@ CHECK-THUMB: ldr r4, .Ltmp[[TMP19:[0-9]+]]
+@ CHECK-THUMB2: mov.w r4, #2880154539
+@ CHECK-BASELINE: ldr r4, .Ltmp[[TMP17:[0-9]+]]
+
+@ Immediate can be represented only with A1 modified immediate
+ ldr r5, =0x1000000b
+@ CHECK-ARM: mov r5, #268435467
+@ CHECK-ARMV5: mov r5, #268435467
+@ CHECK-THUMB: ldr r5, .Ltmp[[TMP20:[0-9]+]]
+@ CHECK-THUMB2: ldr r5, .Ltmp[[TMP16:[0-9]+]]
+@ CHECK-BASELINE: ldr r5, .Ltmp[[TMP18:[0-9]+]]
+
+@ Negative numbers can be used with MVN or in Thumb2 with modified immediate
+ ldr r6, =-1
+@ CHECK-ARM: mvn r6, #0
+@ CHECK-ARMV5: mvn r6, #0
+@ CHECK-THUMB: ldr r6, .Ltmp[[TMP21:[0-9]+]]
+@ CHECK-THUMB2: mov.w r6, #-1
+@ CHECK-BASELINE: ldr r6, .Ltmp[[TMP19:[0-9]+]]
+ ldr r7, =-0x100
+@ CHECK-ARM: mvn r7, #255
+@ CHECK-ARMV5: mvn r7, #255
+@ CHECK-THUMB: ldr r7, .Ltmp[[TMP22:[0-9]+]]
+@ CHECK-THUMB2: mvn r7, #255
+@ CHECK-BASELINE: ldr r7, .Ltmp[[TMP20:[0-9]+]]
+
+@ Constant expressions can be used
+ .equ expr, 0x10 + 0x10
+ ldr r0, = expr
+@ CHECK-ARM: mov r0, #32
+@ CHECK-ARMV5: mov r0, #32
+@ CHECK-THUMB: ldr r0, .Ltmp[[TMP23:[0-9]+]]
+@ CHECK-THUMB2: mov.w r0, #32
+@ CHECK-BASELINE: movw r0, #32
+ ldr r1, = expr - 0x10
+@ CHECK-ARM: mov r1, #16
+@ CHECK-ARMV5: mov r1, #16
+@ CHECK-THUMB: ldr r1, .Ltmp[[TMP24:[0-9]+]]
+@ CHECK-THUMB2: mov.w r1, #16
+@ CHECK-BASELINE: movw r1, #16
+
+@ usage of translation in macro
+.macro usemov_in_a_macro
+ ldr r2, =0x3
+ ldr r3, =expr
+.endm
+@ CHECK-LABEL: f17:
+f17:
+ usemov_in_a_macro
+@ CHECK-ARM: mov r2, #3
+@ CHECK-ARM: mov r3, #32
+@ CHECK-ARMV5: mov r2, #3
+@ CHECK-ARMV5: mov r3, #32
+@ CHECK-THUMB: ldr r2, .Ltmp[[TMP25:[0-9]+]]
+@ CHECK-THUMB: ldr r3, .Ltmp[[TMP26:[0-9]+]]
+@ CHECK-THUMB2: mov.w r2, #3
+@ CHECK-THUMB2: mov.w r3, #32
+@ CHECK-BASELINE: movw r2, #3
+@ CHECK-BASELINE: movw r3, #32
@
@ Constant Pools
@