From ef6ffb17c71232af5962f9926b31508eb942cddc Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 31 Jan 2006 03:14:29 +0000 Subject: [PATCH] Added custom lowering of fabs git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25831 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 13 +++++++++-- lib/Target/X86/X86ISelLowering.h | 4 ++++ lib/Target/X86/X86InstrInfo.td | 36 ++++++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 5064b21ae6a..bf032a7b6f4 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -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"; diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 81ce0911d56..44ae3dd9039 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -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 diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 5c620627b2a..4e8bd71aafb 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -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),