From 1ad60c2adc9ed765a968747d0c548cda53bfd384 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Sat, 10 Sep 2011 00:15:36 +0000 Subject: [PATCH] Thumb2 parsing and encoding for MOV(immediate). Some aliases for MOV(register) also to keep existing T1 tests happy when run in thumbv7 mode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139440 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrThumb2.td | 19 ++++++++-- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 43 ++++++++++++++++++++++- test/MC/ARM/basic-thumb2-instructions.s | 24 +++++++++++++ 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 4b64085563d..2e017ccc52d 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1607,7 +1607,7 @@ defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>; // let neverHasSideEffects = 1 in -def t2MOVr : T2sTwoReg<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVr, +def t2MOVr : T2sTwoReg<(outs GPRnopc:$Rd), (ins GPR:$Rm), IIC_iMOVr, "mov", ".w\t$Rd, $Rm", []> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; @@ -1616,6 +1616,10 @@ def t2MOVr : T2sTwoReg<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVr, let Inst{14-12} = 0b000; let Inst{7-4} = 0b0000; } +def : t2InstAlias<"movs${p}.w $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm, + pred:$p, CPSR)>; +def : t2InstAlias<"movs${p} $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm, + pred:$p, CPSR)>; // AddedComplexity to ensure isel tries t2MOVi before t2MOVi16. let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1, @@ -1630,8 +1634,17 @@ def t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi, let Inst{15} = 0; } -def : t2InstAlias<"mov${s}${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, - pred:$p, cc_out:$s)>; +// cc_out is handled as part of the explicit mnemonic in the parser for 'mov'. +// Use aliases to get that to play nice here. +def : t2InstAlias<"movs${p}.w $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, + pred:$p, CPSR)>; +def : t2InstAlias<"movs${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, + pred:$p, CPSR)>; + +def : t2InstAlias<"mov${p}.w $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, + pred:$p, zero_reg)>; +def : t2InstAlias<"mov${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, + pred:$p, zero_reg)>; let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins imm0_65535_expr:$imm), IIC_iMOVi, diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 44488cbb08e..6120a7085fb 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -3203,7 +3203,7 @@ getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, !isThumb()) || ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) && !isThumb()) || - Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { + Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) { CanAcceptPredicationCode = false; } else { CanAcceptPredicationCode = true; @@ -3765,6 +3765,47 @@ processInstruction(MCInst &Inst, } break; } + case ARM::t2MOVi: { + // If we can use the 16-bit encoding and the user didn't explicitly + // request the 32-bit variant, transform it here. + if (isARMLowRegister(Inst.getOperand(0).getReg()) && + Inst.getOperand(1).getImm() <= 255 && + Inst.getOperand(2).getImm() == ARMCC::AL && + Inst.getOperand(4).getReg() == ARM::CPSR && + (!static_cast(Operands[2])->isToken() || + static_cast(Operands[2])->getToken() != ".w")) { + // The operands aren't in the same order for tMOVi8... + MCInst TmpInst; + TmpInst.setOpcode(ARM::tMOVi8); + TmpInst.addOperand(Inst.getOperand(0)); + TmpInst.addOperand(Inst.getOperand(4)); + TmpInst.addOperand(Inst.getOperand(1)); + TmpInst.addOperand(Inst.getOperand(2)); + TmpInst.addOperand(Inst.getOperand(3)); + Inst = TmpInst; + } + break; + } + case ARM::t2MOVr: { + // If we can use the 16-bit encoding and the user didn't explicitly + // request the 32-bit variant, transform it here. + if (isARMLowRegister(Inst.getOperand(0).getReg()) && + isARMLowRegister(Inst.getOperand(1).getReg()) && + Inst.getOperand(2).getImm() == ARMCC::AL && + Inst.getOperand(4).getReg() == ARM::CPSR && + (!static_cast(Operands[2])->isToken() || + static_cast(Operands[2])->getToken() != ".w")) { + // The operands aren't the same for tMOV[S]r... (no cc_out) + MCInst TmpInst; + TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr); + TmpInst.addOperand(Inst.getOperand(0)); + TmpInst.addOperand(Inst.getOperand(1)); + TmpInst.addOperand(Inst.getOperand(2)); + TmpInst.addOperand(Inst.getOperand(3)); + Inst = TmpInst; + } + break; + } case ARM::t2IT: { // The mask bits for all but the first condition are represented as // the low bit of the condition code value implies 't'. We currently diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s index 4c4938fde77..8a4f6fc05cc 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -988,6 +988,30 @@ _func: @ CHECK: mls r1, r2, r3, r4 @ encoding: [0x02,0xfb,0x13,0x41] +@------------------------------------------------------------------------------ +@ MOV(immediate) +@------------------------------------------------------------------------------ + movs r1, #21 + movs.w r1, #21 + movs r8, #21 + movw r0, #65535 + movw r1, #43777 + movw r1, #43792 + mov.w r0, #0x3fc0000 + mov r0, #0x3fc0000 + movs.w r0, #0x3fc0000 + +@ CHECK: movs r1, #21 @ encoding: [0x15,0x21] +@ CHECK: movs.w r1, #21 @ encoding: [0x5f,0xf0,0x15,0x01] +@ CHECK: movs.w r8, #21 @ encoding: [0x5f,0xf0,0x15,0x08] +@ CHECK: movw r0, #65535 @ encoding: [0x4f,0xf6,0xff,0x70] +@ CHECK: movw r1, #43777 @ encoding: [0x4a,0xf6,0x01,0x31] +@ CHECK: movw r1, #43792 @ encoding: [0x4a,0xf6,0x10,0x31] +@ CHECK: mov.w r0, #66846720 @ encoding: [0x4f,0xf0,0x7f,0x70] +@ CHECK: mov.w r0, #66846720 @ encoding: [0x4f,0xf0,0x7f,0x70] +@ CHECK: movs.w r0, #66846720 @ encoding: [0x5f,0xf0,0x7f,0x70] + + @------------------------------------------------------------------------------ @ IT @------------------------------------------------------------------------------ -- 2.34.1