mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-04 01:43:06 +00:00
Add the remaining fp_round libcalls:
FPROUND_F80_F32, FPROUND_PPCF128_F32, FPROUND_F80_F64, FPROUND_PPCF128_F64 Support for soften float fp_round operands is added, Mips needs this to round f64->f32. Also added support to soften float FABS result, Mips doesn't support double fabs results while in 'single float only' mode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54484 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
724acf1c52
commit
e36bfe678d
@ -101,6 +101,10 @@ namespace RTLIB {
|
||||
// CONVERSION
|
||||
FPEXT_F32_F64,
|
||||
FPROUND_F64_F32,
|
||||
FPROUND_F80_F32,
|
||||
FPROUND_PPCF128_F32,
|
||||
FPROUND_F80_F64,
|
||||
FPROUND_PPCF128_F64,
|
||||
FPTOSINT_F32_I32,
|
||||
FPTOSINT_F32_I64,
|
||||
FPTOSINT_F32_I128,
|
||||
|
@ -59,6 +59,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
|
||||
case ISD::ConstantFP:
|
||||
R = SoftenFloatRes_ConstantFP(cast<ConstantFPSDNode>(N));
|
||||
break;
|
||||
case ISD::FABS: R = SoftenFloatRes_FABS(N); break;
|
||||
case ISD::FADD: R = SoftenFloatRes_FADD(N); break;
|
||||
case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break;
|
||||
case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break;
|
||||
@ -96,6 +97,17 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) {
|
||||
TLI.getTypeToTransformTo(N->getValueType(0)));
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) {
|
||||
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
|
||||
unsigned Size = NVT.getSizeInBits();
|
||||
|
||||
// Mask = ~(1 << (Size-1))
|
||||
SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1),
|
||||
NVT);
|
||||
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
||||
return DAG.getNode(ISD::AND, NVT, Op, Mask);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) {
|
||||
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
|
||||
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
|
||||
@ -290,6 +302,7 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
||||
|
||||
case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break;
|
||||
case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break;
|
||||
case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break;
|
||||
case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break;
|
||||
case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(N); break;
|
||||
case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
|
||||
@ -407,6 +420,17 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) {
|
||||
GetSoftenedFloat(N->getOperand(0)));
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
|
||||
MVT SVT = N->getOperand(0).getValueType();
|
||||
MVT RVT = N->getValueType(0);
|
||||
|
||||
RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT);
|
||||
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");
|
||||
|
||||
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
||||
return MakeLibCall(LC, RVT, &Op, 1, false);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
|
||||
SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
|
||||
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||
|
@ -334,6 +334,7 @@ private:
|
||||
SDValue SoftenFloatRes_BIT_CONVERT(SDNode *N);
|
||||
SDValue SoftenFloatRes_BUILD_PAIR(SDNode *N);
|
||||
SDValue SoftenFloatRes_ConstantFP(ConstantFPSDNode *N);
|
||||
SDValue SoftenFloatRes_FABS(SDNode *N);
|
||||
SDValue SoftenFloatRes_FADD(SDNode *N);
|
||||
SDValue SoftenFloatRes_FCOPYSIGN(SDNode *N);
|
||||
SDValue SoftenFloatRes_FDIV(SDNode *N);
|
||||
@ -352,6 +353,7 @@ private:
|
||||
bool SoftenFloatOperand(SDNode *N, unsigned OpNo);
|
||||
SDValue SoftenFloatOp_BIT_CONVERT(SDNode *N);
|
||||
SDValue SoftenFloatOp_BR_CC(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_ROUND(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_TO_SINT(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_TO_UINT(SDNode *N);
|
||||
SDValue SoftenFloatOp_SELECT_CC(SDNode *N);
|
||||
|
@ -97,6 +97,10 @@ static void InitLibcallNames(const char **Names) {
|
||||
Names[RTLIB::POW_PPCF128] = "powl";
|
||||
Names[RTLIB::FPEXT_F32_F64] = "__extendsfdf2";
|
||||
Names[RTLIB::FPROUND_F64_F32] = "__truncdfsf2";
|
||||
Names[RTLIB::FPROUND_F80_F32] = "__truncxfsf2";
|
||||
Names[RTLIB::FPROUND_PPCF128_F32] = "__trunctfsf2";
|
||||
Names[RTLIB::FPROUND_F80_F64] = "__truncxfdf2";
|
||||
Names[RTLIB::FPROUND_PPCF128_F64] = "__trunctfdf2";
|
||||
Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi";
|
||||
Names[RTLIB::FPTOSINT_F32_I64] = "__fixsfdi";
|
||||
Names[RTLIB::FPTOSINT_F32_I128] = "__fixsfti";
|
||||
@ -176,9 +180,18 @@ RTLIB::Libcall RTLIB::getFPEXT(MVT OpVT, MVT RetVT) {
|
||||
/// getFPROUND - Return the FPROUND_*_* value for the given types, or
|
||||
/// UNKNOWN_LIBCALL if there is none.
|
||||
RTLIB::Libcall RTLIB::getFPROUND(MVT OpVT, MVT RetVT) {
|
||||
if (OpVT == MVT::f64) {
|
||||
if (RetVT == MVT::f32)
|
||||
if (RetVT == MVT::f32) {
|
||||
if (OpVT == MVT::f64)
|
||||
return FPROUND_F64_F32;
|
||||
if (OpVT == MVT::f80)
|
||||
return FPROUND_F80_F32;
|
||||
if (OpVT == MVT::ppcf128)
|
||||
return FPROUND_PPCF128_F32;
|
||||
} else if (RetVT == MVT::f64) {
|
||||
if (OpVT == MVT::f80)
|
||||
return FPROUND_F80_F64;
|
||||
if (OpVT == MVT::ppcf128)
|
||||
return FPROUND_PPCF128_F64;
|
||||
}
|
||||
return UNKNOWN_LIBCALL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user