[llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp ARMInstrInfo.td

Rafael Espindola rafael.espindola at gmail.com
Fri Oct 13 06:15:14 PDT 2006



Changes in directory llvm/lib/Target/ARM:

ARMISelDAGToDAG.cpp updated: 1.65 -> 1.66
ARMInstrInfo.td updated: 1.45 -> 1.46
---
Log message:

implement unordered floating point compares


---
Diffs of the changes:  (+78 -28)

 ARMISelDAGToDAG.cpp |   95 +++++++++++++++++++++++++++++++++++++---------------
 ARMInstrInfo.td     |   11 +++++-
 2 files changed, 78 insertions(+), 28 deletions(-)


Index: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
diff -u llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.65 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.66
--- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.65	Tue Oct 10 15:38:57 2006
+++ llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp	Fri Oct 13 08:14:59 2006
@@ -92,6 +92,7 @@
       RET_FLAG,
 
       CMP,
+      CMPE,
 
       SELECT,
 
@@ -118,30 +119,56 @@
   }
 }
 
-/// DAGCCToARMCC - Convert a DAG integer condition code to an ARM CC
-//Note: ARM doesn't have condition codes corresponding to the ordered
-//condition codes of LLVM. We use exception raising instructions so
-//that we can be sure that V == 0 and test only the rest of the expression.
-static ARMCC::CondCodes DAGCCToARMCC(ISD::CondCode CC) {
+/// DAGFPCCToARMCC - Convert a DAG fp condition code to an ARM CC
+static ARMCC::CondCodes DAGFPCCToARMCC(ISD::CondCode CC) {
   switch (CC) {
   default:
-    std::cerr << "CC = " << CC << "\n";
-    assert(0 && "Unknown condition code!");
-  case ISD::SETUGT: return ARMCC::HI;
-  case ISD::SETULE: return ARMCC::LS;
-  case ISD::SETLE:
-  case ISD::SETOLE: return ARMCC::LE;
-  case ISD::SETLT:
-  case ISD::SETOLT: return ARMCC::LT;
-  case ISD::SETGT:
-  case ISD::SETOGT: return ARMCC::GT;
-  case ISD::SETNE:  return ARMCC::NE;
-  case ISD::SETEQ:
+    assert(0 && "Unknown fp condition code!");
+// For the following conditions we use a comparison that throws exceptions,
+// so we may assume that V=0
   case ISD::SETOEQ: return ARMCC::EQ;
-  case ISD::SETGE:
+  case ISD::SETOGT: return ARMCC::GT;
   case ISD::SETOGE: return ARMCC::GE;
-  case ISD::SETUGE: return ARMCC::CS;
+  case ISD::SETOLT: return ARMCC::LT;
+  case ISD::SETOLE: return ARMCC::LE;
+  case ISD::SETONE: return ARMCC::NE;
+// For the following conditions the result is undefined in case of a nan,
+// so we may assume that V=0
+  case ISD::SETEQ:  return ARMCC::EQ;
+  case ISD::SETGT:  return ARMCC::GT;
+  case ISD::SETGE:  return ARMCC::GE;
+  case ISD::SETLT:  return ARMCC::LT;
+  case ISD::SETLE:  return ARMCC::LE;
+  case ISD::SETNE:  return ARMCC::NE;
+// For the following we may not assume anything
+//    SETO      =  N | Z | !C | !V              = ???
+//    SETUO     = (!N & !Z & C & V)             = ???
+//    SETUEQ    = (!N & !Z & C & V) | Z         = ???
+//    SETUGT    = (!N & !Z & C & V) | (!Z & !N) = ???
+//    SETUGE    = (!N & !Z & C & V) | !N        = !N  = PL
+  case ISD::SETUGE: return ARMCC::PL;
+//    SETULT    = (!N & !Z & C & V) | N         = ???
+//    SETULE    = (!N & !Z & C & V) | Z | N     = ???
+//    SETUNE    = (!N & !Z & C & V) | !Z        = !Z  = NE
+  case ISD::SETUNE: return ARMCC::NE;
+  }
+}
+
+/// DAGIntCCToARMCC - Convert a DAG integer condition code to an ARM CC
+static ARMCC::CondCodes DAGIntCCToARMCC(ISD::CondCode CC) {
+  switch (CC) {
+  default:
+    assert(0 && "Unknown integer condition code!");
+  case ISD::SETEQ:  return ARMCC::EQ;
+  case ISD::SETNE:  return ARMCC::NE;
+  case ISD::SETLT:  return ARMCC::LT;
+  case ISD::SETLE:  return ARMCC::LE;
+  case ISD::SETGT:  return ARMCC::GT;
+  case ISD::SETGE:  return ARMCC::GE;
   case ISD::SETULT: return ARMCC::CC;
+  case ISD::SETULE: return ARMCC::LS;
+  case ISD::SETUGT: return ARMCC::HI;
+  case ISD::SETUGE: return ARMCC::CS;
   }
 }
 
@@ -152,6 +179,7 @@
   case ARMISD::RET_FLAG:      return "ARMISD::RET_FLAG";
   case ARMISD::SELECT:        return "ARMISD::SELECT";
   case ARMISD::CMP:           return "ARMISD::CMP";
+  case ARMISD::CMPE:          return "ARMISD::CMPE";
   case ARMISD::BR:            return "ARMISD::BR";
   case ARMISD::FSITOS:        return "ARMISD::FSITOS";
   case ARMISD::FTOSIS:        return "ARMISD::FTOSIS";
@@ -550,18 +578,31 @@
                         SelectionDAG &DAG) {
   MVT::ValueType vt = LHS.getValueType();
   assert(vt == MVT::i32 || vt == MVT::f32 || vt == MVT::f64);
-  //Note: unordered floating point compares should use a non throwing
-  //compare.
-  bool isUnorderedFloat = (vt == MVT::f32 || vt == MVT::f64) &&
-    (CC >= ISD::SETUO && CC <= ISD::SETUNE);
-  assert(!isUnorderedFloat && "Unordered float compares are not supported");
 
-  SDOperand Cmp = DAG.getNode(ARMISD::CMP, MVT::Flag, LHS, RHS);
+  bool isOrderedFloat = (vt == MVT::f32 || vt == MVT::f64) &&
+    (CC >= ISD::SETOEQ && CC <= ISD::SETONE);
+
+  SDOperand Cmp;
+  if (isOrderedFloat) {
+    Cmp = DAG.getNode(ARMISD::CMPE, MVT::Flag, LHS, RHS);
+  } else {
+    Cmp = DAG.getNode(ARMISD::CMP,  MVT::Flag, LHS, RHS);
+  }
+
   if (vt != MVT::i32)
     Cmp = DAG.getNode(ARMISD::FMSTAT, MVT::Flag, Cmp);
   return Cmp;
 }
 
