diff options
author | Dan Gohman <gohman@apple.com> | 2008-03-10 23:03:31 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-03-10 23:03:31 +0000 |
commit | a2e9485e34f1348526ed104dbdc194673e291077 (patch) | |
tree | 0e06fcf819cf910580f4df1f58bb6101f6114bf6 | |
parent | 82e4289fc7fed755442c215e9d3175c1badb831e (diff) | |
download | external_llvm-a2e9485e34f1348526ed104dbdc194673e291077.zip external_llvm-a2e9485e34f1348526ed104dbdc194673e291077.tar.gz external_llvm-a2e9485e34f1348526ed104dbdc194673e291077.tar.bz2 |
Implement more support for fp-to-i128 and i128-to-fp conversions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48189 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/CodeGen/RuntimeLibcalls.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 205 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 8 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/int-fp-conv.ll | 17 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/itofp128.ll | 14 |
5 files changed, 172 insertions, 80 deletions
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index 637c429..92a0b78 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/include/llvm/CodeGen/RuntimeLibcalls.h @@ -93,17 +93,25 @@ namespace RTLIB { FPROUND_F64_F32, FPTOSINT_F32_I32, FPTOSINT_F32_I64, + FPTOSINT_F32_I128, FPTOSINT_F64_I32, FPTOSINT_F64_I64, + FPTOSINT_F64_I128, FPTOSINT_F80_I64, + FPTOSINT_F80_I128, FPTOSINT_PPCF128_I64, + FPTOSINT_PPCF128_I128, FPTOUINT_F32_I32, FPTOUINT_F32_I64, + FPTOUINT_F32_I128, FPTOUINT_F64_I32, FPTOUINT_F64_I64, + FPTOUINT_F64_I128, FPTOUINT_F80_I32, FPTOUINT_F80_I64, + FPTOUINT_F80_I128, FPTOUINT_PPCF128_I64, + FPTOUINT_PPCF128_I128, SINTTOFP_I32_F32, SINTTOFP_I32_F64, SINTTOFP_I64_F32, diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 1ef19ff..3f09d62 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3826,40 +3826,78 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } break; } - // Convert f32 / f64 to i32 / i64. + // Convert f32 / f64 to i32 / i64 / i128. RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; switch (Node->getOpcode()) { case ISD::FP_TO_SINT: { - if (OVT == MVT::f32) - LC = (VT == MVT::i32) - ? RTLIB::FPTOSINT_F32_I32 : RTLIB::FPTOSINT_F32_I64; - else if (OVT == MVT::f64) - LC = (VT == MVT::i32) - ? RTLIB::FPTOSINT_F64_I32 : RTLIB::FPTOSINT_F64_I64; - else if (OVT == MVT::f80) { - assert(VT == MVT::i64); - LC = RTLIB::FPTOSINT_F80_I64; - } - else if (OVT == MVT::ppcf128) { - assert(VT == MVT::i64); - LC = RTLIB::FPTOSINT_PPCF128_I64; + if (VT == MVT::i32) { + if (OVT == MVT::f32) + LC = RTLIB::FPTOSINT_F32_I32; + else if (OVT == MVT::f64) + LC = RTLIB::FPTOSINT_F64_I32; + else + assert(0 && "Unexpected i32-to-fp conversion!"); + } else if (VT == MVT::i64) { + if (OVT == MVT::f32) + LC = RTLIB::FPTOSINT_F32_I64; + else if (OVT == MVT::f64) + LC = RTLIB::FPTOSINT_F64_I64; + else if (OVT == MVT::f80) + LC = RTLIB::FPTOSINT_F80_I64; + else if (OVT == MVT::ppcf128) + LC = RTLIB::FPTOSINT_PPCF128_I64; + else + assert(0 && "Unexpected i64-to-fp conversion!"); + } else if (VT == MVT::i128) { + if (OVT == MVT::f32) + LC = RTLIB::FPTOSINT_F32_I128; + else if (OVT == MVT::f64) + LC = RTLIB::FPTOSINT_F64_I128; + else if (OVT == MVT::f80) + LC = RTLIB::FPTOSINT_F80_I128; + else if (OVT == MVT::ppcf128) + LC = RTLIB::FPTOSINT_PPCF128_I128; + else + assert(0 && "Unexpected i128-to-fp conversion!"); + } else { + assert(0 && "Unexpectd int-to-fp conversion!"); } break; } case ISD::FP_TO_UINT: { - if (OVT == MVT::f32) - LC = (VT == MVT::i32) - ? RTLIB::FPTOUINT_F32_I32 : RTLIB::FPTOSINT_F32_I64; - else if (OVT == MVT::f64) - LC = (VT == MVT::i32) - ? RTLIB::FPTOUINT_F64_I32 : RTLIB::FPTOSINT_F64_I64; - else if (OVT == MVT::f80) { - LC = (VT == MVT::i32) - ? RTLIB::FPTOUINT_F80_I32 : RTLIB::FPTOUINT_F80_I64; - } - else if (OVT == MVT::ppcf128) { - assert(VT == MVT::i64); - LC = RTLIB::FPTOUINT_PPCF128_I64; + if (VT == MVT::i32) { + if (OVT == MVT::f32) + LC = RTLIB::FPTOUINT_F32_I32; + else if (OVT == MVT::f64) + LC = RTLIB::FPTOUINT_F64_I32; + else if (OVT == MVT::f80) + LC = RTLIB::FPTOUINT_F80_I32; + else + assert(0 && "Unexpected i32-to-fp conversion!"); + } else if (VT == MVT::i64) { + if (OVT == MVT::f32) + LC = RTLIB::FPTOUINT_F32_I64; + else if (OVT == MVT::f64) + LC = RTLIB::FPTOUINT_F64_I64; + else if (OVT == MVT::f80) + LC = RTLIB::FPTOUINT_F80_I64; + else if (OVT == MVT::ppcf128) + LC = RTLIB::FPTOUINT_PPCF128_I64; + else + assert(0 && "Unexpected i64-to-fp conversion!"); + } else if (VT == MVT::i128) { + if (OVT == MVT::f32) + LC = RTLIB::FPTOUINT_F32_I128; + else if (OVT == MVT::f64) + LC = RTLIB::FPTOUINT_F64_I128; + else if (OVT == MVT::f80) + LC = RTLIB::FPTOUINT_F80_I128; + else if (OVT == MVT::ppcf128) + LC = RTLIB::FPTOUINT_PPCF128_I128; + else + assert(0 && "Unexpected i128-to-fp conversion!"); + } else { + assert(0 && "Unexpectd int-to-fp conversion!"); } break; } @@ -5428,9 +5466,12 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) { assert(TLI.getLibcallName(LC) && "Don't know how to expand this SINT_TO_FP!"); Source = DAG.getNode(ISD::SINT_TO_FP, DestTy, Source); - SDOperand UnusedHiPart; - return ExpandLibCall(TLI.getLibcallName(LC), Source.Val, isSigned, - UnusedHiPart); + SDOperand HiPart; + SDOperand Result = ExpandLibCall(TLI.getLibcallName(LC), Source.Val, isSigned, + HiPart); + if (Result.getValueType() != DestTy) + Result = DAG.getNode(ISD::BUILD_PAIR, DestTy, Result, HiPart); + return Result; } /// ExpandLegalINT_TO_FP - This function is responsible for legalizing a @@ -6177,16 +6218,31 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ } RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; - if (Node->getOperand(0).getValueType() == MVT::f32) - LC = RTLIB::FPTOSINT_F32_I64; - else if (Node->getOperand(0).getValueType() == MVT::f64) - LC = RTLIB::FPTOSINT_F64_I64; - else if (Node->getOperand(0).getValueType() == MVT::f80) - LC = RTLIB::FPTOSINT_F80_I64; - else if (Node->getOperand(0).getValueType() == MVT::ppcf128) - LC = RTLIB::FPTOSINT_PPCF128_I64; - Lo = ExpandLibCall(TLI.getLibcallName(LC), Node, - false/*sign irrelevant*/, Hi); + if (VT == MVT::i64) { + if (Node->getOperand(0).getValueType() == MVT::f32) + LC = RTLIB::FPTOSINT_F32_I64; + else if (Node->getOperand(0).getValueType() == MVT::f64) + LC = RTLIB::FPTOSINT_F64_I64; + else if (Node->getOperand(0).getValueType() == MVT::f80) + LC = RTLIB::FPTOSINT_F80_I64; + else if (Node->getOperand(0).getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOSINT_PPCF128_I64; + Lo = ExpandLibCall(TLI.getLibcallName(LC), Node, + false/*sign irrelevant*/, Hi); + } else if (VT == MVT::i128) { + if (Node->getOperand(0).getValueType() == MVT::f32) + LC = RTLIB::FPTOSINT_F32_I128; + else if (Node->getOperand(0).getValueType() == MVT::f64) + LC = RTLIB::FPTOSINT_F64_I128; + else if (Node->getOperand(0).getValueType() == MVT::f80) + LC = RTLIB::FPTOSINT_F80_I128; + else if (Node->getOperand(0).getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOSINT_PPCF128_I128; + Lo = ExpandLibCall(TLI.getLibcallName(LC), Node, + false/*sign irrelevant*/, Hi); + } else { + assert(0 && "Unexpected uint-to-fp conversion!"); + } break; } @@ -6209,16 +6265,31 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ } RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; - if (Node->getOperand(0).getValueType() == MVT::f32) - LC = RTLIB::FPTOUINT_F32_I64; - else if (Node->getOperand(0).getValueType() == MVT::f64) - LC = RTLIB::FPTOUINT_F64_I64; - else if (Node->getOperand(0).getValueType() == MVT::f80) - LC = RTLIB::FPTOUINT_F80_I64; - else if (Node->getOperand(0).getValueType() == MVT::ppcf128) - LC = RTLIB::FPTOUINT_PPCF128_I64; - Lo = ExpandLibCall(TLI.getLibcallName(LC), Node, - false/*sign irrelevant*/, Hi); + if (VT == MVT::i64) { + if (Node->getOperand(0).getValueType() == MVT::f32) + LC = RTLIB::FPTOUINT_F32_I64; + else if (Node->getOperand(0).getValueType() == MVT::f64) + LC = RTLIB::FPTOUINT_F64_I64; + else if (Node->getOperand(0).getValueType() == MVT::f80) + LC = RTLIB::FPTOUINT_F80_I64; + else if (Node->getOperand(0).getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOUINT_PPCF128_I64; + Lo = ExpandLibCall(TLI.getLibcallName(LC), Node, + false/*sign irrelevant*/, Hi); + } else if (VT == MVT::i128) { + if (Node->getOperand(0).getValueType() == MVT::f32) + LC = RTLIB::FPTOUINT_F32_I128; + else if (Node->getOperand(0).getValueType() == MVT::f64) + LC = RTLIB::FPTOUINT_F64_I128; + else if (Node->getOperand(0).getValueType() == MVT::f80) + LC = RTLIB::FPTOUINT_F80_I128; + else if (Node->getOperand(0).getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOUINT_PPCF128_I128; + Lo = ExpandLibCall(TLI.getLibcallName(LC), Node, + false/*sign irrelevant*/, Hi); + } else { + assert(0 && "Unexpected uint-to-fp conversion!"); + } break; } @@ -6631,7 +6702,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ case ISD::UINT_TO_FP: { bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP; MVT::ValueType SrcVT = Node->getOperand(0).getValueType(); - if (VT == MVT::ppcf128 && SrcVT != MVT::i64) { + if (VT == MVT::ppcf128 && SrcVT == MVT::i32) { static const uint64_t zero = 0; if (isSigned) { Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, MVT::f64, @@ -6674,26 +6745,6 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Lo, Hi); break; } - RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; - if (Node->getOperand(0).getValueType() == MVT::i64) { - if (VT == MVT::f32) - LC = isSigned ? RTLIB::SINTTOFP_I64_F32 : RTLIB::UINTTOFP_I64_F32; - else if (VT == MVT::f64) - LC = isSigned ? RTLIB::SINTTOFP_I64_F64 : RTLIB::UINTTOFP_I64_F64; - else if (VT == MVT::f80) { - assert(isSigned); - LC = RTLIB::SINTTOFP_I64_F80; - } - else if (VT == MVT::ppcf128) { - assert(isSigned); - LC = RTLIB::SINTTOFP_I64_PPCF128; - } - } else { - if (VT == MVT::f32) - LC = isSigned ? RTLIB::SINTTOFP_I32_F32 : RTLIB::UINTTOFP_I32_F32; - else - LC = isSigned ? RTLIB::SINTTOFP_I32_F64 : RTLIB::UINTTOFP_I32_F64; - } // Promote the operand if needed. if (getTypeAction(SrcVT) == Promote) { @@ -6705,15 +6756,9 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Node = DAG.UpdateNodeOperands(Op, Tmp).Val; } - const char *LibCall = TLI.getLibcallName(LC); - if (LibCall) - Lo = ExpandLibCall(TLI.getLibcallName(LC), Node, isSigned, Hi); - else { - Lo = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, VT, - Node->getOperand(0)); - if (getTypeAction(Lo.getValueType()) == Expand) - ExpandOp(Lo, Lo, Hi); - } + Lo = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, VT, + Node->getOperand(0)); + ExpandOp(Lo, Lo, Hi); break; } } diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 7900e97..90887a0 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -90,17 +90,25 @@ static void InitLibcallNames(const char **Names) { Names[RTLIB::FPROUND_F64_F32] = "__truncdfsf2"; Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi"; Names[RTLIB::FPTOSINT_F32_I64] = "__fixsfdi"; + Names[RTLIB::FPTOSINT_F32_I128] = "__fixsfti"; Names[RTLIB::FPTOSINT_F64_I32] = "__fixdfsi"; Names[RTLIB::FPTOSINT_F64_I64] = "__fixdfdi"; + Names[RTLIB::FPTOSINT_F64_I128] = "__fixdfti"; Names[RTLIB::FPTOSINT_F80_I64] = "__fixxfdi"; + Names[RTLIB::FPTOSINT_F80_I128] = "__fixxfti"; Names[RTLIB::FPTOSINT_PPCF128_I64] = "__fixtfdi"; + Names[RTLIB::FPTOSINT_PPCF128_I128] = "__fixtfti"; Names[RTLIB::FPTOUINT_F32_I32] = "__fixunssfsi"; Names[RTLIB::FPTOUINT_F32_I64] = "__fixunssfdi"; + Names[RTLIB::FPTOUINT_F32_I128] = "__fixunssfti"; Names[RTLIB::FPTOUINT_F64_I32] = "__fixunsdfsi"; Names[RTLIB::FPTOUINT_F64_I64] = "__fixunsdfdi"; + Names[RTLIB::FPTOUINT_F64_I128] = "__fixunsdfti"; Names[RTLIB::FPTOUINT_F80_I32] = "__fixunsxfsi"; Names[RTLIB::FPTOUINT_F80_I64] = "__fixunsxfdi"; + Names[RTLIB::FPTOUINT_F80_I128] = "__fixunsxfti"; Names[RTLIB::FPTOUINT_PPCF128_I64] = "__fixunstfdi"; + Names[RTLIB::FPTOUINT_PPCF128_I128] = "__fixunstfti"; Names[RTLIB::SINTTOFP_I32_F32] = "__floatsisf"; Names[RTLIB::SINTTOFP_I32_F64] = "__floatsidf"; Names[RTLIB::SINTTOFP_I64_F32] = "__floatdisf"; diff --git a/test/CodeGen/PowerPC/int-fp-conv.ll b/test/CodeGen/PowerPC/int-fp-conv.ll new file mode 100644 index 0000000..82a1826 --- /dev/null +++ b/test/CodeGen/PowerPC/int-fp-conv.ll @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | llc -march=ppc64 > %t +; RUN: grep __floattitf %t +; RUN: grep __fixunstfti %t + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128" +target triple = "powerpc64-apple-darwin9.2.0" + +define ppc_fp128 @foo(i128 %a) nounwind { +entry: + %tmp2829 = uitofp i128 %a to ppc_fp128 ; <i64> [#uses=1] + ret ppc_fp128 %tmp2829 +} +define i128 @boo(ppc_fp128 %a) nounwind { +entry: + %tmp2829 = fptoui ppc_fp128 %a to i128 ; <i64> [#uses=1] + ret i128 %tmp2829 +} diff --git a/test/CodeGen/PowerPC/itofp128.ll b/test/CodeGen/PowerPC/itofp128.ll new file mode 100644 index 0000000..91119e9 --- /dev/null +++ b/test/CodeGen/PowerPC/itofp128.ll @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llc -march=ppc64 + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128" +target triple = "powerpc64-apple-darwin9.2.0" + +define i128 @__fixunstfti(ppc_fp128 %a) nounwind { +entry: + %tmp1213 = uitofp i128 0 to ppc_fp128 ; <ppc_fp128> [#uses=1] + %tmp15 = sub ppc_fp128 %a, %tmp1213 ; <ppc_fp128> [#uses=1] + %tmp2829 = fptoui ppc_fp128 %tmp15 to i64 ; <i64> [#uses=1] + %tmp282930 = zext i64 %tmp2829 to i128 ; <i128> [#uses=1] + %tmp32 = add i128 %tmp282930, 0 ; <i128> [#uses=1] + ret i128 %tmp32 +} |