Thumb2 assembly parsing and encoding for MUL.
authorJim Grosbach <grosbach@apple.com>
Wed, 14 Sep 2011 21:00:40 +0000 (21:00 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 14 Sep 2011 21:00:40 +0000 (21:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139735 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/basic-thumb2-instructions.s

index 9453c3d7dd7bbaf794f11af00e13508871b4b779..4314d743b7be99009a5b1786df6ae2a3f733affd 100644 (file)
@@ -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<ARMOperand*>(Operands[4])->getReg()) &&
+        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
         isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
         static_cast<ARMOperand*>(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<ARMOperand*>(Operands[1])->getReg() == 0 &&
+      static_cast<ARMOperand*>(Operands[3])->isReg() &&
+      static_cast<ARMOperand*>(Operands[4])->isReg() &&
+      static_cast<ARMOperand*>(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<ARMOperand*>(Operands[3])->getReg()) ||
+       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
+       !inITBlock() ||
+       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
+        static_cast<ARMOperand*>(Operands[5])->getReg() &&
+        static_cast<ARMOperand*>(Operands[3])->getReg() !=
+        static_cast<ARMOperand*>(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
index bb399868b8cfa4020f754adf245db687f030548a..cca547d673b25b63f3cc221ed8cd3ad7d014c967 100644 (file)
@@ -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
 @------------------------------------------------------------------------------