[llvm-commits] [llvm] r38501 - in /llvm/trunk/lib/Target/ARM: ARMISelDAGToDAG.cpp ARMInstrInfo.cpp ARMInstrInfo.h ARMInstrInfo.td ARMInstrThumb.td ARMInstrVFP.td ARMLoadStoreOptimizer.cpp ARMRegisterInfo.cpp

Evan Cheng evan.cheng at apple.com
Tue Jul 10 11:08:01 PDT 2007


Author: evancheng
Date: Tue Jul 10 13:08:01 2007
New Revision: 38501

URL: http://llvm.org/viewvc/llvm-project?rev=38501&view=rev
Log:
Remove clobbersPred. Add an OptionalDefOperand to instructions which have the 's' bit.

Modified:
    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.h
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
    llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
    llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
    llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
    llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=38501&r1=38500&r2=38501&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Tue Jul 10 13:08:01 2007
@@ -586,8 +586,9 @@
                                   CurDAG->getTargetConstant(0, MVT::i32));
     else {
       SDOperand Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32),
-                          getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) };
-      return CurDAG->SelectNodeTo(N, ARM::ADDri, MVT::i32, Ops, 4);
+                          getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
+                          CurDAG->getRegister(0, MVT::i32) };
+      return CurDAG->SelectNodeTo(N, ARM::ADDri, MVT::i32, Ops, 5);
     }
   }
   case ISD::ADD: {
@@ -619,10 +620,9 @@
         unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1));
         SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
                             CurDAG->getTargetConstant(ShImm, MVT::i32),
-                            getAL(CurDAG), CurDAG->getRegister(0, MVT::i32)
-
-        };
-        return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 6);
+                            getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
+                            CurDAG->getRegister(0, MVT::i32) };
+        return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7);
       }
       if (isPowerOf2_32(RHSV+1)) {  // 2^n-1?
         SDOperand V = Op.getOperand(0);
@@ -631,8 +631,8 @@
         SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
                             CurDAG->getTargetConstant(ShImm, MVT::i32),
                             getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
-        };
-        return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 6);
+                            CurDAG->getRegister(0, MVT::i32) };
+        return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7);
       }
     }
     break;
@@ -645,15 +645,17 @@
     AddToISelQueue(Op.getOperand(0));
     AddToISelQueue(Op.getOperand(1));
     SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1),
-                        getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) };
-    return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32, Ops, 4);
+                        getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
+                        CurDAG->getRegister(0, MVT::i32) };
+    return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32, Ops, 5);
   }
   case ARMISD::MULHILOS: {
     AddToISelQueue(Op.getOperand(0));
     AddToISelQueue(Op.getOperand(1));
     SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1),
-                        getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) };
-    return CurDAG->getTargetNode(ARM::SMULL, MVT::i32, MVT::i32, Ops, 4);
+                        getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
+                        CurDAG->getRegister(0, MVT::i32) };
+    return CurDAG->getTargetNode(ARM::SMULL, MVT::i32, MVT::i32, Ops, 5);
   }
   case ISD::LOAD: {
     LoadSDNode *LD = cast<LoadSDNode>(Op);

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=38501&r1=38500&r2=38501&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Tue Jul 10 13:08:01 2007
@@ -214,15 +214,18 @@
         // add more than 1 instruction. Abandon!
         return NULL;
       UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
-        .addReg(BaseReg).addImm(SOImmVal).addImm(Pred);
+        .addReg(BaseReg).addImm(SOImmVal)
+        .addImm(Pred).addReg(0).addReg(0);
     } else if (Amt != 0) {
       ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
       unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
       UpdateMI = BuildMI(get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
-        .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc).addImm(Pred);
+        .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
+        .addImm(Pred).addReg(0).addReg(0);
     } else 
       UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
