[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td X86RegisterInfo.cpp

Evan Cheng evan.cheng at apple.com
Mon Jan 9 10:33:40 PST 2006



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.22 -> 1.23
X86ISelLowering.h updated: 1.11 -> 1.12
X86InstrInfo.td updated: 1.190 -> 1.191
X86RegisterInfo.cpp updated: 1.116 -> 1.117
---
Log message:

Support for ADD_PARTS, SUB_PARTS, SHL_PARTS, SHR_PARTS, and SRA_PARTS.


---
Diffs of the changes:  (+313 -103)

 X86ISelLowering.cpp |  126 ++++++++++++++++++++++--
 X86ISelLowering.h   |   21 +++-
 X86InstrInfo.td     |  267 ++++++++++++++++++++++++++++++++++------------------
 X86RegisterInfo.cpp |    2 
 4 files changed, 313 insertions(+), 103 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.22 llvm/lib/Target/X86/X86ISelLowering.cpp:1.23
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.22	Thu Jan  5 18:43:03 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Mon Jan  9 12:33:28 2006
@@ -133,6 +133,12 @@
     setOperationAction(ISD::RET            , MVT::Other, Custom);
     // Darwin ABI issue.
     setOperationAction(ISD::GlobalAddress  , MVT::i32  , Custom);
+    // 64-bit addm sub, shl, sra, srl (iff 32-bit x86)
+    setOperationAction(ISD::ADD_PARTS      , MVT::i32  , Custom);
+    setOperationAction(ISD::SUB_PARTS      , MVT::i32  , Custom);
+    setOperationAction(ISD::SHL_PARTS      , MVT::i32  , Custom);
+    setOperationAction(ISD::SRA_PARTS      , MVT::i32  , Custom);
+    setOperationAction(ISD::SRL_PARTS      , MVT::i32  , Custom);
   }
 
   // We don't have line number support yet.
@@ -243,13 +249,13 @@
     case MVT::f32:
     case MVT::f64:
       if (!X86ScalarSSE) {
+        if (OpVT == MVT::f32)
+          Op = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Op);
         std::vector<MVT::ValueType> Tys;
         Tys.push_back(MVT::Other);
         Tys.push_back(MVT::Flag);
         std::vector<SDOperand> Ops;
         Ops.push_back(Chain);
