mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-08 04:51:23 +00:00
FGETSIGN support for x86, using movmskps/pd. Will be enabled with a
patch to TargetLowering.cpp. rdar://problem/5660695 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132388 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cf9aa284b3
commit
4fd0dee3bf
@ -354,6 +354,7 @@ def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>;
|
||||
def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>;
|
||||
def frem : SDNode<"ISD::FREM" , SDTFPBinOp>;
|
||||
def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>;
|
||||
def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>;
|
||||
def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>;
|
||||
def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>;
|
||||
def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>;
|
||||
|
@ -574,6 +574,10 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
||||
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
|
||||
setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
|
||||
|
||||
// Lower this to FGETSIGNx86 plus an AND.
|
||||
setOperationAction(ISD::FGETSIGN, MVT::i64, Custom);
|
||||
setOperationAction(ISD::FGETSIGN, MVT::i32, Custom);
|
||||
|
||||
// We don't support sin/cos/fmod
|
||||
setOperationAction(ISD::FSIN , MVT::f64, Expand);
|
||||
setOperationAction(ISD::FCOS , MVT::f64, Expand);
|
||||
@ -7215,6 +7219,17 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
|
||||
return DAG.getNode(X86ISD::FOR, dl, VT, Val, SignBit);
|
||||
}
|
||||
|
||||
SDValue X86TargetLowering::LowerFGETSIGN(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDValue N0 = Op.getOperand(0);
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
EVT VT = Op.getValueType();
|
||||
|
||||
// Lower ISD::FGETSIGN to (AND (X86ISD::FGETSIGNx86 ...) 1).
|
||||
SDValue xFGETSIGN = DAG.getNode(X86ISD::FGETSIGNx86, dl, VT, N0,
|
||||
DAG.getConstant(1, VT));
|
||||
return DAG.getNode(ISD::AND, dl, VT, xFGETSIGN, DAG.getConstant(1, VT));
|
||||
}
|
||||
|
||||
/// Emit nodes that will be selected as "test Op0,Op0", or something
|
||||
/// equivalent.
|
||||
SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC,
|
||||
@ -9186,6 +9201,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||
case ISD::FABS: return LowerFABS(Op, DAG);
|
||||
case ISD::FNEG: return LowerFNEG(Op, DAG);
|
||||
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
|
||||
case ISD::FGETSIGN: return LowerFGETSIGN(Op, DAG);
|
||||
case ISD::SETCC: return LowerSETCC(Op, DAG);
|
||||
case ISD::VSETCC: return LowerVSETCC(Op, DAG);
|
||||
case ISD::SELECT: return LowerSELECT(Op, DAG);
|
||||
|
@ -94,6 +94,10 @@ namespace llvm {
|
||||
// one's or all zero's.
|
||||
SETCC_CARRY, // R = carry_bit ? ~0 : 0
|
||||
|
||||
/// X86 MOVMSK{pd|ps}, extracts sign bits of two or four FP values,
|
||||
/// result in an integer GPR. Needs masking for scalar result.
|
||||
FGETSIGNx86,
|
||||
|
||||
/// X86 conditional moves. Operand 0 and operand 1 are the two values
|
||||
/// to select from. Operand 2 is the condition code, and operand 3 is the
|
||||
/// flag operand produced by a CMP or TEST instruction. It also writes a
|
||||
@ -783,6 +787,7 @@ namespace llvm {
|
||||
SDValue LowerFABS(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerFGETSIGN(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerToBT(SDValue And, ISD::CondCode CC,
|
||||
DebugLoc dl, SelectionDAG &DAG) const;
|
||||
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
@ -38,6 +38,7 @@ def X86fxor : SDNode<"X86ISD::FXOR", SDTFPBinOp,
|
||||
def X86frsqrt : SDNode<"X86ISD::FRSQRT", SDTFPUnaryOp>;
|
||||
def X86frcp : SDNode<"X86ISD::FRCP", SDTFPUnaryOp>;
|
||||
def X86fsrl : SDNode<"X86ISD::FSRL", SDTX86FPShiftOp>;
|
||||
def X86fgetsign: SDNode<"X86ISD::FGETSIGNx86",SDTFPToIntOp>;
|
||||
def X86comi : SDNode<"X86ISD::COMI", SDTX86CmpTest>;
|
||||
def X86ucomi : SDNode<"X86ISD::UCOMI", SDTX86CmpTest>;
|
||||
def X86pshufb : SDNode<"X86ISD::PSHUFB",
|
||||
|
@ -1327,11 +1327,6 @@ multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
|
||||
}
|
||||
|
||||
// Mask creation
|
||||
defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
|
||||
SSEPackedSingle>, TB;
|
||||
defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
|
||||
SSEPackedDouble>, TB, OpSize;
|
||||
|
||||
defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
|
||||
"movmskps", SSEPackedSingle>, VEX;
|
||||
defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
|
||||
@ -1342,6 +1337,24 @@ defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
|
||||
defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
|
||||
"movmskpd", SSEPackedDouble>, OpSize,
|
||||
VEX;
|
||||
defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
|
||||
SSEPackedSingle>, TB;
|
||||
defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
|
||||
SSEPackedDouble>, TB, OpSize;
|
||||
|
||||
// X86fgetsign
|
||||
def MOVMSKPDrr32_alt : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins FR64:$src),
|
||||
"movmskpd\t{$src, $dst|$dst, $src}",
|
||||
[(set GR32:$dst, (X86fgetsign FR64:$src))], SSEPackedDouble>, TB, OpSize;
|
||||
def MOVMSKPDrr64_alt : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins FR64:$src),
|
||||
"movmskpd\t{$src, $dst|$dst, $src}",
|
||||
[(set GR64:$dst, (X86fgetsign FR64:$src))], SSEPackedDouble>, TB, OpSize;
|
||||
def MOVMSKPSrr32_alt : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins FR32:$src),
|
||||
"movmskps\t{$src, $dst|$dst, $src}",
|
||||
[(set GR32:$dst, (X86fgetsign FR32:$src))], SSEPackedSingle>, TB;
|
||||
def MOVMSKPSrr64_alt : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins FR32:$src),
|
||||
"movmskps\t{$src, $dst|$dst, $src}",
|
||||
[(set GR64:$dst, (X86fgetsign FR32:$src))], SSEPackedSingle>, TB;
|
||||
|
||||
// Assembler Only
|
||||
def VMOVMSKPSr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
|
||||
|
Loading…
Reference in New Issue
Block a user