-        .addReg(BaseReg).addReg(OffReg).addImm(Pred);
+        .addReg(BaseReg).addReg(OffReg)
+        .addImm(Pred).addReg(0).addReg(0);
     break;
   }
   case ARMII::AddrMode3 : {
@@ -231,10 +234,12 @@
     if (OffReg == 0)
       // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
       UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
-        .addReg(BaseReg).addImm(Amt).addImm(Pred);
+        .addReg(BaseReg).addImm(Amt)
+        .addImm(Pred).addReg(0).addReg(0);
     else
       UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
-        .addReg(BaseReg).addReg(OffReg).addImm(Pred);
+        .addReg(BaseReg).addReg(OffReg)
+        .addImm(Pred).addReg(0).addReg(0);
     break;
   }
   }
@@ -495,6 +500,25 @@
   }
 }
 
+bool ARMInstrInfo::DefinesPredicate(MachineInstr *MI,
+                                    std::vector<MachineOperand> &Pred) const {
+  const TargetInstrDescriptor *TID = MI->getInstrDescriptor();
+  if (!TID->ImplicitDefs && (TID->Flags & M_HAS_OPTIONAL_DEF) == 0)
+    return false;
+
+  bool Found = false;
+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+    const MachineOperand &MO = MI->getOperand(i);
+    if (MO.isReg() && MO.getReg() == ARM::CPSR) {
+      Pred.push_back(MO);
+      Found = true;
+    }
+  }
+
+  return Found;
+}
+
+
 /// FIXME: Works around a gcc miscompilation with -fstrict-aliasing
 static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
                                 unsigned JTI) DISABLE_INLINE;

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.h?rev=38501&r1=38500&r2=38501&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.h Tue Jul 10 13:08:01 2007
@@ -113,6 +113,9 @@
   virtual
   bool SubsumesPredicate(const std::vector<MachineOperand> &Pred1,
                          const std::vector<MachineOperand> &Pred1) const;
+
+  virtual bool DefinesPredicate(MachineInstr *MI,
+                                std::vector<MachineOperand> &Pred) const;
 };
 
   // Utility routines

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=38501&r1=38500&r2=38501&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Jul 10 13:08:01 2007
@@ -380,10 +380,25 @@
   list<Predicate> Predicates = [IsARM];
 }
 
+// Same as I except it can optionally modify CPSR.
+class sI<dag oprnds, AddrMode am, SizeFlagVal sz, IndexMode im,
+        string opc, string asm, string cstr, list<dag> pattern>
+  // FIXME: Set all opcodes to 0 for now.
+  : InstARM<0, am, sz, im, cstr> {
+  let OperandList = !con(oprnds, (ops pred:$p, cc_out:$s));
+  let AsmString   = !strconcat(opc, !strconcat("${p}${s}", asm));
+  let Pattern = pattern;
+  list<Predicate> Predicates = [IsARM];
+}
+
 class AI<dag ops, string opc, string asm, list<dag> pattern>
   : I<ops, AddrModeNone, Size4Bytes, IndexModeNone, opc, asm, "", pattern>;
+class AsI<dag ops, string opc, string asm, list<dag> pattern>
+  : sI<ops, AddrModeNone, Size4Bytes, IndexModeNone, opc, asm, "", pattern>;
 class AI1<dag ops, string opc, string asm, list<dag> pattern>
   : I<ops, AddrMode1, Size4Bytes, IndexModeNone, opc, asm, "", pattern>;
+class AsI1<dag ops, string opc, string asm, list<dag> pattern>
+  : sI<ops, AddrMode1, Size4Bytes, IndexModeNone, opc, asm, "", pattern>;
 class AI2<dag ops, string opc, string asm, list<dag> pattern>
   : I<ops, AddrMode2, Size4Bytes, IndexModeNone, opc, asm, "", pattern>;
 class AI3<dag ops, string opc, string asm, list<dag> pattern>
@@ -412,21 +427,21 @@
 
 /// AI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
 /// binop that produces a value.
