summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2012-04-27 23:51:36 +0000
committerJim Grosbach <grosbach@apple.com>2012-04-27 23:51:36 +0000
commita9cc08f24f61e2663a131d7ac16c329b75162e7b (patch)
treedc2b18dcff471f7b42d87e2fd3d06cac2bd4a38b
parentbb32f1d545241ab957f402165cec359d4473c0ca (diff)
downloadllvm-a9cc08f24f61e2663a131d7ac16c329b75162e7b.tar.gz
llvm-a9cc08f24f61e2663a131d7ac16c329b75162e7b.tar.bz2
llvm-a9cc08f24f61e2663a131d7ac16c329b75162e7b.tar.xz
ARM: Thumb add(sp plus register) asm constraints.
Make sure when parsing the Thumb1 sp+register ADD instruction that the source and destination operands match. In thumb2, just use the wide encoding if they don't. In Thumb1, issue a diagnostic. rdar://11219154 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155748 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td4
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp20
-rw-r--r--test/MC/ARM/basic-thumb2-instructions.s2
-rw-r--r--test/MC/ARM/thumb-diagnostics.s5
4 files changed, 29 insertions, 2 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index 081c0abd6b..15cb9fa5d2 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -363,8 +363,8 @@ def : tInstAlias<"sub${p} sp, sp, $imm",
(tSUBspi SP, t_imm0_508s4:$imm, pred:$p)>;
// ADD <Rm>, sp
-def tADDrSP : T1pIt<(outs GPR:$Rdn), (ins GPRsp:$sp, GPR:$Rn), IIC_iALUr,
- "add", "\t$Rdn, $sp, $Rn", []>,
+def tADDrSP : T1pI<(outs GPR:$Rdn), (ins GPRsp:$sp, GPR:$Rn), IIC_iALUr,
+ "add", "\t$Rdn, $sp, $Rn", []>,
T1Special<{0,0,?,?}> {
// A8.6.9 Encoding T1
bits<4> Rdn;
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 57c76d81cf..7822501e7e 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -5317,6 +5317,16 @@ validateInstruction(MCInst &Inst,
"registers must be in range r0-r7");
break;
}
+ case ARM::tADDrSP: {
+ // If the non-SP source operand and the destination operand are not the
+ // same, we need thumb2 (for the wide encoding), or we have an error.
+ if (!isThumbTwo() &&
+ Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
+ return Error(Operands[4]->getStartLoc(),
+ "source register must be the same as destination");
+ }
+ break;
+ }
}
return false;
@@ -6990,6 +7000,16 @@ processInstruction(MCInst &Inst,
Inst = TmpInst;
return true;
}
+ case ARM::tADDrSP: {
+ // If the non-SP source operand and the destination operand are not the
+ // same, we need to use the 32-bit encoding if it's available.
+ if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
+ Inst.setOpcode(ARM::t2ADDrr);
+ Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
+ return true;
+ }
+ break;
+ }
case ARM::tB:
// A Thumb conditional branch outside of an IT block is a tBcc.
if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s
index 4aed9e2bea..a0dc3dd3a1 100644
--- a/test/MC/ARM/basic-thumb2-instructions.s
+++ b/test/MC/ARM/basic-thumb2-instructions.s
@@ -48,6 +48,7 @@ _func:
adcs r0, r1, r3, lsl #7
adc.w r0, r1, r3, lsr #31
adcs.w r0, r1, r3, asr #32
+ add r2, sp, ip
@ CHECK: adc.w r4, r5, r6 @ encoding: [0x45,0xeb,0x06,0x04]
@ CHECK: adcs.w r4, r5, r6 @ encoding: [0x55,0xeb,0x06,0x04]
@@ -57,6 +58,7 @@ _func:
@ CHECK: adcs.w r0, r1, r3, lsl #7 @ encoding: [0x51,0xeb,0xc3,0x10]
@ CHECK: adc.w r0, r1, r3, lsr #31 @ encoding: [0x41,0xeb,0xd3,0x70]
@ CHECK: adcs.w r0, r1, r3, asr #32 @ encoding: [0x51,0xeb,0x23,0x00]
+@ CHECK: add.w r2, sp, r12 @ encoding: [0x0d,0xeb,0x0c,0x02]
@------------------------------------------------------------------------------
diff --git a/test/MC/ARM/thumb-diagnostics.s b/test/MC/ARM/thumb-diagnostics.s
index 4d09af32ef..0902f4e6fb 100644
--- a/test/MC/ARM/thumb-diagnostics.s
+++ b/test/MC/ARM/thumb-diagnostics.s
@@ -133,3 +133,8 @@ error: invalid operand for instruction
@ CHECK-ERRORS: error: instruction requires: arm-mode
@ CHECK-ERRORS: add r2, sp, #1024
@ CHECK-ERRORS: ^
+
+ add r2, sp, ip
+@ CHECK-ERRORS: error: source register must be the same as destination
+@ CHECK-ERRORS: add r2, sp, ip
+@ CHECK-ERRORS: ^