diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index b9ef6925b51..6335229d3c2 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -1407,3 +1407,11 @@ def : tInstAlias<"cps$imod", (tCPS imod_op:$imod, 0)>; def : tInstAlias<"neg${s}${p} $Rd, $Rm", (tRSB tGPR:$Rd, s_cc_out:$s, tGPR:$Rm, pred:$p)>; + +// Implied destination operand forms for shifts. +def : tInstAlias<"lsl${s}${p} $Rdm, $imm", + (tLSLri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm0_31:$imm, pred:$p)>; +def : tInstAlias<"lsr${s}${p} $Rdm, $imm", + (tLSRri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm_sr:$imm, pred:$p)>; +def : tInstAlias<"asr${s}${p} $Rdm, $imm", + (tASRri tGPR:$Rdm, cc_out:$s, tGPR:$Rdm, imm_sr:$imm, pred:$p)>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 8fa7378ffff..e55a7dad45d 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -6650,6 +6650,37 @@ processInstruction(MCInst &Inst, return true; } + // Handle encoding choice for the shift-immediate instructions. + case ARM::t2LSLri: + case ARM::t2LSRri: + case ARM::t2ASRri: { + if (isARMLowRegister(Inst.getOperand(0).getReg()) && + Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && + Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) && + !(static_cast(Operands[3])->isToken() && + static_cast(Operands[3])->getToken() == ".w")) { + unsigned NewOpc; + switch (Inst.getOpcode()) { + default: llvm_unreachable("unexpected opcode"); + case ARM::t2LSLri: NewOpc = ARM::tLSLri; break; + case ARM::t2LSRri: NewOpc = ARM::tLSRri; break; + case ARM::t2ASRri: NewOpc = ARM::tASRri; break; + } + // The Thumb1 operands aren't in the same order. Awesome, eh? + MCInst TmpInst; + TmpInst.setOpcode(NewOpc); + TmpInst.addOperand(Inst.getOperand(0)); + TmpInst.addOperand(Inst.getOperand(5)); + TmpInst.addOperand(Inst.getOperand(1)); + TmpInst.addOperand(Inst.getOperand(2)); + TmpInst.addOperand(Inst.getOperand(3)); + TmpInst.addOperand(Inst.getOperand(4)); + Inst = TmpInst; + return true; + } + return false; + } + // Handle the Thumb2 mode MOV complex aliases. case ARM::t2MOVsr: case ARM::t2MOVSsr: { diff --git a/test/MC/ARM/basic-thumb-instructions.s b/test/MC/ARM/basic-thumb-instructions.s index 0a083d07228..bc2605c16ec 100644 --- a/test/MC/ARM/basic-thumb-instructions.s +++ b/test/MC/ARM/basic-thumb-instructions.s @@ -97,10 +97,16 @@ _func: asrs r2, r3, #32 asrs r2, r3, #5 asrs r2, r3, #1 + asrs r5, #21 + asrs r5, r5, #21 + asrs r3, r5, #21 @ CHECK: asrs r2, r3, #32 @ encoding: [0x1a,0x10] @ CHECK: asrs r2, r3, #5 @ encoding: [0x5a,0x11] @ CHECK: asrs r2, r3, #1 @ encoding: [0x5a,0x10] +@ CHECK: asrs r5, r5, #21 @ encoding: [0x6d,0x15] +@ CHECK: asrs r5, r5, #21 @ encoding: [0x6d,0x15] +@ CHECK: asrs r3, r5, #21 @ encoding: [0x6b,0x15] @------------------------------------------------------------------------------ @@ -319,9 +325,15 @@ _func: @------------------------------------------------------------------------------ lsls r4, r5, #0 lsls r4, r5, #4 + lsls r3, #12 + lsls r3, r3, #12 + lsls r1, r3, #12 @ CHECK: lsls r4, r5, #0 @ encoding: [0x2c,0x00] @ CHECK: lsls r4, r5, #4 @ encoding: [0x2c,0x01] +@ CHECK: lsls r3, r3, #12 @ encoding: [0x1b,0x03] +@ CHECK: lsls r3, r3, #12 @ encoding: [0x1b,0x03] +@ CHECK: lsls r1, r3, #12 @ encoding: [0x19,0x03] @------------------------------------------------------------------------------ @@ -337,9 +349,15 @@ _func: @------------------------------------------------------------------------------ lsrs r1, r3, #1 lsrs r1, r3, #32 + lsrs r4, #20 + lsrs r4, r4, #20 + lsrs r2, r4, #20 @ CHECK: lsrs r1, r3, #1 @ encoding: [0x59,0x08] @ CHECK: lsrs r1, r3, #32 @ encoding: [0x19,0x08] +@ CHECK: lsrs r4, r4, #20 @ encoding: [0x24,0x0d] +@ CHECK: lsrs r4, r4, #20 @ encoding: [0x24,0x0d] +@ CHECK: lsrs r2, r4, #20 @ encoding: [0x22,0x0d] @------------------------------------------------------------------------------