-multiclass AI1_bin_irs<string opc, PatFrag opnode> {
-  def ri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
+multiclass AsI1_bin_irs<string opc, PatFrag opnode> {
+  def ri : AsI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
                opc, " $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
-  def rr : AI1<(ops GPR:$dst, GPR:$a, GPR:$b),
+  def rr : AsI1<(ops GPR:$dst, GPR:$a, GPR:$b),
                opc, " $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>;
-  def rs : AI1<(ops GPR:$dst, GPR:$a, so_reg:$b),
+  def rs : AsI1<(ops GPR:$dst, GPR:$a, so_reg:$b),
                opc, " $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
 }
 
-/// AI1_bin_s_irs - Similar to AI1_bin_irs except it sets the 's' bit so the
+/// ASI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
 /// instruction modifies the CSPR register.
-multiclass AI1_bin_s_irs<string opc, PatFrag opnode> {
+multiclass ASI1_bin_s_irs<string opc, PatFrag opnode> {
   def ri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
                opc, "s $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, Imp<[], [CPSR]>;
@@ -439,7 +454,7 @@
 }
 
 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
-/// patterns. Similar to AI1_bin_irs except the instruction does not produce
+/// patterns. Similar to AsI1_bin_irs except the instruction does not produce
 /// a explicit result, only implicitly set CPSR.
 multiclass AI1_cmp_irs<string opc, PatFrag opnode> {
   def ri : AI1<(ops GPR:$a, so_imm:$b),
@@ -453,30 +468,6 @@
                [(opnode GPR:$a, so_reg:$b)]>, Imp<[], [CPSR]>;
 }
 
-/// AI1_bin_is - Defines a set of (op r, {so_imm|so_reg}) patterns for a binop.
-multiclass AI1_bin_is<string opc, PatFrag opnode> {
-  def ri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
-               opc, " $dst, $a, $b",
-               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
-  def rs : AI1<(ops GPR:$dst, GPR:$a, so_reg:$b),
-               opc, " $dst, $a, $b",
-               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
-}
-
-/// AI1_unary_irs - Defines a set of (op {so_imm|r|so_reg}) patterns for unary
-/// ops.
-multiclass AI1_unary_irs<string opc, PatFrag opnode> {
-  def i : AI1<(ops GPR:$dst, so_imm:$a),
-              opc, " $dst, $a",
-              [(set GPR:$dst, (opnode so_imm:$a))]>;
-  def r : AI1<(ops GPR:$dst, GPR:$a),
-              opc, " $dst, $a",
-              [(set GPR:$dst, (opnode GPR:$a))]>;
-  def s : AI1<(ops GPR:$dst, so_reg:$a),
-              opc, " $dst, $a",
-              [(set GPR:$dst, (opnode so_reg:$a))]>;
-}
-
 /// AI_unary_rrot - A unary operation with two forms: one whose operand is a
 /// register and one whose operand is a register rotated by 8/16/24.
 multiclass AI_unary_rrot<string opc, PatFrag opnode> {
@@ -536,17 +527,17 @@
 class JTI2<dag ops, string asm, list<dag> pattern>
   : XI<ops, AddrMode2, SizeSpecial, IndexModeNone, asm, "", pattern>;
 
-/// AXI1_bin_c_irs - Same as AI1_bin_irs but without the predicate operand and
-/// setting carry bit.
-multiclass AXI1_bin_c_irs<string opc, PatFrag opnode> {
-  def ri : AXI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
-               !strconcat(opc, " $dst, $a, $b"),
+/// AsXI1_bin_c_irs - Same as AsI1_bin_irs but without the predicate operand and
+/// setting carry bit. But it can optionally set CPSR.
+multiclass AsXI1_bin_c_irs<string opc, PatFrag opnode> {
+  def ri : AXI1<(ops GPR:$dst, GPR:$a, so_imm:$b, cc_out:$s),
+               !strconcat(opc, "${s} $dst, $a, $b"),
                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, Imp<[CPSR], []>;
-  def rr : AXI1<(ops GPR:$dst, GPR:$a, GPR:$b),
-               !strconcat(opc, " $dst, $a, $b"),
+  def rr : AXI1<(ops GPR:$dst, GPR:$a, GPR:$b, cc_out:$s),
+               !strconcat(opc, "${s} $dst, $a, $b"),
                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>, Imp<[CPSR], []>;
-  def rs : AXI1<(ops GPR:$dst, GPR:$a, so_reg:$b),
-               !strconcat(opc, " $dst, $a, $b"),
+  def rs : AXI1<(ops GPR:$dst, GPR:$a, so_reg:$b, cc_out:$s),
+               !strconcat(opc, "${s} $dst, $a, $b"),
                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>, Imp<[CPSR], []>;
 }
 
@@ -649,7 +640,7 @@
                     "ldm${p}${addr:submode} $addr, $dst1",
                     []>;
 
-let isCall = 1, noResults = 1, clobbersPred = 1,
+let isCall = 1, noResults = 1,
   Defs = [R0, R1, R2, R3, R12, LR,
           D0, D1, D2, D3, D4, D5, D6, D7, CPSR] in {
   def BL  : AXI<(ops i32imm:$func, variable_ops),
@@ -697,7 +688,7 @@
   // FIXME: should be able to write a pattern for ARMBrcond, but can't use
   // a two-value operand where a dag node expects two operands. :( 
   def Bcc : AI<(ops brtarget:$dst), "b", " $dst",
-                 [/*(ARMbrcond bb:$dst, imm:$cc, CCR:$ccr)*/]>;
+                [/*(ARMbrcond bb:$dst, imm:$cc, CCR:$ccr)*/]>;
 }
 
 //===----------------------------------------------------------------------===//
@@ -840,29 +831,28 @@
 //  Move Instructions.
 //
 
-def MOVr : AI1<(ops GPR:$dst, GPR:$src),
-                "mov", " $dst, $src", []>;
-def MOVs : AI1<(ops GPR:$dst, so_reg:$src),
-                "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>;
+def MOVr : AsI1<(ops GPR:$dst, GPR:$src),
+                 "mov", " $dst, $src", []>;
+def MOVs : AsI1<(ops GPR:$dst, so_reg:$src),
+                 "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>;
 
 let isReMaterializable = 1 in
-def MOVi : AI1<(ops GPR:$dst, so_imm:$src),
-                "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>;
+def MOVi : AsI1<(ops GPR:$dst, so_imm:$src),
+                 "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>;
+
+def MOVrx       : AsI1<(ops GPR:$dst, GPR:$src),
+                      "mov", " $dst, $src, rrx",
+                      [(set GPR:$dst, (ARMrrx GPR:$src))]>;
 
 // These aren't really mov instructions, but we have to define them this way
 // due to flag operands.
 
-let clobbersPred = 1 in {
 def MOVsrl_flag : AI1<(ops GPR:$dst, GPR:$src),
                       "mov", "s $dst, $src, lsr #1",
                       [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, Imp<[], [CPSR]>;
 def MOVsra_flag : AI1<(ops GPR:$dst, GPR:$src),
                       "mov", "s $dst, $src, asr #1",
                       [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, Imp<[], [CPSR]>;
-}
-def MOVrx       : AI1<(ops GPR:$dst, GPR:$src),
-                      "mov", " $dst, $src, rrx",
-                      [(set GPR:$dst, (ARMrrx GPR:$src))]>;
 
 //===----------------------------------------------------------------------===//
 //  Extend Instructions.
@@ -907,38 +897,40 @@
 //  Arithmetic Instructions.
 //
 
-defm ADD  : AI1_bin_irs<"add", BinOpFrag<(add  node:$LHS, node:$RHS)>>;
-defm SUB  : AI1_bin_irs<"sub", BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
+defm ADD  : AsI1_bin_irs<"add", BinOpFrag<(add  node:$LHS, node:$RHS)>>;
+defm SUB  : AsI1_bin_irs<"sub", BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
 
 // ADD and SUB with 's' bit set.
-let clobbersPred = 1 in {
-defm ADDS : AI1_bin_s_irs<"add", BinOpFrag<(addc node:$LHS, node:$RHS)>>;
-defm SUBS : AI1_bin_s_irs<"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
-}
+defm ADDS : ASI1_bin_s_irs<"add", BinOpFrag<(addc node:$LHS, node:$RHS)>>;
+defm SUBS : ASI1_bin_s_irs<"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
 
 // FIXME: Do not allow ADC / SBC to be predicated for now.
-defm ADC  : AXI1_bin_c_irs<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>;
-defm SBC  : AXI1_bin_c_irs<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+defm ADC  : AsXI1_bin_c_irs<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>;
+defm SBC  : AsXI1_bin_c_irs<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
 
 // These don't define reg/reg forms, because they are handled above.
-defm RSB  : AI1_bin_is <"rsb", BinOpFrag<(sub  node:$RHS, node:$LHS)>>;
+def RSBri : AsI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
+                  "rsb", " $dst, $a, $b",
+                  [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]>;
+
+def RSBrs : AsI1<(ops GPR:$dst, GPR:$a, so_reg:$b),
+                  "rsb", " $dst, $a, $b",
+                  [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]>;
 
 // RSB with 's' bit set.
-let clobbersPred = 1 in {
 def RSBSri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
                  "rsb", "s $dst, $a, $b",
                  [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]>, Imp<[], [CPSR]>;
 def RSBSrs : AI1<(ops GPR:$dst, GPR:$a, so_reg:$b),
                  "rsb", "s $dst, $a, $b",
                  [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>, Imp<[], [CPSR]>;
-}
 
-// FIXME: Do not allow RSC to be predicated for now.
-def RSCri : AXI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
-                 "rsc $dst, $a, $b",
+// FIXME: Do not allow RSC to be predicated for now. But they can set CPSR.
+def RSCri : AXI1<(ops GPR:$dst, GPR:$a, so_imm:$b, cc_out:$s),
+                 "rsc${s} $dst, $a, $b",
                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>, Imp<[CPSR], []>;
-def RSCrs : AXI1<(ops GPR:$dst, GPR:$a, so_reg:$b),
-                 "rsc $dst, $a, $b",
+def RSCrs : AXI1<(ops GPR:$dst, GPR:$a, so_reg:$b, cc_out:$s),
+                 "rsc${s} $dst, $a, $b",
                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>, Imp<[CPSR], []>;
 
 // (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
@@ -961,18 +953,18 @@
 //  Bitwise Instructions.
 //
 
-defm AND   : AI1_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>>;
-defm ORR   : AI1_bin_irs<"orr", BinOpFrag<(or  node:$LHS, node:$RHS)>>;
-defm EOR   : AI1_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>>;
-defm BIC   : AI1_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
-
-def  MVNr  : AI<(ops GPR:$dst, GPR:$src),
-                "mvn", " $dst, $src", [(set GPR:$dst, (not GPR:$src))]>;
-def  MVNs  : AI<(ops GPR:$dst, so_reg:$src),
-                "mvn", " $dst, $src", [(set GPR:$dst, (not so_reg:$src))]>;
+defm AND   : AsI1_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>>;
+defm ORR   : AsI1_bin_irs<"orr", BinOpFrag<(or  node:$LHS, node:$RHS)>>;
+defm EOR   : AsI1_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>>;
+defm BIC   : AsI1_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
+
+def  MVNr  : AsI<(ops GPR:$dst, GPR:$src),
+                 "mvn", " $dst, $src", [(set GPR:$dst, (not GPR:$src))]>;
+def  MVNs  : AsI<(ops GPR:$dst, so_reg:$src),
+                 "mvn", " $dst, $src", [(set GPR:$dst, (not so_reg:$src))]>;
 let isReMaterializable = 1 in
-def  MVNi  : AI<(ops GPR:$dst, so_imm:$imm),
-                "mvn", " $dst, $imm", [(set GPR:$dst, so_imm_not:$imm)]>;
+def  MVNi  : AsI<(ops GPR:$dst, so_imm:$imm),
+                 "mvn", " $dst, $imm", [(set GPR:$dst, so_imm_not:$imm)]>;
 
 def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
              (BICri GPR:$src, so_imm_not:$imm)>;
@@ -981,46 +973,42 @@
 //  Multiply Instructions.
 //
 
-// AI_orr - Defines a (op r, r) pattern.
-class AI_orr<string opc, SDNode opnode>
-  : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
-       opc, " $dst, $a, $b",
-       [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>;
-
-// AI_oorr - Defines a (op (op r, r), r) pattern.
-class AI_oorr<string opc, SDNode opnode1, SDNode opnode2>
-  : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c),
-       opc, " $dst, $a, $b, $c",
-       [(set GPR:$dst, (opnode1 (opnode2 GPR:$a, GPR:$b), GPR:$c))]>;
-
-def MUL  : AI_orr<"mul", mul>;
-def MLA  : AI_oorr<"mla", add, mul>;
+def MUL  : AsI<(ops GPR:$dst, GPR:$a, GPR:$b),
+                "mul", " $dst, $a, $b",
+                [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
+
+def MLA  : AsI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c),
+                "mla", " $dst, $a, $b, $c",
+                [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
 
 // Extra precision multiplies with low / high results
-def SMULL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
-               "smull", " $ldst, $hdst, $a, $b",
-               []>;
+def SMULL : AsI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
+                "smull", " $ldst, $hdst, $a, $b", []>;
 
-def UMULL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
-               "umull", " $ldst, $hdst, $a, $b",
-               []>;
+def UMULL : AsI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
+                "umull", " $ldst, $hdst, $a, $b", []>;
 
 // Multiply + accumulate
-def SMLAL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
-               "smlal", " $ldst, $hdst, $a, $b",
-               []>;
+def SMLAL : AsI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
+                "smlal", " $ldst, $hdst, $a, $b", []>;
 
-def UMLAL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
-               "umlal", " $ldst, $hdst, $a, $b",
-               []>;
+def UMLAL : AsI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
+                "umlal", " $ldst, $hdst, $a, $b", []>;
 
 def UMAAL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
-               "umaal", " $ldst, $hdst, $a, $b",
-               []>, Requires<[IsARM, HasV6]>;
+               "umaal", " $ldst, $hdst, $a, $b", []>,
+            Requires<[IsARM, HasV6]>;
 
 // Most significant word multiply
-def SMMUL : AI_orr<"smmul", mulhs>, Requires<[IsARM, HasV6]>;
-def SMMLA : AI_oorr<"smmla", add, mulhs>, Requires<[IsARM, HasV6]>;
+def SMMUL : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               "smmul", " $dst, $a, $b",
+               [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
+            Requires<[IsARM, HasV6]>;
+
+def SMMLA : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c),
+               "smmla", " $dst, $a, $b, $c",
+               [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
+            Requires<[IsARM, HasV6]>;
 
 
 def SMMLS : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c),
@@ -1164,7 +1152,6 @@
 //  Comparison Instructions...
 //
 
-let clobbersPred = 1 in {
 defm CMP  : AI1_cmp_irs<"cmp", BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
 defm CMN  : AI1_cmp_irs<"cmn", BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
 
@@ -1174,7 +1161,6 @@
 
 defm CMPnz : AI1_cmp_irs<"cmp", BinOpFrag<(ARMcmpNZ node:$LHS, node:$RHS)>>;
 defm CMNnz : AI1_cmp_irs<"cmn", BinOpFrag<(ARMcmpNZ node:$LHS,(ineg node:$RHS))>>;
-}
 
 def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
              (CMNri  GPR:$src, so_imm_neg:$imm)>;
@@ -1223,8 +1209,8 @@
 //
 
 // __aeabi_read_tp preserves the registers r1-r3.
-let isCall = 1, clobbersPred = 1,
-  Defs = [R0, R12, LR] in {
+let isCall = 1,
+  Defs = [R0, R12, LR, CPSR] in {
   def TPsoft : AXI<(ops),
                "bl __aeabi_read_tp",
                [(set R0, ARMthread_pointer)]>;

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=38501&r1=38500&r2=38501&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Jul 10 13:08:01 2007
@@ -33,7 +33,6 @@
              string asm, string cstr, list<dag> pattern>
   // FIXME: Set all opcodes to 0 for now.
   : InstARM<0, am, sz, IndexModeNone, cstr> {
-  let clobbersPred = 1;
   let OperandList = ops;
   let AsmString   = asm;
   let Pattern = pattern;

Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=38501&r1=38500&r2=38501&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Tue Jul 10 13:08:01 2007
@@ -275,7 +275,6 @@
 
 // FMSRR: GPR -> SPR
 
-let clobbersPred = 1 in
 def FMSTAT : ASI<(ops), "fmstat", "", [(arm_fmstat)]>, Imp<[], [CPSR]>;
 
 // FMXR: GPR -> VFP Sstem reg

Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=38501&r1=38500&r2=38501&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Tue Jul 10 13:08:01 2007
@@ -158,7 +158,7 @@
 
     BuildMI(MBB, MBBI, TII->get(BaseOpc), NewBase)
       .addReg(Base, false, false, BaseKill).addImm(ImmedOffset)
-      .addImm(Pred).addReg(PredReg);
+      .addImm(Pred).addReg(PredReg).addReg(0);
     Base = NewBase;
     BaseKill = true;  // New base is always killed right its use.
   }

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=38501&r1=38500&r2=38501&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Tue Jul 10 13:08:01 2007
@@ -191,7 +191,7 @@
       BuildMI(MBB, I, TII.get(ARM::tMOVr), DestReg).addReg(SrcReg);
     else
       BuildMI(MBB, I, TII.get(ARM::MOVr), DestReg).addReg(SrcReg)
-        .addImm((int64_t)ARMCC::AL).addReg(0);
+        .addImm((int64_t)ARMCC::AL).addReg(0).addReg(0);
   } else if (RC == ARM::SPRRegisterClass)
     BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg).addReg(SrcReg)
       .addImm((int64_t)ARMCC::AL).addReg(0);
@@ -258,6 +258,9 @@
   switch (Opc) {
   default: break;
   case ARM::MOVr: {
+    if (MI->getOperand(4).getReg() == ARM::CPSR)
+      // If it is updating CPSR, then it cannot be foled.
+      break;
     unsigned Pred = MI->getOperand(2).getImmedValue();
     unsigned PredReg = MI->getOperand(3).getReg();
     if (OpNum == 0) { // move -> store
@@ -454,7 +457,7 @@
     // Build the new ADD / SUB.
     BuildMI(MBB, MBBI, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg)
       .addReg(BaseReg, false, false, true).addImm(SOImmVal)
-      .addImm((unsigned)Pred).addReg(PredReg, false);
+      .addImm((unsigned)Pred).addReg(PredReg).addReg(0);
     BaseReg = DestReg;
   }
 }
@@ -1380,7 +1383,7 @@
     MachineInstrBuilder MIB =
       BuildMI(MBB, MBBI, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri),FramePtr)
       .addFrameIndex(FramePtrSpillFI).addImm(0);
-    if (!isThumb) MIB.addImm(ARMCC::AL).addReg(0);
+    if (!isThumb) MIB.addImm(ARMCC::AL).addReg(0).addReg(0);
   }
 
   if (!isThumb) {
@@ -1496,10 +1499,11 @@
             hasFP(MF))
           if (NumBytes)
             BuildMI(MBB, MBBI, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
-              .addImm(NumBytes).addImm((unsigned)ARMCC::AL).addReg(0);
+              .addImm(NumBytes)
+              .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
           else
             BuildMI(MBB, MBBI, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr)
-              .addImm((unsigned)ARMCC::AL).addReg(0);
+              .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
       } else if (NumBytes) {
         emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, false, TII);
       }





More information about the llvm-commits mailing list