X86 conditional branch support.
authorEvan Cheng <evan.cheng@apple.com>
Mon, 19 Dec 2005 23:12:38 +0000 (23:12 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Mon, 19 Dec 2005 23:12:38 +0000 (23:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24870 91177308-0d34-0410-b5e6-96231b3b80d8

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

index d575ee617f387187a72ea9e06b8aadbe969f8cfe..bdc49513eba01cb19c3836cf998b8f400e424baa 100644 (file)
@@ -883,6 +883,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       }
       Result = LegalizeOp(Result);  // Relegalize new nodes.
       break;
+    case TargetLowering::Custom: {
+      SDOperand Tmp =
+        TLI.LowerOperation(DAG.getNode(ISD::BRCOND, 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:
       // Basic block destination (Op#2) is always legal.
       if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1))
index 5e7554d9dd53b3282ef47670708076ea220a03a3..5ee107bfdb5aa427673456e611238ded6a1d178d 100644 (file)
@@ -131,10 +131,6 @@ def SDTBr : SDTypeProfile<0, 1, [ // br
   SDTCisVT<0, OtherVT>
 ]>;
 
-def SDTBrCond : SDTypeProfile<0, 2, [ // brcond
-  SDTCisInt<0>, SDTCisVT<1, OtherVT>
-]>;
-
 def SDTRet : SDTypeProfile<0, 0, []>; // ret
 
 def SDTWritePort : SDTypeProfile<0, 2, [ // writeport
@@ -256,7 +252,6 @@ def select     : SDNode<"ISD::SELECT"     , SDTSelect>;
 def selectcc   : SDNode<"ISD::SELECT_CC"  , SDTSelectCC>;
 
 def br         : SDNode<"ISD::BR"         , SDTBr,     [SDNPHasChain]>;
-def brcond     : SDNode<"ISD::BRCOND"     , SDTBrCond, [SDNPHasChain]>;
 def ret        : SDNode<"ISD::RET"        , SDTRet,    [SDNPHasChain]>;
 
 def writeport  : SDNode<"ISD::WRITEPORT"  , SDTWritePort, [SDNPHasChain]>;
index dac14daf49a3bd7735ecedc6d1750b6b48e8acd5..776ff6c8a91c9d6ccbb19753d22c0f79561561dd 100644 (file)
@@ -31,7 +31,6 @@ static cl::opt<bool> EnableFastCC("enable-x86-fastcc", cl::Hidden,
 
 X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   : TargetLowering(TM) {
-
   // Set up the TargetLowering object.
 
   // X86 is weird, it always uses i8 for shift amounts and setcc results.
@@ -81,6 +80,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::FP_TO_SINT       , MVT::i8   , Promote);
   setOperationAction(ISD::FP_TO_SINT       , MVT::i16  , Promote);
 
+  if (X86DAGIsel) {
+    setOperationAction(ISD::BRCOND         , MVT::Other, Custom);
+  }
   setOperationAction(ISD::BRCONDTWOWAY     , MVT::Other, Expand);
   setOperationAction(ISD::BRTWOWAY_CC      , MVT::Other, Expand);
   setOperationAction(ISD::MEMMOVE          , MVT::Other, Expand);
@@ -949,5 +951,22 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     return DAG.getNode(X86ISD::CMOV, Op.getValueType(),
                        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) {
+      CC = Cond.getOperand(2);
+      Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
+                         Cond.getOperand(0), Cond.getOperand(1));
+    } else {
+      CC = DAG.getCondCode(ISD::SETNE);
+      Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Cond, Cond);
+    }
+    return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
+                       Op.getOperand(0), Op.getOperand(2), CC, Cond);
+  }
   }
 }
index 26cc7d5ec6a4598c7c0914f8511939fdb78e364a..918b23420db8103f711d7c877a6255087467830c 100644 (file)
@@ -72,6 +72,9 @@ namespace llvm {
 
       /// X86 conditional moves.
       CMOV,
+
+      /// X86 conditional branches.
+      BRCOND,
     };
   }
 
index f5b109a97257a74cfedf580856931f6b3b76e265..07ff869b203a0720c3f0f830147fd65517c3377a 100644 (file)
@@ -24,10 +24,15 @@ def SDTX86Cmov    : SDTypeProfile<1, 4,
                                   [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
                                    SDTCisVT<3, OtherVT>, SDTCisVT<4, FlagVT>]>;
 
