* Added support for X86 RET with an additional operand to specify number of
authorEvan Cheng <evan.cheng@apple.com>
Wed, 21 Dec 2005 20:21:51 +0000 (20:21 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 21 Dec 2005 20:21:51 +0000 (20:21 +0000)
bytes to pop off stack.
* Added support for X86 SETCC.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24917 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrInfo.td

index 581b969957e15aeb231a967bf4f786f90feb704f..d76a89df8fe9a1305e3a83cfecd6a059f4692275 100644 (file)
@@ -1621,6 +1621,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
                            Node->getOperand(2));
       break;
     }
+    case TargetLowering::Custom: {
+      SDOperand Tmp =
+        TLI.LowerOperation(DAG.getNode(ISD::SETCC, Node->getValueType(0),
+                                       Tmp1, Tmp2, Node->getOperand(2)), DAG);
+      if (Tmp.Val) {
+        Result = LegalizeOp(Tmp);
+        break;
+      }
+      // FALLTHROUGH if the target thinks it is legal.
+    }
     case TargetLowering::Legal:
       if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1))
         Result = DAG.getNode(ISD::SETCC, Node->getValueType(0), Tmp1, Tmp2,
index ee6e320fc51f45c8bcbb25f497c551ca10596ddb..5e4fb412f1947fd4fbbe46d4ee6750de639c3c9b 100644 (file)
@@ -119,6 +119,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   if (X86DAGIsel) {
     setOperationAction(ISD::SELECT         , MVT::i16  , Custom);
     setOperationAction(ISD::SELECT         , MVT::i32  , Custom);
+    setOperationAction(ISD::SETCC          , MVT::i8   , Custom);
+    setOperationAction(ISD::SETCC          , MVT::i16  , Custom);
+    setOperationAction(ISD::SETCC          , MVT::i32  , Custom);
   }
 
   // We don't have line number support yet.
@@ -256,7 +259,10 @@ SDOperand X86TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
       }
       break;
   }
-  return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
+
+  return DAG.getNode(X86ISD::RET_FLAG, MVT::Other,
+                     Copy, DAG.getConstant(getBytesToPopOnReturn(), MVT::i16),
+                     Copy.getValue(1));
 }
 
 //===----------------------------------------------------------------------===//
@@ -999,10 +1005,20 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     Tys.push_back(MVT::Other);
     return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
   }
