From fcf4d24ffbba0935de3e8371cfd52fc3d6980789 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Thu, 11 Oct 2007 23:32:15 +0000 Subject: [PATCH] Implement ppc long double->uint conversion. Make ppc long double constants print. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42882 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter.cpp | 33 ++++++++++++++++++++++++++++++++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 28 ++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index 5eb85cd21a5..47a53457fc9 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -917,6 +917,39 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) { << " long double most significant halfword\n"; } return; + } else if (CFP->getType() == Type::PPC_FP128Ty) { + // all long double variants are printed as hex + // api needed to prevent premature destruction + APInt api = CFP->getValueAPF().convertToAPInt(); + const uint64_t *p = api.getRawData(); + if (TD->isBigEndian()) { + O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32) + << "\t" << TAI->getCommentString() + << " long double most significant word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[0]) + << "\t" << TAI->getCommentString() + << " long double next word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32) + << "\t" << TAI->getCommentString() + << " long double next word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[1]) + << "\t" << TAI->getCommentString() + << " long double least significant word\n"; + } else { + O << TAI->getData32bitsDirective() << uint32_t(p[1]) + << "\t" << TAI->getCommentString() + << " long double least significant word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32) + << "\t" << TAI->getCommentString() + << " long double next word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[0]) + << "\t" << TAI->getCommentString() + << " long double next word\n"; + O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32) + << "\t" << TAI->getCommentString() + << " long double most significant word\n"; + } + return; } else assert(0 && "Floating point constant type not handled"); } else if (CV->getType() == Type::Int64Ty) { if (const ConstantInt *CI = dyn_cast(CV)) { diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 87f39483cf6..31a97919c06 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3322,17 +3322,35 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } break; case Expand: { - // Convert f32 / f64 to i32 / i64. MVT::ValueType VT = Op.getValueType(); MVT::ValueType OVT = Node->getOperand(0).getValueType(); + // Convert ppcf128 to i32 if (OVT == MVT::ppcf128 && VT == MVT::i32) { - Result = DAG.getNode(ISD::FP_TO_SINT, VT, + if (Node->getOpcode()==ISD::FP_TO_SINT) + Result = DAG.getNode(ISD::FP_TO_SINT, VT, DAG.getNode(ISD::FP_ROUND, MVT::f64, (DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128, Node->getOperand(0), DAG.getValueType(MVT::f64))))); + else { + const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; + APFloat apf = APFloat(APInt(128, 2, TwoE31)); + Tmp2 = DAG.getConstantFP(apf, OVT); + // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X + // FIXME: generated code sucks. + Result = DAG.getNode(ISD::SELECT_CC, VT, Node->getOperand(0), Tmp2, + DAG.getNode(ISD::ADD, MVT::i32, + DAG.getNode(ISD::FP_TO_SINT, VT, + DAG.getNode(ISD::FSUB, OVT, + Node->getOperand(0), Tmp2)), + DAG.getConstant(0x80000000, MVT::i32)), + DAG.getNode(ISD::FP_TO_SINT, VT, + Node->getOperand(0)), + DAG.getCondCode(ISD::SETGE)); + } break; } + // Convert f32 / f64 to i32 / i64. RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; switch (Node->getOpcode()) { case ISD::FP_TO_SINT: { @@ -5170,7 +5188,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ if (VT == MVT::ppcf128 && TLI.getOperationAction(ISD::FP_ROUND_INREG, VT) == TargetLowering::Custom) { - SDOperand Result = TLI.LowerOperation(Op, DAG); + SDOperand SrcLo, SrcHi, Src; + ExpandOp(Op.getOperand(0), SrcLo, SrcHi); + Src = DAG.getNode(ISD::BUILD_PAIR, VT, SrcLo, SrcHi); + SDOperand Result = TLI.LowerOperation( + DAG.getNode(ISD::FP_ROUND_INREG, VT, Src, Op.getOperand(1)), DAG); assert(Result.Val->getOpcode() == ISD::BUILD_PAIR); Lo = Result.Val->getOperand(0); Hi = Result.Val->getOperand(1); -- 2.11.0