Added custom lowering of fabs
authorEvan Cheng <evan.cheng@apple.com>
Tue, 31 Jan 2006 03:14:29 +0000 (03:14 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 31 Jan 2006 03:14:29 +0000 (03:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25831 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrInfo.td

index 5064b21ae6a4cbb435a5b0b3f8ded10315843614..bf032a7b6f40243188cca0e69d10f63682731e5e 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/SSARegMap.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetOptions.h"
 using namespace llvm;
 
@@ -209,12 +210,12 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     // We don't support sin/cos/sqrt/fmod
     setOperationAction(ISD::FSIN , MVT::f64, Expand);
     setOperationAction(ISD::FCOS , MVT::f64, Expand);
-    setOperationAction(ISD::FABS , MVT::f64, Expand);
+    setOperationAction(ISD::FABS , MVT::f64, Custom);
     setOperationAction(ISD::FNEG , MVT::f64, Expand);
     setOperationAction(ISD::FREM , MVT::f64, Expand);
     setOperationAction(ISD::FSIN , MVT::f32, Expand);
     setOperationAction(ISD::FCOS , MVT::f32, Expand);
-    setOperationAction(ISD::FABS , MVT::f32, Expand);
+    setOperationAction(ISD::FABS , MVT::f32, Custom);
     setOperationAction(ISD::FNEG , MVT::f32, Expand);
     setOperationAction(ISD::FREM , MVT::f32, Expand);
 
@@ -1562,6 +1563,13 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     Tys.push_back(MVT::Other);
     return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
   }
+  case ISD::FABS: {
+    MVT::ValueType VT = Op.getValueType();
+    SDOperand Mask = (VT == MVT::f64)
+      ? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), MVT::f64)
+      : DAG.getConstantFP(BitsToFloat (~(1U   << 31)), MVT::f32);
+    return DAG.getNode(X86ISD::FAND, VT, Op.getOperand(0), Mask);
+  }
   case ISD::SETCC: {
     assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
     SDOperand Cond;
@@ -1912,6 +1920,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   case X86ISD::SBB:                return "X86ISD::SBB";
   case X86ISD::SHLD:               return "X86ISD::SHLD";
   case X86ISD::SHRD:               return "X86ISD::SHRD";
+  case X86ISD::FAND:               return "X86ISD::FAND";
   case X86ISD::FILD:               return "X86ISD::FILD";
   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";
index 81ce0911d56183a930592928c74a23e999251329..44ae3dd90393d4997332dab827a18119d192f1ea 100644 (file)
@@ -41,6 +41,10 @@ namespace llvm {
       SHLD,
       SHRD,
 
+      /// FAND - Bitwise logical AND of floating point values. This corresponds
+      /// to X86::ANDPS or X86::ANDPD.
+      FAND,
+
       /// FILD - This instruction implements SINT_TO_FP with the integer source
       /// in memory and FP reg result.  This corresponds to the X86::FILD*m
       /// instructions. It has three inputs (token chain, address, and source
index 5c620627b2ae1431518d933d01643443ff8073c7..4e8bd71aafbdbc5ecfee6ffae630fb929ff64c20 100644 (file)
@@ -68,6 +68,9 @@ def X86sbb     : SDNode<"X86ISD::SBB" ,     SDTIntBinOp,
 def X86shld    : SDNode<"X86ISD::SHLD",     SDTIntShiftDOp>;
 def X86shrd    : SDNode<"X86ISD::SHRD",     SDTIntShiftDOp>;
 
+def X86fand    : SDNode<"X86ISD::FAND",     SDTFPBinOp,
+                        [SDNPCommutative, SDNPAssociative]>;
+
 def X86cmp     : SDNode<"X86ISD::CMP" ,     SDTX86CmpTest,
                         [SDNPOutFlag]>;
 def X86test    : SDNode<"X86ISD::TEST",     SDTX86CmpTest,
@@ -2549,10 +2552,12 @@ def SUBSDrm : I<0x5C, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
 // SSE Logical
 let isCommutable = 1 in {
 def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
-                "andps {$src2, $dst|$dst, $src2}", []>,
+                "andps {$src2, $dst|$dst, $src2}",
+                [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>,
               Requires<[HasSSE1]>, TB;
 def ANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
-                "andpd {$src2, $dst|$dst, $src2}", []>,
+                "andpd {$src2, $dst|$dst, $src2}",
+                [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>,
               Requires<[HasSSE2]>, TB, OpSize;
 def ORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
                 "orps {$src2, $dst|$dst, $src2}", []>,
@@ -2567,12 +2572,39 @@ def XORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
                 "xorpd {$src2, $dst|$dst, $src2}", []>,
               Requires<[HasSSE2]>, TB, OpSize;
 }
+def ANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
+                "andps {$src2, $dst|$dst, $src2}",
+                []>,
+              Requires<[HasSSE1]>, TB;
+def ANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
+                "andpd {$src2, $dst|$dst, $src2}",
+                []>,
+              Requires<[HasSSE2]>, TB, OpSize;
+def ORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
+                "orps {$src2, $dst|$dst, $src2}", []>,
+             Requires<[HasSSE1]>, TB;
+def ORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
+                "orpd {$src2, $dst|$dst, $src2}", []>,
+             Requires<[HasSSE2]>, TB, OpSize;
+def XORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
+                "xorps {$src2, $dst|$dst, $src2}", []>,
+              Requires<[HasSSE1]>, TB;
+def XORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
+                "xorpd {$src2, $dst|$dst, $src2}", []>,
+              Requires<[HasSSE2]>, TB, OpSize;
+
 def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2),
                 "andnps {$src2, $dst|$dst, $src2}", []>,
                Requires<[HasSSE1]>, TB;
+def ANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2),
+                "andnps {$src2, $dst|$dst, $src2}", []>,
+               Requires<[HasSSE1]>, TB;
 def ANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2),
                 "andnpd {$src2, $dst|$dst, $src2}", []>,
                Requires<[HasSSE2]>, TB, OpSize;
+def ANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2),
+                "andnpd {$src2, $dst|$dst, $src2}", []>,
+               Requires<[HasSSE2]>, TB, OpSize;
 
 def CMPSSrr : I<0xC2, MRMSrcReg, 
                 (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc),