[llvm-commits] [llvm] r122663 - in /llvm/trunk/lib/Target/ARM: ARMAsmPrinter.cpp ARMAsmPrinter.h ARMISelDAGToDAG.cpp ARMInstrInfo.td

Anton Korobeynikov asl at math.spbu.ru
Sat Jan 1 12:38:38 PST 2011


Author: asl
Date: Sat Jan  1 14:38:38 2011
New Revision: 122663

URL: http://llvm.org/viewvc/llvm-project?rev=122663&view=rev
Log:
Model operand restrictions of mul-like instructions on ARMv5 via
earlyclobber stuff. This should fix PRs 2313 and 8157.

Unfortunately, no testcase, since it'd be dependent on register
assignments.

Modified:
    llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
    llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h
    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td

Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=122663&r1=122662&r2=122663&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Sat Jan  1 14:38:38 2011
@@ -725,6 +725,16 @@
   Inst.addOperand(MCOperand::CreateReg(ccreg));
 }
 
+void ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI,
+                                           unsigned Opcode) {
+  MCInst TmpInst;
+
+  // Emit the instruction as usual, just patch the opcode.
+  LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
+  TmpInst.setOpcode(Opcode);
+  OutStreamer.EmitInstruction(TmpInst);
+}
+
 void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
   switch (MI->getOpcode()) {
   default: break;
@@ -1376,6 +1386,30 @@
     }
     return;
   }
+  // These are the pseudos created to comply with stricter operand restrictions
+  // on ARMv5. Lower them now to "normal" instructions, since all the
+  // restrictions are already satisfied.
+  case ARM::MULv5:
+    EmitPatchedInstruction(MI, ARM::MUL);
+    return;
+  case ARM::MLAv5:
+    EmitPatchedInstruction(MI, ARM::MLA);
+    return;
+  case ARM::SMULLv5:
+    EmitPatchedInstruction(MI, ARM::SMULL);
+    return;
+  case ARM::UMULLv5:
+    EmitPatchedInstruction(MI, ARM::UMULL);
+    return;
+  case ARM::SMLALv5:
+    EmitPatchedInstruction(MI, ARM::SMLAL);
+    return;
+  case ARM::UMLALv5:
+    EmitPatchedInstruction(MI, ARM::UMLAL);
+    return;
+  case ARM::UMAALv5:
+    EmitPatchedInstruction(MI, ARM::UMAAL);
+    return;
   }
 
   MCInst TmpInst;

Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h?rev=122663&r1=122662&r2=122663&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h Sat Jan  1 14:38:38 2011
@@ -79,6 +79,9 @@
   // Helper for ELF .o only
   void emitARMAttributeSection();
 
+  // Generic helper used to emit e.g. ARMv5 mul pseudos
+  void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc);
+
 public:
   void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
 

Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=122663&r1=122662&r2=122663&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Sat Jan  1 14:38:38 2011
@@ -2322,7 +2322,9 @@
       SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
                         CurDAG->getRegister(0, MVT::i32) };
-      return CurDAG->getMachineNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5);
+      return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
+                                    ARM::UMULL : ARM::UMULLv5,
+                                    dl, MVT::i32, MVT::i32, Ops, 5);
     }
   }
   case ISD::SMUL_LOHI: {
@@ -2336,7 +2338,9 @@
       SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
                         CurDAG->getRegister(0, MVT::i32) };
-      return CurDAG->getMachineNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5);
+      return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
+                                    ARM::SMULL : ARM::SMULLv5,
+                                    dl, MVT::i32, MVT::i32, Ops, 5);
     }
   }
   case ISD::LOAD: {

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=122663&r1=122662&r2=122663&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Sat Jan  1 14:38:38 2011
@@ -149,6 +149,7 @@
 def HasV5T           : Predicate<"Subtarget->hasV5TOps()">;
 def HasV5TE          : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate;
 def HasV6            : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate;
+def NoV6             : Predicate<"!Subtarget->hasV6Ops()">;
 def HasV6T2          : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate;
 def NoV6T2           : Predicate<"!Subtarget->hasV6T2Ops()">;
 def HasV7            : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate;
@@ -2504,14 +2505,31 @@
   let Inst{3-0}   = Rn;
 }
 
-let isCommutable = 1 in
+let isCommutable = 1 in {
+let Constraints = "@earlyclobber $Rd" in
+def MULv5: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
+                      IIC_iMUL32, [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
+                      Requires<[IsARM, NoV6]>;
+
 def MUL  : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
                    IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
-                   [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>;
+                   [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
+                   Requires<[IsARM, HasV6]>;
+}
 
+let Constraints = "@earlyclobber $Rd" in
+def MLAv5: PseudoInst<(outs GPR:$Rd),
+                      (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
+                      IIC_iMAC32, [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm),
+                                                      GPR:$Ra))]>, 
+                      Requires<[IsARM, NoV6]> {
+  bits<4> Ra;
+  let Inst{15-12} = Ra;
+}
 def MLA  : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
                     IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
-                   [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]> {
+                   [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
+                   Requires<[IsARM, HasV6]> {
   bits<4> Ra;
   let Inst{15-12} = Ra;
 }
@@ -2534,23 +2552,54 @@
 
 let neverHasSideEffects = 1 in {
 let isCommutable = 1 in {
+let Constraints = "@earlyclobber $RdLo, at earlyclobber $RdHi" in {
+def SMULLv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+                         (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 
+                         IIC_iMUL64, []>,
+                         Requires<[IsARM, NoV6]>;
+
+def UMULLv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+                         (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
+                         IIC_iMUL64, []>,
+                         Requires<[IsARM, NoV6]>;
+}
+
 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
                                (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
-                    "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
+                    "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
+                    Requires<[IsARM, HasV6]>;
 
 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
                                (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
-                    "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
+                    "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
+                    Requires<[IsARM, HasV6]>;
 }
 
 // Multiply + accumulate
+let Constraints = "@earlyclobber $RdLo, at earlyclobber $RdHi" in {
+def SMLALv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+                         (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 
+                         IIC_iMAC64, []>,
+                         Requires<[IsARM, NoV6]>;
+def UMLALv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+                         (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 
+                         IIC_iMAC64, []>,
+                         Requires<[IsARM, NoV6]>;
+def UMAALv5 : PseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
+                         (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 
+                         IIC_iMAC64, []>,
+                         Requires<[IsARM, NoV6]>;
+
+}
+
 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
                                (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
-                    "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
-
+                    "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
+                    Requires<[IsARM, HasV6]>;
 def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi),
                                (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
-                    "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>;
+                    "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
+                    Requires<[IsARM, HasV6]>;
 
 def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
                                (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,





More information about the llvm-commits mailing list