+  case ISD::SETCC: {
+    assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
+    SDOperand CC   = Op.getOperand(2);
+    SDOperand Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
+                                 Op.getOperand(0), Op.getOperand(1));
+    return DAG.getNode(X86ISD::SETCC, MVT::i8, CC, Cond);
+  }
   case ISD::SELECT: {
     SDOperand Cond  = Op.getOperand(0);
     SDOperand CC;
-    if (Cond.getOpcode() == ISD::SETCC) {
+    if (Cond.getOpcode() == X86ISD::SETCC) {
+      CC = Cond.getOperand(0);
+      Cond = Cond.getOperand(1);
+    } else if (Cond.getOpcode() == ISD::SETCC) {
       CC = Cond.getOperand(2);
       Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
                          Cond.getOperand(0), Cond.getOperand(1));
@@ -1014,12 +1030,14 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
                        Op.getOperand(1), Op.getOperand(2), CC, Cond);
   }
   case ISD::BRCOND: {
-    SDOperand Chain = Op.getOperand(0);
     SDOperand Cond  = Op.getOperand(1);
     SDOperand Dest  = Op.getOperand(2);
     SDOperand CC;
     // TODO: handle Cond == OR / AND / XOR
-    if (Cond.getOpcode() == ISD::SETCC) {
+    if (Cond.getOpcode() == X86ISD::SETCC) {
+      CC = Cond.getOperand(0);
+      Cond = Cond.getOperand(1);
+    } else if (Cond.getOpcode() == ISD::SETCC) {
       CC = Cond.getOperand(2);
       Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
                          Cond.getOperand(0), Cond.getOperand(1));
@@ -1061,6 +1079,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   case X86ISD::RDTSC_DAG:          return "X86ISD::RDTSC_DAG";
   case X86ISD::CMP:                return "X86ISD::CMP";
   case X86ISD::TEST:               return "X86ISD::TEST";
+  case X86ISD::SETCC:              return "X86ISD::SETCC";
   case X86ISD::CMOV:               return "X86ISD::CMOV";
   case X86ISD::BRCOND:             return "X86ISD::BRCOND";
   case X86ISD::RET_FLAG:           return "X86ISD::RET_FLAG";
index a1c09136dcaf6ac466a76201943d4a426e8ecc75..c15e009c90ab9991cab902d57951352f8b21b53c 100644 (file)
@@ -81,13 +81,24 @@ namespace llvm {
       /// X86 compare and logical compare instructions.
       CMP, TEST,
 
-      /// X86 conditional moves.
+      /// X86 SetCC. Operand 1 is condition code, and operand 2 is the flag
+      /// operand produced by a CMP instruction.
+      SETCC,
+
+      /// 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.
       CMOV,
 
-      /// X86 conditional branches.
+      /// X86 conditional branches. Operand 1 is the chain operand, operand 2
+      /// is the block to branch if condition is true, operand 3 is the
+      /// condition code, and operand 4 is the flag operand produced by a CMP
+      /// or TEST instruction.
       BRCOND,
 
-      // Return with a flag operand.
+      /// 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 fc4e0b998710be6b12aadbea75e3a66f76e4c0d2..9c7fcb0237f15e8cd801d4330ca41b5a6afe4c51 100644 (file)
@@ -28,25 +28,31 @@ def SDTX86BrCond  : SDTypeProfile<0, 3,
                                   [SDTCisVT<0, OtherVT>,
                                    SDTCisVT<1, OtherVT>, SDTCisVT<2, FlagVT>]>;
 
-def SDTX86RetFlag : SDTypeProfile<0, 1, [SDTCisVT<0, FlagVT>]>;
+def SDTX86SetCC   : SDTypeProfile<1, 2,
+                                  [SDTCisVT<0, i8>, SDTCisVT<1, OtherVT>,
+                                   SDTCisVT<2, FlagVT>]>;
+
+def SDTX86RetFlag : SDTypeProfile<0, 2, [SDTCisVT<0, i16>,
+                                         SDTCisVT<1, FlagVT>]>;
 
 def SDTX86Fld     : SDTypeProfile<1, 2, [SDTCisFP<0>,
                                          SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
 
 def SDTX86FpSet   : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
 
-def X86cmp    : SDNode<"X86ISD::CMP" ,     SDTX86CmpTest, []>;
-def X86test   : SDNode<"X86ISD::TEST",     SDTX86CmpTest, []>;
+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,     []>;
+def X86Brcond  : SDNode<"X86ISD::BRCOND",   SDTX86BrCond,   [SDNPHasChain]>;
+def X86SetCC   : SDNode<"X86ISD::SETCC",    SDTX86SetCC,    []>;
 
-def X86retflag: SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>;
+def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>;
 
-def X86fld    : SDNode<"X86ISD::FLD",      SDTX86Fld,     [SDNPHasChain]>;
+def X86fld     : SDNode<"X86ISD::FLD",      SDTX86Fld,      [SDNPHasChain]>;
 
-def X86fpset  : SDNode<"X86ISD::FP_SET_RESULT",
-                                           SDTX86FpSet,   [SDNPHasChain]>;
+def X86fpset   : SDNode<"X86ISD::FP_SET_RESULT",
+                                            SDTX86FpSet,    [SDNPHasChain]>;
 
 //===----------------------------------------------------------------------===//
 // X86 Operand Definitions.
@@ -283,12 +289,13 @@ let isTerminator = 1 in
 //
 
 // Return instructions.
-let isTerminator = 1, isReturn = 1, isBarrier = 1 in
-  def RET : I<0xC3, RawFrm, (ops), "ret", [(ret)]>;
-let isTerminator = 1, isReturn = 1, isBarrier = 1 in
+let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in
+  def RET : I<0xC3, RawFrm, (ops), "ret", []>;
+let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in
   def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>;
 
-def : Pat<(X86retflag FLAG), (RET)>;
+def : Pat<(X86retflag 0, FLAG),        (RET)>;
+def : Pat<(X86retflag imm:$amt, FLAG), (RETI imm:$amt)>;
 
 // All branches are RawFrm, Void, Branch, and Terminators
 let isBranch = 1, isTerminator = 1 in
@@ -1800,42 +1807,87 @@ def TEST32mi : Ii32<0xF7, MRM0m,                     // flags = [mem32] & imm32
 def SAHF     : I<0x9E, RawFrm, (ops), "sahf", []>, Imp<[AH],[]>;  // flags = AH
 def LAHF     : I<0x9F, RawFrm, (ops), "lahf", []>, Imp<[],[AH]>;  // AH = flags
 
-def SETBr    : I<0x92, MRM0r,
-                 (ops R8   :$dst),
-                 "setb $dst", []>, TB;    // R8 = <  unsign
-def SETBm    : I<0x92, MRM0m,
-                 (ops i8mem:$dst),
-                 "setb $dst", []>, TB;    // [mem8] = <  unsign
-def SETAEr   : I<0x93, MRM0r, 
-                 (ops R8   :$dst),
-                 "setae $dst", []>, TB;   // R8 = >= unsign
-def SETAEm   : I<0x93, MRM0m, 
-                 (ops i8mem:$dst),
-                 "setae $dst", []>, TB;   // [mem8] = >= unsign
 def SETEr    : I<0x94, MRM0r, 
                  (ops R8   :$dst),
-                 "sete $dst", []>, TB;    // R8 = ==
+                 "sete $dst", [(set R8:$dst, (X86SetCC SETEQ, STATUS))]>,
+               TB;                        // R8 = ==
 def SETEm    : I<0x94, MRM0m, 
                  (ops i8mem:$dst),
-                 "sete $dst", []>, TB;    // [mem8] = ==
+                 "sete $dst", [(store (X86SetCC SETEQ, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = ==
 def SETNEr   : I<0x95, MRM0r, 
                  (ops R8   :$dst),
-                 "setne $dst", []>, TB;   // R8 = !=
+                 "setne $dst", [(set R8:$dst, (X86SetCC SETNE, STATUS))]>,
+               TB;                        // R8 = !=
 def SETNEm   : I<0x95, MRM0m, 
                  (ops i8mem:$dst),
-                 "setne $dst", []>, TB;   // [mem8] = !=
+                 "setne $dst", [(store (X86SetCC SETNE, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = !=
+def SETLr    : I<0x9C, MRM0r, 
+                 (ops R8   :$dst),
+                 "setl $dst", [(set R8:$dst, (X86SetCC SETLT, STATUS))]>,
+               TB;                        // R8 = <  signed
+def SETLm    : I<0x9C, MRM0m, 
+                 (ops i8mem:$dst),
+                 "setl $dst", [(store (X86SetCC SETLT, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = <  signed
+def SETGEr   : I<0x9D, MRM0r, 
+                 (ops R8   :$dst),
+                 "setge $dst", [(set R8:$dst, (X86SetCC SETGE, STATUS))]>,
+               TB;                        // R8 = >= signed
+def SETGEm   : I<0x9D, MRM0m, 
+                 (ops i8mem:$dst),
+                 "setge $dst", [(store (X86SetCC SETGE, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = >= signed
+def SETLEr   : I<0x9E, MRM0r, 
+                 (ops R8   :$dst),
+                 "setle $dst", [(set R8:$dst, (X86SetCC SETLE, STATUS))]>,
+               TB;                        // R8 = <= signed
+def SETLEm   : I<0x9E, MRM0m, 
+                 (ops i8mem:$dst),
+                 "setle $dst", [(store (X86SetCC SETLE, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = <= signed
+def SETGr    : I<0x9F, MRM0r, 
+                 (ops R8   :$dst),
+                 "setg $dst", [(set R8:$dst, (X86SetCC SETGT, STATUS))]>,
+               TB;                        // R8 = >  signed
+def SETGm    : I<0x9F, MRM0m, 
+                 (ops i8mem:$dst),
+                 "setg $dst", [(store (X86SetCC SETGT, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = >  signed
+
+def SETBr    : I<0x92, MRM0r,
+                 (ops R8   :$dst),
+                 "setb $dst", [(set R8:$dst, (X86SetCC SETULT, STATUS))]>,
+               TB;                        // R8 = <  unsign
+def SETBm    : I<0x92, MRM0m,
+                 (ops i8mem:$dst),
+                 "setb $dst", [(store (X86SetCC SETULT, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = <  unsign
+def SETAEr   : I<0x93, MRM0r, 
+                 (ops R8   :$dst),
+                 "setae $dst", [(set R8:$dst, (X86SetCC SETUGE, STATUS))]>,
+               TB;                        // R8 = >= unsign
+def SETAEm   : I<0x93, MRM0m, 
+                 (ops i8mem:$dst),
+                 "setae $dst", [(store (X86SetCC SETUGE, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = >= unsign
 def SETBEr   : I<0x96, MRM0r, 
                  (ops R8   :$dst),
-                 "setbe $dst", []>, TB;   // R8 = <= unsign
+                 "setbe $dst", [(set R8:$dst, (X86SetCC SETULE, STATUS))]>,
+               TB;                        // R8 = <= unsign
 def SETBEm   : I<0x96, MRM0m, 
                  (ops i8mem:$dst),
-                 "setbe $dst", []>, TB;   // [mem8] = <= unsign
+                 "setbe $dst", [(store (X86SetCC SETULE, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = <= unsign
 def SETAr    : I<0x97, MRM0r, 
                  (ops R8   :$dst),
-                 "seta $dst", []>, TB;    // R8 = >  signed
+                 "seta $dst", [(set R8:$dst, (X86SetCC SETUGT, STATUS))]>,
+               TB;                        // R8 = >  signed
 def SETAm    : I<0x97, MRM0m, 
                  (ops i8mem:$dst),
-                 "seta $dst", []>, TB;    // [mem8] = >  signed
+                 "seta $dst", [(store (X86SetCC SETUGT, STATUS), addr:$dst)]>,
+               TB;                        // [mem8] = >  signed
 def SETSr    : I<0x98, MRM0r, 
                  (ops R8   :$dst),
                  "sets $dst", []>, TB;    // R8 = <sign bit>
@@ -1860,30 +1912,6 @@ def SETNPr   : I<0x9B, MRM0r,
 def SETNPm   : I<0x9B, MRM0m, 
                  (ops i8mem:$dst),
                  "setnp $dst", []>, TB;   // [mem8] = not parity
-def SETLr    : I<0x9C, MRM0r, 
-                 (ops R8   :$dst),
-                 "setl $dst", []>, TB;    // R8 = <  signed
-def SETLm    : I<0x9C, MRM0m, 
-                 (ops i8mem:$dst),
-                 "setl $dst", []>, TB;    // [mem8] = <  signed
-def SETGEr   : I<0x9D, MRM0r, 
-                 (ops R8   :$dst),
-                 "setge $dst", []>, TB;   // R8 = >= signed
-def SETGEm   : I<0x9D, MRM0m, 
-                 (ops i8mem:$dst),
-                 "setge $dst", []>, TB;   // [mem8] = >= signed
-def SETLEr   : I<0x9E, MRM0r, 
-                 (ops R8   :$dst),
-                 "setle $dst", []>, TB;   // R8 = <= signed
-def SETLEm   : I<0x9E, MRM0m, 
-                 (ops i8mem:$dst),
-                 "setle $dst", []>, TB;   // [mem8] = <= signed
-def SETGr    : I<0x9F, MRM0r, 
-                 (ops R8   :$dst),
-                 "setg $dst", []>, TB;    // R8 = <  signed
-def SETGm    : I<0x9F, MRM0m, 
-                 (ops i8mem:$dst),
-                 "setg $dst", []>, TB;    // [mem8] = <  signed
 
 // Integer comparisons
 def CMP8rr  : I<0x38, MRMDestReg,