From f67e8554bf4808ad447ffb5d2deebbb10b810391 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Fri, 16 Sep 2011 22:58:42 +0000 Subject: [PATCH] Thumb2 assembly parsing and encoding for SUB(immediate). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139966 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrThumb.td | 6 ++--- lib/Target/ARM/ARMInstrThumb2.td | 11 +++++++++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 19 +++++++++++---- test/MC/ARM/basic-thumb2-instructions.s | 28 +++++++++++++++++++++++ 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index f8198c86946..a49f9880797 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -1145,7 +1145,7 @@ def tSBC : // A8.6.151 // Subtract immediate def tSUBi3 : // A8.6.210 T1 - T1sIGenEncodeImm<0b01111, (outs tGPR:$Rd), (ins tGPR:$Rm, i32imm:$imm3), + T1sIGenEncodeImm<0b01111, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3), IIC_iALUi, "sub", "\t$Rd, $Rm, $imm3", [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7_neg:$imm3))]> { @@ -1154,8 +1154,8 @@ def tSUBi3 : // A8.6.210 T1 } def tSUBi8 : // A8.6.210 T2 - T1sItGenEncodeImm<{1,1,1,?,?}, (outs tGPR:$Rdn), (ins tGPR:$Rn, i32imm:$imm8), - IIC_iALUi, + T1sItGenEncodeImm<{1,1,1,?,?}, (outs tGPR:$Rdn), + (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi, "sub", "\t$Rdn, $imm8", [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255_neg:$imm8))]>; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index cf157c58363..5aec45ed9d7 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3810,6 +3810,17 @@ def : t2InstAlias<"add${s}${p} $Rd, $Rn, $ShiftedRm", (t2ADDrs rGPR:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm, pred:$p, cc_out:$s)>; +// Aliases for SUB without the ".w" optional width specifier. +def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $imm", + (t2SUBri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; +def : t2InstAlias<"sub${p} $Rd, $Rn, $imm", + (t2SUBri12 rGPR:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>; +def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $Rm", + (t2SUBrr rGPR:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>; +def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $ShiftedRm", + (t2SUBrs rGPR:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm, + pred:$p, cc_out:$s)>; + // Alias for compares without the ".w" optional width specifier. def : t2InstAlias<"cmn${p} $Rn, $Rm", (t2CMNzrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 32c2a6cdf2b..30bed29949c 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -3249,7 +3249,9 @@ bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do // have to check the immediate range here since Thumb2 has a variant // that can handle a different range and has a cc_out operand. - if (isThumb() && Mnemonic == "add" && Operands.size() == 6 && + if (((isThumb() && Mnemonic == "add") || + (isThumbTwo() && Mnemonic == "sub")) && + Operands.size() == 6 && static_cast(Operands[3])->isReg() && static_cast(Operands[4])->isReg() && static_cast(Operands[4])->getReg() == ARM::SP && @@ -3257,12 +3259,13 @@ bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, (static_cast(Operands[5])->isReg() || static_cast(Operands[5])->isImm0_1020s4())) return true; - // For Thumb2, add immediate does not have a cc_out operand for the - // imm0_4096 variant. That's the least-preferred variant when + // For Thumb2, add/sub immediate does not have a cc_out operand for the + // imm0_4095 variant. That's the least-preferred variant when // selecting via the generic "add" mnemonic, so to know that we // should remove the cc_out operand, we have to explicitly check that // it's not one of the other variants. Ugh. - if (isThumbTwo() && Mnemonic == "add" && Operands.size() == 6 && + if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") && + Operands.size() == 6 && static_cast(Operands[3])->isReg() && static_cast(Operands[4])->isReg() && static_cast(Operands[5])->isImm()) { @@ -3750,6 +3753,14 @@ processInstruction(MCInst &Inst, if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) Inst.setOpcode(ARM::tADDi3); break; + case ARM::tSUBi8: + // If the immediate is in the range 0-7, we want tADDi3 iff Rd was + // explicitly specified. From the ARM ARM: "Encoding T1 is preferred + // to encoding T2 if is specified and encoding T2 is preferred + // to encoding T1 if is omitted." + if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) + Inst.setOpcode(ARM::tSUBi3); + 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 3d86850ced8..7f08d480b2b 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -2390,6 +2390,34 @@ _func: @ CHECK: strt r1, [r8, #255] @ encoding: [0x48,0xf8,0xff,0x1e] +@------------------------------------------------------------------------------ +@ SUB (immediate) +@------------------------------------------------------------------------------ + itet eq + subeq r1, r2, #4 + subwne r5, r3, #1023 + subeq r4, r5, #293 + sub r2, sp, #1024 + sub r2, r8, #0xff00 + sub r2, r3, #257 + subw r2, r3, #257 + sub r12, r6, #0x100 + subw r12, r6, #0x100 + subs r1, r2, #0x1f0 + +@ CHECK: itet eq @ encoding: [0x0a,0xbf] +@ CHECK: subeq r1, r2, #4 @ encoding: [0x11,0x1f] +@ CHECK: subwne r5, r3, #1023 @ encoding: [0xa3,0xf2,0xff,0x35] +@ CHECK: subweq r4, r5, #293 @ encoding: [0xa5,0xf2,0x25,0x14] +@ CHECK: sub.w r2, sp, #1024 @ encoding: [0xad,0xf5,0x80,0x62] +@ CHECK: sub.w r2, r8, #65280 @ encoding: [0xa8,0xf5,0x7f,0x42] +@ CHECK: subw r2, r3, #257 @ encoding: [0xa3,0xf2,0x01,0x12] +@ CHECK: subw r2, r3, #257 @ encoding: [0xa3,0xf2,0x01,0x12] +@ CHECK: sub.w r12, r6, #256 @ encoding: [0xa6,0xf5,0x80,0x7c] +@ CHECK: subw r12, r6, #256 @ encoding: [0xa6,0xf2,0x00,0x1c] +@ CHECK: subs.w r1, r2, #496 @ encoding: [0xb2,0xf5,0xf8,0x71] + + @------------------------------------------------------------------------------ @ SUB (register) @------------------------------------------------------------------------------ -- 2.34.1