-        if (OpVT == MVT::f32)
-          Op = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Op);
         Ops.push_back(Op);
         Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
       } else {
@@ -476,7 +482,6 @@
     std::vector<MVT::ValueType> NodeTys;
     NodeTys.push_back(MVT::Other);   // Returns a chain
     NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
-
     std::vector<SDOperand> Ops;
     Ops.push_back(Chain);
     Ops.push_back(Callee);
@@ -991,7 +996,6 @@
     std::vector<MVT::ValueType> NodeTys;
     NodeTys.push_back(MVT::Other);   // Returns a chain
     NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
-
     std::vector<SDOperand> Ops;
     Ops.push_back(Chain);
     Ops.push_back(Callee);
@@ -1193,6 +1197,99 @@
 SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   switch (Op.getOpcode()) {
   default: assert(0 && "Should not custom lower this!");
+  case ISD::ADD_PARTS:
+  case ISD::SUB_PARTS: {
+    assert(Op.getNumOperands() == 4 && Op.getValueType() == MVT::i32 &&
+           "Not an i64 add/sub!");
+    bool isAdd = Op.getOpcode() == ISD::ADD_PARTS;
+    std::vector<MVT::ValueType> Tys;
+    Tys.push_back(MVT::i32);
+    Tys.push_back(MVT::Flag);
+    std::vector<SDOperand> Ops;
+    Ops.push_back(Op.getOperand(0));
+    Ops.push_back(Op.getOperand(2));
+    SDOperand Lo = DAG.getNode(isAdd ? X86ISD::ADD_FLAG : X86ISD::SUB_FLAG,
+                               Tys, Ops);
+    SDOperand Hi = DAG.getNode(isAdd ? X86ISD::ADC : X86ISD::SBB, MVT::i32,
+                               Op.getOperand(1), Op.getOperand(3),
+                               Lo.getValue(1));
+    Tys.clear();
+    Tys.push_back(MVT::i32);
+    Tys.push_back(MVT::i32);
+    Ops.clear();
+    Ops.push_back(Lo);
+    Ops.push_back(Hi);
+    return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
+  }
+  case ISD::SHL_PARTS:
+  case ISD::SRA_PARTS:
+  case ISD::SRL_PARTS: {
+    assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
+           "Not an i64 shift!");
+    bool isSRA = Op.getOpcode() == ISD::SRA_PARTS;
+    SDOperand ShOpLo = Op.getOperand(0);
+    SDOperand ShOpHi = Op.getOperand(1);
+    SDOperand ShAmt  = Op.getOperand(2);
+    SDOperand Tmp1 = isSRA ? DAG.getNode(ISD::SRA, MVT::i32, ShOpHi,
+                                         DAG.getConstant(32, MVT::i32))
+                           : DAG.getConstant(0, MVT::i32);
+
+    SDOperand Tmp2, Tmp3;
+    if (Op.getOpcode() == ISD::SHL_PARTS) {
+      Tmp2 = DAG.getNode(X86ISD::SHLD, MVT::i32, ShOpHi, ShOpLo, ShAmt);
+      Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, ShOpLo, ShAmt);
+    } else {
+      Tmp2 = DAG.getNode(X86ISD::SHRD, MVT::i32, ShOpLo, ShOpHi, ShAmt);
+      Tmp3 = DAG.getNode(isSRA ? ISD::SRA : ISD::SHL, MVT::i32, ShOpHi, ShAmt);
+    }
+
+    SDOperand InFlag = DAG.getNode(X86ISD::TEST, MVT::Flag,
+                                   ShAmt, DAG.getConstant(32, MVT::i8));
+
+    SDOperand Hi, Lo;
+    SDOperand CC = DAG.getConstant(X86ISD::COND_E, MVT::i8);
+
+    std::vector<MVT::ValueType> Tys;
+    Tys.push_back(MVT::i32);
+    Tys.push_back(MVT::Flag);
+    std::vector<SDOperand> Ops;
+    if (Op.getOpcode() == ISD::SHL_PARTS) {
+      Ops.push_back(Tmp2);
+      Ops.push_back(Tmp3);
+      Ops.push_back(CC);
+      Ops.push_back(InFlag);
+      Hi = DAG.getNode(X86ISD::CMOV, Tys, Ops);
+      InFlag = Hi.getValue(1);
+
+      Ops.clear();
+      Ops.push_back(Tmp3);
+      Ops.push_back(Tmp1);
+      Ops.push_back(CC);
+      Ops.push_back(InFlag);
+      Lo = DAG.getNode(X86ISD::CMOV, Tys, Ops);
+    } else {
+      Ops.push_back(Tmp2);
+      Ops.push_back(Tmp3);
+      Ops.push_back(CC);
+      Lo = DAG.getNode(X86ISD::CMOV, Tys, Ops);
+      InFlag = Lo.getValue(1);
+
+      Ops.clear();
+      Ops.push_back(Tmp3);
+      Ops.push_back(Tmp1);
+      Ops.push_back(CC);
+      Ops.push_back(InFlag);
+      Hi = DAG.getNode(X86ISD::CMOV, Tys, Ops);
+    }
+
+    Tys.clear();
+    Tys.push_back(MVT::i32);
+    Tys.push_back(MVT::i32);
+    Ops.clear();
+    Ops.push_back(Lo);
+    Ops.push_back(Hi);
+    return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
+  }
   case ISD::SINT_TO_FP: {
     assert(Op.getValueType() == MVT::f64 &&
            Op.getOperand(0).getValueType() == MVT::i64 &&
@@ -1362,8 +1459,16 @@
       CC = DAG.getConstant(X86ISD::COND_E, MVT::i8);
       Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Cond, Cond);
     }
-    return DAG.getNode(X86ISD::CMOV, Op.getValueType(),
-                       Op.getOperand(1), Op.getOperand(2), CC, Cond);
+
+    std::vector<MVT::ValueType> Tys;
+    Tys.push_back(Op.getValueType());
+    Tys.push_back(MVT::Flag);
+    std::vector<SDOperand> Ops;
+    Ops.push_back(Op.getOperand(1));
+    Ops.push_back(Op.getOperand(2));
+    Ops.push_back(CC);
+    Ops.push_back(Cond);
+    return DAG.getNode(X86ISD::CMOV, Tys, Ops);
   }
   case ISD::BRCOND: {
     SDOperand Cond  = Op.getOperand(1);
@@ -1389,7 +1494,7 @@
   }
   case ISD::RET: {
     // Can only be return void.
-    return DAG.getNode(X86ISD::RET, MVT::Other, Op.getOperand(0),
+    return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0),
                        DAG.getConstant(getBytesToPopOnReturn(), MVT::i16));
   }
   case ISD::GlobalAddress: {
@@ -1414,6 +1519,12 @@
 const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   switch (Opcode) {
   default: return NULL;
+  case X86ISD::ADD_FLAG:           return "X86ISD::ADD_FLAG";
+  case X86ISD::SUB_FLAG:           return "X86ISD::SUB_FLAG";
+  case X86ISD::ADC:                return "X86ISD::ADC";
+  case X86ISD::SBB:                return "X86ISD::SBB";
+  case X86ISD::SHLD:               return "X86ISD::SHLD";
+  case X86ISD::SHRD:               return "X86ISD::SHRD";
   case X86ISD::FILD64m:            return "X86ISD::FILD64m";
   case X86ISD::FP_TO_INT16_IN_MEM: return "X86ISD::FP_TO_INT16_IN_MEM";
   case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM";
@@ -1430,7 +1541,6 @@
   case X86ISD::SETCC:              return "X86ISD::SETCC";
   case X86ISD::CMOV:               return "X86ISD::CMOV";
   case X86ISD::BRCOND:             return "X86ISD::BRCOND";
-  case X86ISD::RET:                return "X86ISD::RET";
   case X86ISD::RET_FLAG:           return "X86ISD::RET_FLAG";
   }
 }


