implement smull and umull


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30975 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 17e0eec..6582a5b 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -174,6 +174,16 @@
                        "mul $dst, $a, $b",
 		       [(set IntRegs:$dst, (mul IntRegs:$a, IntRegs:$b))]>;
 
+let Defs = [R0] in {
+  def SMULL   : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
+                         "smull r12, $dst, $a, $b",
+                         [(set IntRegs:$dst, (mulhs IntRegs:$a, IntRegs:$b))]>;
+
+  def UMULL   : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
+                         "umull r12, $dst, $a, $b",
+                         [(set IntRegs:$dst, (mulhu IntRegs:$a, IntRegs:$b))]>;
+}
+
 def bcond      : InstARM<(ops brtarget:$dst, CCOp:$cc),
 		         "b$cc $dst",
 		         [(armbr bb:$dst, imm:$cc)]>;
diff --git a/lib/Target/ARM/ARMMul.cpp b/lib/Target/ARM/ARMMul.cpp
index 185fb96..474039d 100644
--- a/lib/Target/ARM/ARMMul.cpp
+++ b/lib/Target/ARM/ARMMul.cpp
@@ -8,7 +8,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Modify the ARM multiplication instructions so that Rd and Rm are distinct
+// Modify the ARM multiplication instructions so that Rd{Hi,Lo} and Rm are distinct
 //
 //===----------------------------------------------------------------------===//
 
@@ -39,7 +39,10 @@
          I != E; ++I) {
       MachineInstr *MI = I;
 
-      if (MI->getOpcode() == ARM::MUL) {
+      int Op = MI->getOpcode();
+      if (Op == ARM::MUL ||
+          Op == ARM::SMULL ||
+          Op == ARM::UMULL) {
         MachineOperand &RdOp = MI->getOperand(0);
         MachineOperand &RmOp = MI->getOperand(1);
         MachineOperand &RsOp = MI->getOperand(2);
@@ -48,7 +51,7 @@
         unsigned Rm = RmOp.getReg();
         unsigned Rs = RsOp.getReg();
 
-        if(Rd == Rm) {
+        if (Rd == Rm) {
           Changed = true;
           if (Rd != Rs) {
 	    //Rd and Rm must be distinct, but Rd can be equal to Rs.
@@ -56,9 +59,10 @@
             RmOp.setReg(Rs);
             RsOp.setReg(Rm);
           } else {
-            BuildMI(MBB, I, ARM::MOV, 3, ARM::R12).addReg(Rm).addImm(0)
+            unsigned scratch = Op == ARM::MUL ? ARM::R12 : ARM::R0;
+            BuildMI(MBB, I, ARM::MOV, 3, scratch).addReg(Rm).addImm(0)
               .addImm(ARMShift::LSL);
-            RmOp.setReg(ARM::R12);
+            RmOp.setReg(scratch);
           }
         }
       }
diff --git a/lib/Target/ARM/README.txt b/lib/Target/ARM/README.txt
index 06a8cce..768a2e6 100644
--- a/lib/Target/ARM/README.txt
+++ b/lib/Target/ARM/README.txt
@@ -46,3 +46,8 @@
 Only needs 8 bytes of stack space. We currently allocate 16.
 
 ----------------------------------------------------------
+
+32 x 32 -> 64 multiplications currently uses two instructions. We
+should try to declare smull and umull as returning two values.
+
+----------------------------------------------------------