Implement ppc long double->uint conversion.
authorDale Johannesen <dalej@apple.com>
Thu, 11 Oct 2007 23:32:15 +0000 (23:32 +0000)
committerDale Johannesen <dalej@apple.com>
Thu, 11 Oct 2007 23:32:15 +0000 (23:32 +0000)
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
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

index 5eb85cd21a5d49757742d4669b336f30ddfe4df3..47a53457fc9823f5470a6f05a66cb472ceb72852 100644 (file)
@@ -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<ConstantInt>(CV)) {
index 87f39483cf622b1fd420eb051f9964126a55c29e..31a97919c062ae5731b442cedafb8155a94d6640 100644 (file)
@@ -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);