Index: llvm/lib/Target/X86/X86ISelLowering.h
diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.11 llvm/lib/Target/X86/X86ISelLowering.h:1.12
--- llvm/lib/Target/X86/X86ISelLowering.h:1.11	Thu Jan  5 18:43:03 2006
+++ llvm/lib/Target/X86/X86ISelLowering.h	Mon Jan  9 12:33:28 2006
@@ -25,6 +25,21 @@
       // Start the numbering where the builtin ops leave off.
       FIRST_NUMBER = ISD::BUILTIN_OP_END+X86::INSTRUCTION_LIST_END,
 
+      /// ADD_FLAG, SUB_FLAG - Same as ISD::ADD and ISD::SUB except it also
+      /// produces a flag result.
+      ADD_FLAG,
+      SUB_FLAG,
+
+      /// ADC, SBB - Add with carry and subtraction with borrow. These
+      /// correspond to X86::ADCxx and X86::SBBxx instructions.
+      ADC,
+      SBB,
+
+      /// SHLD, SHRD - Double shift instructions. These correspond to
+      /// X86::SHLDxx and X86::SHRDxx instructions.
+      SHLD,
+      SHRD,
+
       /// FILD64m - This instruction implements SINT_TO_FP with a
       /// 64-bit source in memory and a FP reg result.  This corresponds to
       /// the X86::FILD64m instruction.  It has two inputs (token chain and
@@ -99,7 +114,7 @@
       /// X86 conditional moves. Operand 1 and operand 2 are the two values
       /// to select from (operand 1 is a R/W operand). Operand 3 is the condition
       /// code, and operand 4 is the flag operand produced by a CMP or TEST
-      /// instruction.
+      /// instruction. It also writes a flag result.
       CMOV,
 
       /// X86 conditional branches. Operand 1 is the chain operand, operand 2
@@ -108,10 +123,6 @@
       /// or TEST instruction.
       BRCOND,
 
-      /// Return without a flag operand. Operand 1 is the number of bytes of
-      /// stack to pop, and operand 2 is the chain.
-      RET,
-
       /// Return with a flag operand. Operand 1 is the number of bytes of stack
       /// to pop, operand 2 is the chain and operand 3 is a flag operand.
       RET_FLAG,


Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.190 llvm/lib/Target/X86/X86InstrInfo.td:1.191
--- llvm/lib/Target/X86/X86InstrInfo.td:1.190	Thu Jan  5 20:31:59 2006
+++ llvm/lib/Target/X86/X86InstrInfo.td	Mon Jan  9 12:33:28 2006
@@ -17,6 +17,10 @@
 // X86 specific DAG Nodes.
 //
 
+def SDTIntShiftDOp: SDTypeProfile<1, 3,
+                                  [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
+                                   SDTCisInt<0>, SDTCisInt<3>]>;
+
 def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisSameAs<1, 2>]>;
 
 def SDTX86Cmov    : SDTypeProfile<1, 4,
@@ -33,43 +37,67 @@
 
 def SDTX86Ret     : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>;
 
