Thumb assembly parsing and encoding for MUL.
authorJim Grosbach <grosbach@apple.com>
Fri, 19 Aug 2011 22:07:46 +0000 (22:07 +0000)
committerJim Grosbach <grosbach@apple.com>
Fri, 19 Aug 2011 22:07:46 +0000 (22:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138108 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrThumb.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/basic-thumb-instructions.s
test/MC/ARM/thumb-diagnostics.s

index 5825f9bedef373aa59eb4d960f9d7e5d06e109c5..9163629da143114e2425ccec7be94e4278d80de9 100644 (file)
@@ -1049,10 +1049,20 @@ def tMOVSr      : T1I<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iMOVr,
 // Multiply register
 let isCommutable = 1 in
 def tMUL :                      // A8.6.105 T1
-  T1sItDPEncode<0b1101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
-                IIC_iMUL32,
-                "mul", "\t$Rdn, $Rm, $Rdn",
-                [(set tGPR:$Rdn, (mul tGPR:$Rn, tGPR:$Rm))]>;
+  Thumb1sI<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), AddrModeNone, 2,
+           IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", "$Rm = $Rd",
+           [(set tGPR:$Rd, (mul tGPR:$Rn, tGPR:$Rm))]>,
+      T1DataProcessing<0b1101> {
+  bits<3> Rd;
+  bits<3> Rn;
+  let Inst{5-3} = Rn;
+  let Inst{2-0} = Rd;
+  let AsmMatchConverter = "cvtThumbMultiply";
+}
+
+def : InstAlias<"mul${s}${p} $Rdm, $Rn", (tMUL tGPR:$Rdm, s_cc_out:$s, tGPR:$Rn,
+                                               pred:$p)>,
+          Requires<[IsThumb]>;
 
 // Move inverse register
 def tMVN :                      // A8.6.107
index 33399ec14f865f5c6da38fc039c5a6e91afc6c8f..349513682493949ff20d7a3c0ef79a3465428d66 100644 (file)
@@ -145,6 +145,8 @@ class ARMAsmParser : public MCTargetAsmParser {
                   const SmallVectorImpl<MCParsedAsmOperand*> &);
   bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
                                   const SmallVectorImpl<MCParsedAsmOperand*> &);
+  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
+                        const SmallVectorImpl<MCParsedAsmOperand*> &);
 
   bool validateInstruction(MCInst &Inst,
                            const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
@@ -2371,6 +2373,29 @@ cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
   return true;
 }
 
+/// cvtThumbMultiple- Convert parsed operands to MCInst.
+/// Needed here because the Asm Gen Matcher can't handle properly tied operands
+/// when they refer multiple MIOperands inside a single one.
+bool ARMAsmParser::
+cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
+           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  // The second source operand must be the same register as the destination
+  // operand.
+  if (Operands.size() == 6 &&
+      ((ARMOperand*)Operands[3])->getReg() !=
+      ((ARMOperand*)Operands[5])->getReg()) {
+    Error(Operands[3]->getStartLoc(),
+          "destination register must match second source register");
+    return false;
+  }
+  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
+  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
+  ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1);
+  Inst.addOperand(Inst.getOperand(0));
+  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
+
+  return true;
+}
 
 /// Parse an ARM memory expression, return false if successful else return true
 /// or an error.  The first token must be a '[' when called.
@@ -3220,7 +3245,8 @@ MatchAndEmitInstruction(SMLoc IDLoc,
   case Match_MnemonicFail:
     return Error(IDLoc, "invalid instruction");
   case Match_ConversionFail:
-    return Error(IDLoc, "unable to convert operands to instruction");
+    // The converter function will have already emited a diagnostic.
+    return true;
   case Match_RequiresITBlock:
     return Error(IDLoc, "instruction only valid inside IT block");
   case Match_RequiresV6:
index dcd2cad40cc5bd706f20e54d064d4aca3a83121a..04823ae747950dec5bb2530fcf0071f66e9eb93a 100644 (file)
@@ -321,3 +321,13 @@ _func:
 
 @ CHECK: mov   r3, r4                  @ encoding: [0x23,0x46]
 @ CHECK: movs  r1, r3                  @ encoding: [0x19,0x00]
+
+
+@------------------------------------------------------------------------------
+@ MUL
+@------------------------------------------------------------------------------
+        muls r1, r2, r1
+        muls r3, r4
+
+@ CHECK: muls  r1, r2, r1              @ encoding: [0x51,0x43]
+@ CHECK: muls  r3, r4, r3              @ encoding: [0x63,0x43]
index 6deccacfbd24a0864ffe3eb64d6ee7397c1e455c..f7297d959e5840aabe92b071e2912fb163d4b520 100644 (file)
@@ -62,3 +62,9 @@ error: invalid operand for instruction
 @ CHECK-ERRORS: error: invalid operand for instruction
 @ CHECK-ERRORS:         lsls r4, r5, #32
 @ CHECK-ERRORS:                      ^
+
+@ Mismatched source/destination operands for MUL instruction.
+        muls r1, r2, r3
+@ CHECK-ERRORS: error: destination register must match second source register
+@ CHECK-ERRORS:         muls r1, r2, r3
+@ CHECK-ERRORS:              ^