diff options
| author | Jim Grosbach <grosbach@apple.com> | 2012-04-27 23:51:36 +0000 |
|---|---|---|
| committer | Jim Grosbach <grosbach@apple.com> | 2012-04-27 23:51:36 +0000 |
| commit | c6f32b32955f030f7766cde26d5315c1013029c1 (patch) | |
| tree | 664f5077514a1229fcdc3a629ebc8b0c93a9a50d | |
| parent | 9d8f6f3d9d736b08d85c9aca00cb83d49e810cb8 (diff) | |
| download | bcm5719-llvm-c6f32b32955f030f7766cde26d5315c1013029c1.tar.gz bcm5719-llvm-c6f32b32955f030f7766cde26d5315c1013029c1.zip | |
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
llvm-svn: 155748
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb.td | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 20 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/basic-thumb2-instructions.s | 2 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/thumb-diagnostics.s | 5 |
4 files changed, 29 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index 081c0abd6bd..15cb9fa5d2b 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/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/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 57c76d81cf4..7822501e7ec 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/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/llvm/test/MC/ARM/basic-thumb2-instructions.s b/llvm/test/MC/ARM/basic-thumb2-instructions.s index 4aed9e2bea1..a0dc3dd3a1f 100644 --- a/llvm/test/MC/ARM/basic-thumb2-instructions.s +++ b/llvm/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/llvm/test/MC/ARM/thumb-diagnostics.s b/llvm/test/MC/ARM/thumb-diagnostics.s index 4d09af32ef3..0902f4e6fb3 100644 --- a/llvm/test/MC/ARM/thumb-diagnostics.s +++ b/llvm/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: ^ |