+def SDT_X86CallSeqStart : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
+def SDT_X86CallSeqEnd   : SDTypeProfile<0, 2, [ SDTCisVT<0, i32>,
+                                                SDTCisVT<1, i32> ]>;
+
+def SDT_X86Call   : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
+
+def SDTX86FpGet   : SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>;
+def SDTX86FpSet   : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
+
 def SDTX86Fld     : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
                                          SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
 def SDTX86Fst     : SDTypeProfile<0, 3, [SDTCisFP<0>,
                                          SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
 
+def SDTX86RdTsc   : SDTypeProfile<0, 0, []>;
 
-def SDTX86FpGet   : SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>;
-def SDTX86FpSet   : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
+def X86addflag : SDNode<"X86ISD::ADD_FLAG", SDTIntBinOp ,
+                        [SDNPCommutative, SDNPAssociative, SDNPOutFlag]>;
+def X86subflag : SDNode<"X86ISD::SUB_FLAG", SDTIntBinOp,
+                        [SDNPOutFlag]>;
+def X86adc     : SDNode<"X86ISD::ADC" ,     SDTIntBinOp ,
+                        [SDNPCommutative, SDNPAssociative]>;
+def X86sbb     : SDNode<"X86ISD::SBB" ,     SDTIntBinOp>;
+
+def X86shld    : SDNode<"X86ISD::SHLD",     SDTIntShiftDOp>;
+def X86shrd    : SDNode<"X86ISD::SHRD",     SDTIntShiftDOp>;
 
 def X86cmp     : SDNode<"X86ISD::CMP" ,     SDTX86CmpTest,  []>;
 def X86test    : SDNode<"X86ISD::TEST",     SDTX86CmpTest,  []>;
 
-def X86cmov    : SDNode<"X86ISD::CMOV",     SDTX86Cmov,     []>;
-def X86brcond  : SDNode<"X86ISD::BRCOND",   SDTX86BrCond,   [SDNPHasChain]>;
+def X86cmov    : SDNode<"X86ISD::CMOV",     SDTX86Cmov,    
+                        [SDNPOutFlag]>;
+def X86brcond  : SDNode<"X86ISD::BRCOND",   SDTX86BrCond,
+                        [SDNPHasChain]>;
 def X86setcc   : SDNode<"X86ISD::SETCC",    SDTX86SetCC,    []>;
 
-def X86ret     : SDNode<"X86ISD::RET",      SDTX86Ret,      [SDNPHasChain]>;
-def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,      [SDNPHasChain]>;
+def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
+                        [SDNPHasChain, SDNPOptInFlag]>;
 
-def X86fld     : SDNode<"X86ISD::FLD",      SDTX86Fld,      [SDNPHasChain]>;
-def X86fst     : SDNode<"X86ISD::FST",      SDTX86Fst,      [SDNPHasChain]>;
+def X86callseq_start :
+                 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
+                        [SDNPHasChain]>;
+def X86callseq_end :
+                 SDNode<"ISD::CALLSEQ_END",   SDT_X86CallSeqEnd,
+                        [SDNPHasChain]>;
+
+def X86call    : SDNode<"X86ISD::CALL",     SDT_X86Call,
+                        [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
+
+def X86fpget   : SDNode<"X86ISD::FP_GET_RESULT", SDTX86FpGet,
+                        [SDNPHasChain, SDNPInFlag]>;
+def X86fpset   : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet,
+                        [SDNPHasChain, SDNPOutFlag]>;
+
+def X86fld     : SDNode<"X86ISD::FLD",      SDTX86Fld,
+                        [SDNPHasChain]>;
+def X86fst     : SDNode<"X86ISD::FST",      SDTX86Fst,
+                        [SDNPHasChain]>;
 
-def X86fpget   : SDNode<"X86ISD::FP_GET_RESULT",
-                                            SDTX86FpGet,    [SDNPHasChain]>;
-def X86fpset   : SDNode<"X86ISD::FP_SET_RESULT",
-                                            SDTX86FpSet,    [SDNPHasChain]>;
-
-def SDT_X86CallSeqStart : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
-def SDT_X86CallSeqEnd   : SDTypeProfile<0, 2, [ SDTCisVT<0, i32>,
-                                                SDTCisVT<1, i32> ]>;
-def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
-                           [SDNPHasChain]>;
-def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_X86CallSeqEnd,
-                           [SDNPHasChain]>;
-
-def SDT_X86Call   : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
-def call          : SDNode<"X86ISD::CALL", SDT_X86Call, [SDNPHasChain]>;
+def X86rdtsc   : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
+                        [SDNPHasChain, SDNPOutFlag]>;
 
 //===----------------------------------------------------------------------===//
 // X86 Operand Definitions.
@@ -334,10 +362,10 @@
 def NOOP : I<0x90, RawFrm, (ops), "nop", []>; // nop
 
 def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN",
-                         [(callseq_start imm:$amt)]>;
+                         [(X86callseq_start imm:$amt)]>;
 def ADJCALLSTACKUP   : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2),
                          "#ADJCALLSTACKUP",
-                         [(callseq_end imm:$amt1, imm:$amt2)]>;
+                         [(X86callseq_end imm:$amt1, imm:$amt2)]>;
 def IMPLICIT_USE     : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_USE", []>;
 def IMPLICIT_DEF     : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_DEF", []>;
 let isTerminator = 1 in
@@ -351,15 +379,9 @@
 // Return instructions.
 let isTerminator = 1, isReturn = 1, isBarrier = 1,
     hasCtrlDep = 1, noResults = 1 in {
-  // FIXME: temporary workaround for return without an incoming flag.
-  def RETVOID  : I<0xC3, RawFrm, (ops), "ret", [(X86ret 0)]>;
-  def RETIVOID : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt",
-                      [(X86ret imm:$amt)]>;
-  let hasInFlag = 1 in {
-    def RET    : I<0xC3, RawFrm, (ops), "ret", [(X86retflag 0)]>;
-    def RETI   : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt",
-                      [(X86retflag imm:$amt)]>;
-  }
+  def RET    : I<0xC3, RawFrm, (ops), "ret", [(X86retflag 0)]>;
+  def RETI   : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt",
+                    [(X86retflag imm:$amt)]>;
 }
 
 // All branches are RawFrm, Void, Branch, and Terminators
@@ -404,23 +426,21 @@
 //===----------------------------------------------------------------------===//
 //  Call Instructions...
 //
-// FIXME: How about hasInFlag = 1? A fastcall would require an incoming flag
-// to stick the CopyToRegs to the call.
-let isCall = 1, noResults = 1, hasOutFlag = 1 in
+let isCall = 1, noResults = 1 in
   // All calls clobber the non-callee saved registers...
   let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
               XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in {
     def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst",
                       []>;
     def CALL32r     : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst",
-                      [(call R32:$dst)]>;
+                      [(X86call R32:$dst)]>;
     def CALL32m     : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst",
-                      [(call (loadi32 addr:$dst))]>;
+                      [(X86call (loadi32 addr:$dst))]>;
   }
 
-def : Pat<(call tglobaladdr:$dst),
+def : Pat<(X86call tglobaladdr:$dst),
           (CALLpcrel32 tglobaladdr:$dst)>;
-def : Pat<(call externalsym:$dst),
+def : Pat<(X86call externalsym:$dst),
           (CALLpcrel32 externalsym:$dst)>;
 
 // Tail call stuff.
@@ -1544,64 +1564,94 @@
 // Double shift instructions (generalizations of rotate)
 
 def SHLD32rrCL : I<0xA5, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
-                   "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
+                   "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
+                   [(set R32:$dst, (X86shld R32:$src1, R32:$src2, CL))]>,
                    Imp<[CL],[]>, TB;
 def SHRD32rrCL : I<0xAD, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
-                   "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
+                   "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
+                   [(set R32:$dst, (X86shrd R32:$src1, R32:$src2, CL))]>,
                    Imp<[CL],[]>, TB;
 def SHLD16rrCL : I<0xA5, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
-                   "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
+                   "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
+                   [(set R16:$dst, (X86shld R16:$src1, R16:$src2, CL))]>,
                    Imp<[CL],[]>, TB, OpSize;
 def SHRD16rrCL : I<0xAD, MRMDestReg, (ops R16:$dst, R16:$src1, R16:$src2),
-                   "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
+                   "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
+                   [(set R16:$dst, (X86shrd R16:$src1, R16:$src2, CL))]>,
                    Imp<[CL],[]>, TB, OpSize;
 
 let isCommutable = 1 in {  // These instructions commute to each other.
 def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
                      (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
-                     "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>, TB;
+                     "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
+                     [(set R32:$dst, (X86shld R32:$src1, R32:$src2,
+                                      (i8 imm:$src3)))]>,
+                 TB;
 def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
                      (ops R32:$dst, R32:$src1, R32:$src2, i8imm:$src3),
-                     "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>, TB;
+                     "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
+                     [(set R32:$dst, (X86shrd R32:$src1, R32:$src2,
+                                      (i8 imm:$src3)))]>,
+                 TB;
 def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
                      (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
-                     "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
+                     "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
+                     [(set R16:$dst, (X86shld R16:$src1, R16:$src2,
+                                      (i8 imm:$src3)))]>,
                      TB, OpSize;
 def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
                      (ops R16:$dst, R16:$src1, R16:$src2, i8imm:$src3),
-                     "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
+                     "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
+                     [(set R16:$dst, (X86shrd R16:$src1, R16:$src2,
+                                      (i8 imm:$src3)))]>,
                      TB, OpSize;
 }
 
 let isTwoAddress = 0 in {
   def SHLD32mrCL : I<0xA5, MRMDestMem, (ops i32mem:$dst, R32:$src2),
-                     "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
+                     "shld{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
+                     [(store (X86shld (loadi32 addr:$dst), R32:$src2, CL),
+                       addr:$dst)]>,
                      Imp<[CL],[]>, TB;
   def SHRD32mrCL : I<0xAD, MRMDestMem, (ops i32mem:$dst, R32:$src2),
-                    "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
+                    "shrd{l} {%cl, $src2, $dst|$dst, $src2, %CL}",
+                    [(store (X86shrd (loadi32 addr:$dst), R32:$src2, CL),
+                      addr:$dst)]>,
                     Imp<[CL],[]>, TB;
   def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
                       (ops i32mem:$dst, R32:$src2, i8imm:$src3),
-                      "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
+                      "shld{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
+                      [(store (X86shld (loadi32 addr:$dst), R32:$src2,
+                                        (i8 imm:$src3)), addr:$dst)]>,
                       TB;
   def SHRD32mri8 : Ii8<0xAC, MRMDestMem, 
                        (ops i32mem:$dst, R32:$src2, i8imm:$src3),
-                       "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
+                       "shrd{l} {$src3, $src2, $dst|$dst, $src2, $src3}",
+                       [(store (X86shrd (loadi32 addr:$dst), R32:$src2,
+                                         (i8 imm:$src3)), addr:$dst)]>,
                        TB;
 
   def SHLD16mrCL : I<0xA5, MRMDestMem, (ops i16mem:$dst, R16:$src2),
-                     "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
+                     "shld{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
+                     [(store (X86shld (loadi16 addr:$dst), R16:$src2, CL),
+                       addr:$dst)]>,
                      Imp<[CL],[]>, TB, OpSize;
   def SHRD16mrCL : I<0xAD, MRMDestMem, (ops i16mem:$dst, R16:$src2),
-                    "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
+                    "shrd{w} {%cl, $src2, $dst|$dst, $src2, %CL}",
+                    [(store (X86shrd (loadi16 addr:$dst), R16:$src2, CL),
+                      addr:$dst)]>,
                     Imp<[CL],[]>, TB, OpSize;
   def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
                       (ops i16mem:$dst, R16:$src2, i8imm:$src3),
-                      "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
+                      "shld{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
+                      [(store (X86shld (loadi16 addr:$dst), R16:$src2,
+                                        (i8 imm:$src3)), addr:$dst)]>,
                       TB, OpSize;
   def SHRD16mri8 : Ii8<0xAC, MRMDestMem, 
                        (ops i16mem:$dst, R16:$src2, i8imm:$src3),
-                       "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
+                       "shrd{w} {$src3, $src2, $dst|$dst, $src2, $src3}",
+                      [(store (X86shrd (loadi16 addr:$dst), R16:$src2,
+                                        (i8 imm:$src3)), addr:$dst)]>,
                        TB, OpSize;
 }
 
@@ -1684,22 +1734,29 @@
 
 let isCommutable = 1 in {  // X = ADC Y, Z --> X = ADC Z, Y
 def ADC32rr  : I<0x11, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
-                 "adc{l} {$src2, $dst|$dst, $src2}", []>;
+                 "adc{l} {$src2, $dst|$dst, $src2}",
+                 [(set R32:$dst, (X86adc R32:$src1, R32:$src2))]>;
 }
 def ADC32rm  : I<0x13, MRMSrcMem , (ops R32:$dst, R32:$src1, i32mem:$src2),
-                 "adc{l} {$src2, $dst|$dst, $src2}", []>;
+                 "adc{l} {$src2, $dst|$dst, $src2}",
+                 [(set R32:$dst, (X86adc R32:$src1, (load addr:$src2)))]>;
 def ADC32ri  : Ii32<0x81, MRM2r, (ops R32:$dst, R32:$src1, i32imm:$src2),
-                    "adc{l} {$src2, $dst|$dst, $src2}", []>;
-def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i8imm:$src2),
-                   "adc{l} {$src2, $dst|$dst, $src2}", []>;
+                    "adc{l} {$src2, $dst|$dst, $src2}",
+                 [(set R32:$dst, (X86adc R32:$src1, imm:$src2))]>;
+def ADC32ri8 : Ii8<0x83, MRM2r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
+                   "adc{l} {$src2, $dst|$dst, $src2}",
+                 [(set R32:$dst, (X86adc R32:$src1, i32immSExt8:$src2))]>;
 
 let isTwoAddress = 0 in {
   def ADC32mr  : I<0x11, MRMDestMem, (ops i32mem:$dst, R32:$src2),
-                   "adc{l} {$src2, $dst|$dst, $src2}", []>;
+                   "adc{l} {$src2, $dst|$dst, $src2}",
+                   [(store (X86adc (load addr:$dst), R32:$src2), addr:$dst)]>;
   def ADC32mi  : Ii32<0x81, MRM2m, (ops i32mem:$dst, i32imm:$src2),
-                      "adc{l} {$src2, $dst|$dst, $src2}", []>;
-  def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i8imm :$src2),
-                     "adc{l} {$src2, $dst|$dst, $src2}", []>;
+                      "adc{l} {$src2, $dst|$dst, $src2}",
+                  [(store (X86adc (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
+  def ADC32mi8 : Ii8<0x83, MRM2m, (ops i32mem:$dst, i32i8imm :$src2),
+                     "adc{l} {$src2, $dst|$dst, $src2}",
+             [(store (X86adc (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
 }
 
 def SUB8rr   : I<0x28, MRMDestReg, (ops R8 :$dst, R8 :$src1, R8 :$src2),
@@ -1768,36 +1825,52 @@
 }
 
 def SBB32rr    : I<0x19, MRMDestReg, (ops R32:$dst, R32:$src1, R32:$src2),
-                  "sbb{l} {$src2, $dst|$dst, $src2}", []>;
+                  "sbb{l} {$src2, $dst|$dst, $src2}",
+                  [(set R32:$dst, (X86sbb R32:$src1, R32:$src2))]>;
 
 let isTwoAddress = 0 in {
   def SBB32mr  : I<0x19, MRMDestMem, (ops i32mem:$dst, R32:$src2), 
-                   "sbb{l} {$src2, $dst|$dst, $src2}", []>;
+                   "sbb{l} {$src2, $dst|$dst, $src2}",
+                   [(store (X86sbb (load addr:$dst), R32:$src2), addr:$dst)]>;
   def SBB8mi  : Ii32<0x80, MRM3m, (ops i8mem:$dst, i8imm:$src2), 
-                      "sbb{b} {$src2, $dst|$dst, $src2}", []>;
+                      "sbb{b} {$src2, $dst|$dst, $src2}",
+                   [(store (X86sbb (loadi8 addr:$dst), imm:$src2), addr:$dst)]>;
   def SBB16mi  : Ii32<0x81, MRM3m, (ops i16mem:$dst, i16imm:$src2), 
-                      "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
+                      "sbb{w} {$src2, $dst|$dst, $src2}",
+                  [(store (X86sbb (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
+                     OpSize;
   def SBB32mi  : Ii32<0x81, MRM3m, (ops i32mem:$dst, i32imm:$src2), 
-                      "sbb{l} {$src2, $dst|$dst, $src2}", []>;
-  def SBB16mi8 : Ii8<0x83, MRM3m, (ops i16mem:$dst, i8imm :$src2), 
-                     "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
-  def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i8imm :$src2), 
-                     "sbb{l} {$src2, $dst|$dst, $src2}", []>;
+                      "sbb{l} {$src2, $dst|$dst, $src2}",
+                  [(store (X86sbb (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
+  def SBB16mi8 : Ii8<0x83, MRM3m, (ops i16mem:$dst, i16i8imm :$src2), 
+                     "sbb{w} {$src2, $dst|$dst, $src2}",
+             [(store (X86sbb (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
+                     OpSize;
+  def SBB32mi8 : Ii8<0x83, MRM3m, (ops i32mem:$dst, i32i8imm :$src2), 
+                     "sbb{l} {$src2, $dst|$dst, $src2}",
+             [(store (X86sbb (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
 }
 def SBB8ri   : Ii8<0x80, MRM3r, (ops R8:$dst, R8:$src1, i8imm:$src2),
-                    "sbb{b} {$src2, $dst|$dst, $src2}", []>;
+                    "sbb{b} {$src2, $dst|$dst, $src2}",
+                    [(set R8:$dst, (X86sbb R8:$src1, imm:$src2))]>;
 def SBB16ri  : Ii16<0x81, MRM3r, (ops R16:$dst, R16:$src1, i16imm:$src2),
-                    "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
+                    "sbb{w} {$src2, $dst|$dst, $src2}",
+                    [(set R16:$dst, (X86sbb R16:$src1, imm:$src2))]>, OpSize;
 
 def SBB32rm  : I<0x1B, MRMSrcMem, (ops R32:$dst, R32:$src1, i32mem:$src2),
-                    "sbb{l} {$src2, $dst|$dst, $src2}", []>;
+                    "sbb{l} {$src2, $dst|$dst, $src2}",
+                    [(set R32:$dst, (X86sbb R32:$src1, (load addr:$src2)))]>;
 def SBB32ri  : Ii32<0x81, MRM3r, (ops R32:$dst, R32:$src1, i32imm:$src2),
-                    "sbb{l} {$src2, $dst|$dst, $src2}", []>;
+                    "sbb{l} {$src2, $dst|$dst, $src2}",
+                    [(set R32:$dst, (X86sbb R32:$src1, imm:$src2))]>;
 
-def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i8imm:$src2),
-                   "sbb{w} {$src2, $dst|$dst, $src2}", []>, OpSize;
-def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i8imm:$src2),
-                   "sbb{l} {$src2, $dst|$dst, $src2}", []>;
+def SBB16ri8 : Ii8<0x83, MRM3r, (ops R16:$dst, R16:$src1, i16i8imm:$src2),
+                   "sbb{w} {$src2, $dst|$dst, $src2}",
+                   [(set R16:$dst, (X86sbb R16:$src1, i16immSExt8:$src2))]>,
+                   OpSize;
+def SBB32ri8 : Ii8<0x83, MRM3r, (ops R32:$dst, R32:$src1, i32i8imm:$src2),
+                   "sbb{l} {$src2, $dst|$dst, $src2}",
+                   [(set R32:$dst, (X86sbb R32:$src1, i32immSExt8:$src2))]>;
 
 let isCommutable = 1 in {  // X = IMUL Y, Z --> X = IMUL Z, Y
 def IMUL16rr : I<0xAF, MRMSrcReg, (ops R16:$dst, R16:$src1, R16:$src2),
@@ -1817,6 +1890,25 @@
 
 } // end Two Address instructions
 
+// X86 specific add which produces a flag.
+def : Pat<(X86addflag R32:$src1, R32:$src2),
+          (ADD32rr R32:$src1, R32:$src2)>;
+def : Pat<(X86addflag R32:$src1, (load addr:$src2)),
+          (ADD32rm R32:$src1, addr:$src2)>;
+def : Pat<(X86addflag R32:$src1, imm:$src2),
+          (ADD32ri R32:$src1, imm:$src2)>;
+def : Pat<(X86addflag R32:$src1, i32immSExt8:$src2),
+          (ADD32ri8 R32:$src1, i32immSExt8:$src2)>;
+
+def : Pat<(X86subflag R32:$src1, R32:$src2),
+          (SUB32rr R32:$src1, R32:$src2)>;
+def : Pat<(X86subflag R32:$src1, (load addr:$src2)),
+          (SUB32rm R32:$src1, addr:$src2)>;
+def : Pat<(X86subflag R32:$src1, imm:$src2),
+          (SUB32ri R32:$src1, imm:$src2)>;
+def : Pat<(X86subflag R32:$src1, i32immSExt8:$src2),
+          (SUB32ri8 R32:$src1, i32immSExt8:$src2)>;
+
 // Suprisingly enough, these are not two address instructions!
 def IMUL16rri  : Ii16<0x69, MRMSrcReg,                      // R16 = R16*I16
                       (ops R16:$dst, R16:$src1, i16imm:$src2),
@@ -2471,13 +2563,12 @@
 }
 
 // Random Pseudo Instructions.
-let hasInFlag = 1 in
-  def FpGETRESULT : FpI<(ops RFP:$dst), SpecialFP, []>;   // FPR = ST(0)
+def FpGETRESULT : FpI<(ops RFP:$dst), SpecialFP, []>;   // FPR = ST(0)
 
 // Do not inline into instruction def. since it isn't predicated on FPStack.
 def : Pat<(X86fpget), (FpGETRESULT)>;
 
-let noResults = 1, hasOutFlag = 1 in 
+let noResults = 1 in 
   def FpSETRESULT : FpI<(ops RFP:$src), SpecialFP,
                         []>, Imp<[], [ST0]>;              // ST(0) = FPR
 
@@ -2754,8 +2845,8 @@
 // Miscellaneous Instructions
 //===----------------------------------------------------------------------===//
 
-def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", []>, TB, Imp<[],[EAX,EDX]>;
-
+def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>,
+            TB, Imp<[],[EAX,EDX]>;
 
 //===----------------------------------------------------------------------===//
 // Some peepholes


Index: llvm/lib/Target/X86/X86RegisterInfo.cpp
diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.116 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.117
--- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.116	Thu Jan  5 18:43:03 2006
+++ llvm/lib/Target/X86/X86RegisterInfo.cpp	Mon Jan  9 12:33:28 2006
@@ -568,8 +568,6 @@
   switch (MBBI->getOpcode()) {
   case X86::RET:
   case X86::RETI:
-  case X86::RETVOID:   // FIXME: See X86InstrInfo.td
-  case X86::RETIVOID:  // FIXME: See X86InstrInfo.td
   case X86::TAILJMPd:
   case X86::TAILJMPr:
   case X86::TAILJMPm: break;  // These are ok






More information about the llvm-commits mailing list