+static SDOperand GetARMCC(ISD::CondCode CC, MVT::ValueType vt,
+                          SelectionDAG &DAG) {
+  assert(vt == MVT::i32 || vt == MVT::f32 || vt == MVT::f64);
+  if (vt == MVT::i32)
+    return DAG.getConstant(DAGIntCCToARMCC(CC), MVT::i32);
+  else
+    return DAG.getConstant(DAGFPCCToARMCC(CC), MVT::i32);
+}
+
 static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) {
   SDOperand LHS = Op.getOperand(0);
   SDOperand RHS = Op.getOperand(1);
@@ -569,7 +610,7 @@
   SDOperand TrueVal = Op.getOperand(2);
   SDOperand FalseVal = Op.getOperand(3);
   SDOperand      Cmp = GetCMP(CC, LHS, RHS, DAG);
-  SDOperand    ARMCC = DAG.getConstant(DAGCCToARMCC(CC), MVT::i32);
+  SDOperand    ARMCC = GetARMCC(CC, LHS.getValueType(), DAG);
   return DAG.getNode(ARMISD::SELECT, MVT::i32, TrueVal, FalseVal, ARMCC, Cmp);
 }
 
@@ -580,7 +621,7 @@
   SDOperand    RHS = Op.getOperand(3);
   SDOperand   Dest = Op.getOperand(4);
   SDOperand    Cmp = GetCMP(CC, LHS, RHS, DAG);
-  SDOperand  ARMCC = DAG.getConstant(DAGCCToARMCC(CC), MVT::i32);
+  SDOperand  ARMCC = GetARMCC(CC, LHS.getValueType(), DAG);
   return DAG.getNode(ARMISD::BR, MVT::Other, Chain, Dest, ARMCC, Cmp);
 }
 


Index: llvm/lib/Target/ARM/ARMInstrInfo.td
diff -u llvm/lib/Target/ARM/ARMInstrInfo.td:1.45 llvm/lib/Target/ARM/ARMInstrInfo.td:1.46
--- llvm/lib/Target/ARM/ARMInstrInfo.td:1.45	Thu Oct 12 13:00:26 2006
+++ llvm/lib/Target/ARM/ARMInstrInfo.td	Fri Oct 13 08:14:59 2006
@@ -76,6 +76,7 @@
 
 def SDTVoidBinOp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
 def armcmp       : SDNode<"ARMISD::CMP",  SDTVoidBinOp, [SDNPOutFlag]>;
+def armcmpe      : SDNode<"ARMISD::CMPE", SDTVoidBinOp, [SDNPOutFlag]>;
 
 def armfsitos      : SDNode<"ARMISD::FSITOS", SDTUnaryOp>;
 def armftosis      : SDNode<"ARMISD::FTOSIS", SDTUnaryOp>;
@@ -179,12 +180,20 @@
 		       [(armcmp IntRegs:$a, addr_mode1:$b)]>;
 
 // Floating Point Compare
+def fcmps   : InstARM<(ops FPRegs:$a, FPRegs:$b),
+	               "fcmps $a, $b",
+		       [(armcmp FPRegs:$a, FPRegs:$b)]>;
+
 def fcmpes  : InstARM<(ops FPRegs:$a, FPRegs:$b),
 	               "fcmpes $a, $b",
-		       [(armcmp FPRegs:$a, FPRegs:$b)]>;
+		       [(armcmpe FPRegs:$a, FPRegs:$b)]>;
 
 def fcmped  : InstARM<(ops DFPRegs:$a, DFPRegs:$b),
 	               "fcmped $a, $b",
+		       [(armcmpe DFPRegs:$a, DFPRegs:$b)]>;
+
+def fcmpd   : InstARM<(ops DFPRegs:$a, DFPRegs:$b),
+	               "fcmpd $a, $b",
 		       [(armcmp DFPRegs:$a, DFPRegs:$b)]>;
 
 // Floating Point Conversion






More information about the llvm-commits mailing list