From 64944f48a1164c02c15ca423a53919682a89074c Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 14 Sep 2011 21:00:40 +0000 Subject: [PATCH] Thumb2 assembly parsing and encoding for MUL. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139735 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 24 ++++++++++++++++++++++- test/MC/ARM/basic-thumb2-instructions.s | 15 ++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 9453c3d7dd7..4314d743b7b 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -3307,7 +3307,7 @@ bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, // If both registers are low, we're in an IT block, and the immediate is // in range, we should use encoding T1 instead, which has a cc_out. if (inITBlock() && - isARMLowRegister(static_cast(Operands[4])->getReg()) && + isARMLowRegister(static_cast(Operands[3])->getReg()) && isARMLowRegister(static_cast(Operands[4])->getReg()) && static_cast(Operands[5])->isImm0_7()) return false; @@ -3317,6 +3317,28 @@ bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, return true; } + // The thumb2 multiply instruction doesn't have a CCOut register, so + // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to + // use the 16-bit encoding or not. + if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 && + static_cast(Operands[1])->getReg() == 0 && + static_cast(Operands[3])->isReg() && + static_cast(Operands[4])->isReg() && + static_cast(Operands[5])->isReg() && + // If the registers aren't low regs, the destination reg isn't the + // same as one of the source regs, or the cc_out operand is zero + // outside of an IT block, we have to use the 32-bit encoding, so + // remove the cc_out operand. + (!isARMLowRegister(static_cast(Operands[3])->getReg()) || + !isARMLowRegister(static_cast(Operands[4])->getReg()) || + !inITBlock() || + (static_cast(Operands[3])->getReg() != + static_cast(Operands[5])->getReg() && + static_cast(Operands[3])->getReg() != + static_cast(Operands[4])->getReg()))) + return true; + + // Register-register 'add/sub' for thumb does not have a cc_out operand // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s index bb399868b8c..cca547d673b 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -1108,6 +1108,21 @@ _func: @ CHECK: msr CPSR_fsxc, r8 @ encoding: [0x88,0xf3,0x00,0x8f] +@------------------------------------------------------------------------------ +@ MUL +@------------------------------------------------------------------------------ + muls r3, r4, r3 + mul r3, r4, r3 + mul r3, r4, r6 + it eq + muleq r3, r4, r5 + +@ CHECK: muls r3, r4, r3 @ encoding: [0x63,0x43] +@ CHECK: mul r3, r4, r3 @ encoding: [0x04,0xfb,0x03,0xf3] +@ CHECK: mul r3, r4, r6 @ encoding: [0x04,0xfb,0x06,0xf3] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: muleq r3, r4, r5 @ encoding: [0x04,0xfb,0x05,0xf3] + @------------------------------------------------------------------------------ @ IT @------------------------------------------------------------------------------