-def X86cmp  : SDNode<"X86ISD::CMP" , SDTX86CmpTest, []>;
-def X86test : SDNode<"X86ISD::TEST", SDTX86CmpTest, []>;
+def SDTX86BrCond  : SDTypeProfile<0, 3,
+                                  [SDTCisVT<0, OtherVT>,
+                                   SDTCisVT<1, OtherVT>, SDTCisVT<2, FlagVT>]>;
 
-def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov,    []>;
+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]>;
 
 //===----------------------------------------------------------------------===//
 // X86 Operand Definitions.
@@ -268,21 +273,33 @@ let isBranch = 1, isTerminator = 1 in
 
 let isBarrier = 1 in
   def JMP : IBr<0xE9, (ops brtarget:$dst), "jmp $dst", [(br bb:$dst)]>;
+
+def JE  : IBr<0x84, (ops brtarget:$dst), "je $dst",
+              [(X86Brcond bb:$dst, SETEQ, STATUS)]>, Imp<[STATUS],[]>, TB;
+def JNE : IBr<0x85, (ops brtarget:$dst), "jne $dst",
+              [(X86Brcond bb:$dst, SETNE, STATUS)]>, Imp<[STATUS],[]>, TB;
+def JL  : IBr<0x8C, (ops brtarget:$dst), "jl $dst",
+              [(X86Brcond bb:$dst, SETLT, STATUS)]>, Imp<[STATUS],[]>, TB;
+def JLE : IBr<0x8E, (ops brtarget:$dst), "jle $dst",
+              [(X86Brcond bb:$dst, SETLE, STATUS)]>, Imp<[STATUS],[]>, TB;
+def JG  : IBr<0x8F, (ops brtarget:$dst), "jg $dst",
+              [(X86Brcond bb:$dst, SETGT, STATUS)]>, Imp<[STATUS],[]>, TB;
+def JGE : IBr<0x8D, (ops brtarget:$dst), "jge $dst",
+              [(X86Brcond bb:$dst, SETGE, STATUS)]>, Imp<[STATUS],[]>, TB;
+
 def JB  : IBr<0x82, (ops brtarget:$dst), "jb $dst",
-              []>, TB;
-def JAE : IBr<0x83, (ops brtarget:$dst), "jae $dst", []>, TB;
-def JE  : IBr<0x84, (ops brtarget:$dst), "je $dst", []>, TB;
-def JNE : IBr<0x85, (ops brtarget:$dst), "jne $dst", []>, TB;
-def JBE : IBr<0x86, (ops brtarget:$dst), "jbe $dst", []>, TB;
-def JA  : IBr<0x87, (ops brtarget:$dst), "ja $dst", []>, TB;
+              [(X86Brcond bb:$dst, SETULT, STATUS)]>, Imp<[STATUS],[]>, TB;
+def JBE : IBr<0x86, (ops brtarget:$dst), "jbe $dst",
+              [(X86Brcond bb:$dst, SETULE, STATUS)]>, Imp<[STATUS],[]>, TB;
+def JA  : IBr<0x87, (ops brtarget:$dst), "ja $dst",
+              [(X86Brcond bb:$dst, SETUGT, STATUS)]>, Imp<[STATUS],[]>, TB;
+def JAE : IBr<0x83, (ops brtarget:$dst), "jae $dst",
+              [(X86Brcond bb:$dst, SETUGE, STATUS)]>, Imp<[STATUS],[]>, TB;
+
 def JS  : IBr<0x88, (ops brtarget:$dst), "js $dst", []>, TB;
 def JNS : IBr<0x89, (ops brtarget:$dst), "jns $dst", []>, TB;
 def JP  : IBr<0x8A, (ops brtarget:$dst), "jp $dst", []>, TB;
 def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst", []>, TB;
-def JL  : IBr<0x8C, (ops brtarget:$dst), "jl $dst", []>, TB;
-def JGE : IBr<0x8D, (ops brtarget:$dst), "jge $dst", []>, TB;
-def JLE : IBr<0x8E, (ops brtarget:$dst), "jle $dst", []>, TB;
-def JG  : IBr<0x8F, (ops brtarget:$dst), "jg $dst", []>, TB;
 
 //===----------------------------------------------------------------------===//
 //  Call Instructions...