LLVM API Documentation

LegalizeFloatTypes.cpp

Go to the documentation of this file.
00001 //===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements float type expansion and softening for LegalizeTypes.
00011 // Softening is the act of turning a computation in an illegal floating point
00012 // type into a computation in an integer type of the same size; also known as
00013 // "soft float".  For example, turning f32 arithmetic into operations using i32.
00014 // The resulting integer value is the same as what you would get by performing
00015 // the floating point operation and bitcasting the result to the integer type.
00016 // Expansion is the act of changing a computation in an illegal type to be a
00017 // computation in two identical registers of a smaller type.  For example,
00018 // implementing ppcf128 arithmetic in two f64 registers.
00019 //
00020 //===----------------------------------------------------------------------===//
00021 
00022 #include "LegalizeTypes.h"
00023 using namespace llvm;
00024 
00025 /// GetFPLibCall - Return the right libcall for the given floating point type.
00026 static RTLIB::Libcall GetFPLibCall(MVT VT,
00027                                    RTLIB::Libcall Call_F32,
00028                                    RTLIB::Libcall Call_F64,
00029                                    RTLIB::Libcall Call_F80,
00030                                    RTLIB::Libcall Call_PPCF128) {
00031   return
00032     VT == MVT::f32 ? Call_F32 :
00033     VT == MVT::f64 ? Call_F64 :
00034     VT == MVT::f80 ? Call_F80 :
00035     VT == MVT::ppcf128 ? Call_PPCF128 :
00036     RTLIB::UNKNOWN_LIBCALL;
00037 }
00038 
00039 //===----------------------------------------------------------------------===//
00040 //  Result Float to Integer Conversion.
00041 //===----------------------------------------------------------------------===//
00042 
00043 void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
00044   DEBUG(cerr << "Soften float result " << ResNo << ": "; N->dump(&DAG);
00045         cerr << "\n");
00046   SDValue R = SDValue();
00047 
00048   switch (N->getOpcode()) {
00049   default:
00050 #ifndef NDEBUG
00051     cerr << "SoftenFloatResult #" << ResNo << ": ";
00052     N->dump(&DAG); cerr << "\n";
00053 #endif
00054     assert(0 && "Do not know how to soften the result of this operator!");
00055     abort();
00056 
00057     case ISD::BIT_CONVERT: R = SoftenFloatRes_BIT_CONVERT(N); break;
00058     case ISD::BUILD_PAIR:  R = SoftenFloatRes_BUILD_PAIR(N); break;
00059     case ISD::ConstantFP:
00060       R = SoftenFloatRes_ConstantFP(cast<ConstantFPSDNode>(N));
00061       break;
00062     case ISD::FABS:        R = SoftenFloatRes_FABS(N); break;
00063     case ISD::FADD:        R = SoftenFloatRes_FADD(N); break;
00064     case ISD::FCEIL:       R = SoftenFloatRes_FCEIL(N); break;
00065     case ISD::FCOPYSIGN:   R = SoftenFloatRes_FCOPYSIGN(N); break;
00066     case ISD::FCOS:        R = SoftenFloatRes_FCOS(N); break;
00067     case ISD::FDIV:        R = SoftenFloatRes_FDIV(N); break;
00068     case ISD::FEXP:        R = SoftenFloatRes_FEXP(N); break;
00069     case ISD::FEXP2:       R = SoftenFloatRes_FEXP2(N); break;
00070     case ISD::FFLOOR:      R = SoftenFloatRes_FFLOOR(N); break;
00071     case ISD::FLOG:        R = SoftenFloatRes_FLOG(N); break;
00072     case ISD::FLOG2:       R = SoftenFloatRes_FLOG2(N); break;
00073     case ISD::FLOG10:      R = SoftenFloatRes_FLOG10(N); break;
00074     case ISD::FMUL:        R = SoftenFloatRes_FMUL(N); break;
00075     case ISD::FNEARBYINT:  R = SoftenFloatRes_FNEARBYINT(N); break;
00076     case ISD::FNEG:        R = SoftenFloatRes_FNEG(N); break;
00077     case ISD::FP_EXTEND:   R = SoftenFloatRes_FP_EXTEND(N); break;
00078     case ISD::FP_ROUND:    R = SoftenFloatRes_FP_ROUND(N); break;
00079     case ISD::FPOW:        R = SoftenFloatRes_FPOW(N); break;
00080     case ISD::FPOWI:       R = SoftenFloatRes_FPOWI(N); break;
00081     case ISD::FRINT:       R = SoftenFloatRes_FRINT(N); break;
00082     case ISD::FSIN:        R = SoftenFloatRes_FSIN(N); break;
00083     case ISD::FSQRT:       R = SoftenFloatRes_FSQRT(N); break;
00084     case ISD::FSUB:        R = SoftenFloatRes_FSUB(N); break;
00085     case ISD::FTRUNC:      R = SoftenFloatRes_FTRUNC(N); break;
00086     case ISD::LOAD:        R = SoftenFloatRes_LOAD(N); break;
00087     case ISD::SELECT:      R = SoftenFloatRes_SELECT(N); break;
00088     case ISD::SELECT_CC:   R = SoftenFloatRes_SELECT_CC(N); break;
00089     case ISD::SINT_TO_FP:
00090     case ISD::UINT_TO_FP:  R = SoftenFloatRes_XINT_TO_FP(N); break;
00091   }
00092 
00093   // If R is null, the sub-method took care of registering the result.
00094   if (R.getNode())
00095     SetSoftenedFloat(SDValue(N, ResNo), R);
00096 }
00097 
00098 SDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) {
00099   return BitConvertToInteger(N->getOperand(0));
00100 }
00101 
00102 SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) {
00103   // Convert the inputs to integers, and build a new pair out of them.
00104   return DAG.getNode(ISD::BUILD_PAIR, N->getDebugLoc(),
00105                      TLI.getTypeToTransformTo(N->getValueType(0)),
00106                      BitConvertToInteger(N->getOperand(0)),
00107                      BitConvertToInteger(N->getOperand(1)));
00108 }
00109 
00110 SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) {
00111   return DAG.getConstant(N->getValueAPF().bitcastToAPInt(),
00112                          TLI.getTypeToTransformTo(N->getValueType(0)));
00113 }
00114 
00115 SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) {
00116   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00117   unsigned Size = NVT.getSizeInBits();
00118 
00119   // Mask = ~(1 << (Size-1))
00120   SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1),
00121                                  NVT);
00122   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00123   return DAG.getNode(ISD::AND, N->getDebugLoc(), NVT, Op, Mask);
00124 }
00125 
00126 SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) {
00127   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00128   SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
00129                      GetSoftenedFloat(N->getOperand(1)) };
00130   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00131                                   RTLIB::ADD_F32,
00132                                   RTLIB::ADD_F64,
00133                                   RTLIB::ADD_F80,
00134                                   RTLIB::ADD_PPCF128),
00135                      NVT, Ops, 2, false, N->getDebugLoc());
00136 }
00137 
00138 SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) {
00139   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00140   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00141   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00142                                   RTLIB::CEIL_F32,
00143                                   RTLIB::CEIL_F64,
00144                                   RTLIB::CEIL_F80,
00145                                   RTLIB::CEIL_PPCF128),
00146                      NVT, &Op, 1, false, N->getDebugLoc());
00147 }
00148 
00149 SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) {
00150   SDValue LHS = GetSoftenedFloat(N->getOperand(0));
00151   SDValue RHS = BitConvertToInteger(N->getOperand(1));
00152   DebugLoc dl = N->getDebugLoc();
00153 
00154   MVT LVT = LHS.getValueType();
00155   MVT RVT = RHS.getValueType();
00156 
00157   unsigned LSize = LVT.getSizeInBits();
00158   unsigned RSize = RVT.getSizeInBits();
00159 
00160   // First get the sign bit of second operand.
00161   SDValue SignBit = DAG.getNode(ISD::SHL, dl, RVT, DAG.getConstant(1, RVT),
00162                                   DAG.getConstant(RSize - 1,
00163                                                   TLI.getShiftAmountTy()));
00164   SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit);
00165 
00166   // Shift right or sign-extend it if the two operands have different types.
00167   int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits();
00168   if (SizeDiff > 0) {
00169     SignBit = DAG.getNode(ISD::SRL, dl, RVT, SignBit,
00170                           DAG.getConstant(SizeDiff, TLI.getShiftAmountTy()));
00171     SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit);
00172   } else if (SizeDiff < 0) {
00173     SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit);
00174     SignBit = DAG.getNode(ISD::SHL, dl, LVT, SignBit,
00175                           DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy()));
00176   }
00177 
00178   // Clear the sign bit of the first operand.
00179   SDValue Mask = DAG.getNode(ISD::SHL, dl, LVT, DAG.getConstant(1, LVT),
00180                                DAG.getConstant(LSize - 1,
00181                                                TLI.getShiftAmountTy()));
00182   Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, LVT));
00183   LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask);
00184 
00185   // Or the value with the sign bit.
00186   return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit);
00187 }
00188 
00189 SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) {
00190   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00191   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00192   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00193                                   RTLIB::COS_F32,
00194                                   RTLIB::COS_F64,
00195                                   RTLIB::COS_F80,
00196                                   RTLIB::COS_PPCF128),
00197                      NVT, &Op, 1, false, N->getDebugLoc());
00198 }
00199 
00200 SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) {
00201   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00202   SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
00203                      GetSoftenedFloat(N->getOperand(1)) };
00204   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00205                                   RTLIB::DIV_F32,
00206                                   RTLIB::DIV_F64,
00207                                   RTLIB::DIV_F80,
00208                                   RTLIB::DIV_PPCF128),
00209                      NVT, Ops, 2, false, N->getDebugLoc());
00210 }
00211 
00212 SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) {
00213   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00214   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00215   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00216                                   RTLIB::EXP_F32,
00217                                   RTLIB::EXP_F64,
00218                                   RTLIB::EXP_F80,
00219                                   RTLIB::EXP_PPCF128),
00220                      NVT, &Op, 1, false, N->getDebugLoc());
00221 }
00222 
00223 SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) {
00224   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00225   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00226   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00227                                   RTLIB::EXP2_F32,
00228                                   RTLIB::EXP2_F64,
00229                                   RTLIB::EXP2_F80,
00230                                   RTLIB::EXP2_PPCF128),
00231                      NVT, &Op, 1, false, N->getDebugLoc());
00232 }
00233 
00234 SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) {
00235   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00236   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00237   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00238                                   RTLIB::FLOOR_F32,
00239                                   RTLIB::FLOOR_F64,
00240                                   RTLIB::FLOOR_F80,
00241                                   RTLIB::FLOOR_PPCF128),
00242                      NVT, &Op, 1, false, N->getDebugLoc());
00243 }
00244 
00245 SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) {
00246   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00247   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00248   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00249                                   RTLIB::LOG_F32,
00250                                   RTLIB::LOG_F64,
00251                                   RTLIB::LOG_F80,
00252                                   RTLIB::LOG_PPCF128),
00253                      NVT, &Op, 1, false, N->getDebugLoc());
00254 }
00255 
00256 SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) {
00257   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00258   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00259   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00260                                   RTLIB::LOG2_F32,
00261                                   RTLIB::LOG2_F64,
00262                                   RTLIB::LOG2_F80,
00263                                   RTLIB::LOG2_PPCF128),
00264                      NVT, &Op, 1, false, N->getDebugLoc());
00265 }
00266 
00267 SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) {
00268   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00269   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00270   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00271                                   RTLIB::LOG10_F32,
00272                                   RTLIB::LOG10_F64,
00273                                   RTLIB::LOG10_F80,
00274                                   RTLIB::LOG10_PPCF128),
00275                      NVT, &Op, 1, false, N->getDebugLoc());
00276 }
00277 
00278 SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
00279   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00280   SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
00281                      GetSoftenedFloat(N->getOperand(1)) };
00282   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00283                                   RTLIB::MUL_F32,
00284                                   RTLIB::MUL_F64,
00285                                   RTLIB::MUL_F80,
00286                                   RTLIB::MUL_PPCF128),
00287                      NVT, Ops, 2, false, N->getDebugLoc());
00288 }
00289 
00290 SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) {
00291   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00292   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00293   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00294                                   RTLIB::NEARBYINT_F32,
00295                                   RTLIB::NEARBYINT_F64,
00296                                   RTLIB::NEARBYINT_F80,
00297                                   RTLIB::NEARBYINT_PPCF128),
00298                      NVT, &Op, 1, false, N->getDebugLoc());
00299 }
00300 
00301 SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) {
00302   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00303   // Expand Y = FNEG(X) -> Y = SUB -0.0, X
00304   SDValue Ops[2] = { DAG.getConstantFP(-0.0, N->getValueType(0)),
00305                      GetSoftenedFloat(N->getOperand(0)) };
00306   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00307                                   RTLIB::SUB_F32,
00308                                   RTLIB::SUB_F64,
00309                                   RTLIB::SUB_F80,
00310                                   RTLIB::SUB_PPCF128),
00311                      NVT, Ops, 2, false, N->getDebugLoc());
00312 }
00313 
00314 SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
00315   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00316   SDValue Op = N->getOperand(0);
00317   RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0));
00318   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!");
00319   return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc());
00320 }
00321 
00322 SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
00323   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00324   SDValue Op = N->getOperand(0);
00325   RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0));
00326   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!");
00327   return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc());
00328 }
00329 
00330 SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) {
00331   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00332   SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
00333                      GetSoftenedFloat(N->getOperand(1)) };
00334   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00335                                   RTLIB::POW_F32,
00336                                   RTLIB::POW_F64,
00337                                   RTLIB::POW_F80,
00338                                   RTLIB::POW_PPCF128),
00339                      NVT, Ops, 2, false, N->getDebugLoc());
00340 }
00341 
00342 SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) {
00343   assert(N->getOperand(1).getValueType() == MVT::i32 &&
00344          "Unsupported power type!");
00345   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00346   SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) };
00347   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00348                                   RTLIB::POWI_F32,
00349                                   RTLIB::POWI_F64,
00350                                   RTLIB::POWI_F80,
00351                                   RTLIB::POWI_PPCF128),
00352                      NVT, Ops, 2, false, N->getDebugLoc());
00353 }
00354 
00355 SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) {
00356   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00357   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00358   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00359                                   RTLIB::RINT_F32,
00360                                   RTLIB::RINT_F64,
00361                                   RTLIB::RINT_F80,
00362                                   RTLIB::RINT_PPCF128),
00363                      NVT, &Op, 1, false, N->getDebugLoc());
00364 }
00365 
00366 SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) {
00367   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00368   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00369   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00370                                   RTLIB::SIN_F32,
00371                                   RTLIB::SIN_F64,
00372                                   RTLIB::SIN_F80,
00373                                   RTLIB::SIN_PPCF128),
00374                      NVT, &Op, 1, false, N->getDebugLoc());
00375 }
00376 
00377 SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) {
00378   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00379   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00380   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00381                                   RTLIB::SQRT_F32,
00382                                   RTLIB::SQRT_F64,
00383                                   RTLIB::SQRT_F80,
00384                                   RTLIB::SQRT_PPCF128),
00385                      NVT, &Op, 1, false, N->getDebugLoc());
00386 }
00387 
00388 SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) {
00389   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00390   SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
00391                      GetSoftenedFloat(N->getOperand(1)) };
00392   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00393                                   RTLIB::SUB_F32,
00394                                   RTLIB::SUB_F64,
00395                                   RTLIB::SUB_F80,
00396                                   RTLIB::SUB_PPCF128),
00397                      NVT, Ops, 2, false, N->getDebugLoc());
00398 }
00399 
00400 SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) {
00401   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00402   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00403   return MakeLibCall(GetFPLibCall(N->getValueType(0),
00404                                   RTLIB::TRUNC_F32,
00405                                   RTLIB::TRUNC_F64,
00406                                   RTLIB::TRUNC_F80,
00407                                   RTLIB::TRUNC_PPCF128),
00408                      NVT, &Op, 1, false, N->getDebugLoc());
00409 }
00410 
00411 SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
00412   LoadSDNode *L = cast<LoadSDNode>(N);
00413   MVT VT = N->getValueType(0);
00414   MVT NVT = TLI.getTypeToTransformTo(VT);
00415   DebugLoc dl = N->getDebugLoc();
00416 
00417   SDValue NewL;
00418   if (L->getExtensionType() == ISD::NON_EXTLOAD) {
00419     NewL = DAG.getLoad(L->getAddressingMode(), dl, L->getExtensionType(),
00420                        NVT, L->getChain(), L->getBasePtr(), L->getOffset(),
00421                        L->getSrcValue(), L->getSrcValueOffset(), NVT,
00422                        L->isVolatile(), L->getAlignment());
00423     // Legalized the chain result - switch anything that used the old chain to
00424     // use the new one.
00425     ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
00426     return NewL;
00427   }
00428 
00429   // Do a non-extending load followed by FP_EXTEND.
00430   NewL = DAG.getLoad(L->getAddressingMode(), dl, ISD::NON_EXTLOAD,
00431                      L->getMemoryVT(), L->getChain(),
00432                      L->getBasePtr(), L->getOffset(),
00433                      L->getSrcValue(), L->getSrcValueOffset(),
00434                      L->getMemoryVT(),
00435                      L->isVolatile(), L->getAlignment());
00436   // Legalized the chain result - switch anything that used the old chain to
00437   // use the new one.
00438   ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
00439   return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL));
00440 }
00441 
00442 SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) {
00443   SDValue LHS = GetSoftenedFloat(N->getOperand(1));
00444   SDValue RHS = GetSoftenedFloat(N->getOperand(2));
00445   return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
00446                      LHS.getValueType(), N->getOperand(0),LHS,RHS);
00447 }
00448 
00449 SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) {
00450   SDValue LHS = GetSoftenedFloat(N->getOperand(2));
00451   SDValue RHS = GetSoftenedFloat(N->getOperand(3));
00452   return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(),
00453                      LHS.getValueType(), N->getOperand(0),
00454                      N->getOperand(1), LHS, RHS, N->getOperand(4));
00455 }
00456 
00457 SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
00458   bool Signed = N->getOpcode() == ISD::SINT_TO_FP;
00459   MVT SVT = N->getOperand(0).getValueType();
00460   MVT RVT = N->getValueType(0);
00461   MVT NVT = MVT();
00462   DebugLoc dl = N->getDebugLoc();
00463 
00464   // If the input is not legal, eg: i1 -> fp, then it needs to be promoted to
00465   // a larger type, eg: i8 -> fp.  Even if it is legal, no libcall may exactly
00466   // match.  Look for an appropriate libcall.
00467   RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
00468   for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
00469        t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
00470     NVT = (MVT::SimpleValueType)t;
00471     // The source needs to big enough to hold the operand.
00472     if (NVT.bitsGE(SVT))
00473       LC = Signed ? RTLIB::getSINTTOFP(NVT, RVT):RTLIB::getUINTTOFP (NVT, RVT);
00474   }
00475   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
00476 
00477   // Sign/zero extend the argument if the libcall takes a larger type.
00478   SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
00479                            NVT, N->getOperand(0));
00480   return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false, dl);
00481 }
00482 
00483 
00484 //===----------------------------------------------------------------------===//
00485 //  Operand Float to Integer Conversion..
00486 //===----------------------------------------------------------------------===//
00487 
00488 bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
00489   DEBUG(cerr << "Soften float operand " << OpNo << ": "; N->dump(&DAG);
00490         cerr << "\n");
00491   SDValue Res = SDValue();
00492 
00493   switch (N->getOpcode()) {
00494   default:
00495 #ifndef NDEBUG
00496     cerr << "SoftenFloatOperand Op #" << OpNo << ": ";
00497     N->dump(&DAG); cerr << "\n";
00498 #endif
00499     assert(0 && "Do not know how to soften this operator's operand!");
00500     abort();
00501 
00502   case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break;
00503   case ISD::BR_CC:       Res = SoftenFloatOp_BR_CC(N); break;
00504   case ISD::FP_ROUND:    Res = SoftenFloatOp_FP_ROUND(N); break;
00505   case ISD::FP_TO_SINT:  Res = SoftenFloatOp_FP_TO_SINT(N); break;
00506   case ISD::FP_TO_UINT:  Res = SoftenFloatOp_FP_TO_UINT(N); break;
00507   case ISD::SELECT_CC:   Res = SoftenFloatOp_SELECT_CC(N); break;
00508   case ISD::SETCC:       Res = SoftenFloatOp_SETCC(N); break;
00509   case ISD::STORE:       Res = SoftenFloatOp_STORE(N, OpNo); break;
00510   }
00511 
00512   // If the result is null, the sub-method took care of registering results etc.
00513   if (!Res.getNode()) return false;
00514 
00515   // If the result is N, the sub-method updated N in place.  Tell the legalizer
00516   // core about this.
00517   if (Res.getNode() == N)
00518     return true;
00519 
00520   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
00521          "Invalid operand expansion");
00522 
00523   ReplaceValueWith(SDValue(N, 0), Res);
00524   return false;
00525 }
00526 
00527 /// SoftenSetCCOperands - Soften the operands of a comparison.  This code is
00528 /// shared among BR_CC, SELECT_CC, and SETCC handlers.
00529 void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
00530                                            ISD::CondCode &CCCode, DebugLoc dl) {
00531   SDValue LHSInt = GetSoftenedFloat(NewLHS);
00532   SDValue RHSInt = GetSoftenedFloat(NewRHS);
00533   MVT VT = NewLHS.getValueType();
00534 
00535   assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!");
00536 
00537   // Expand into one or more soft-fp libcall(s).
00538   RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL;
00539   switch (CCCode) {
00540   case ISD::SETEQ:
00541   case ISD::SETOEQ:
00542     LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
00543     break;
00544   case ISD::SETNE:
00545   case ISD::SETUNE:
00546     LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : RTLIB::UNE_F64;
00547     break;
00548   case ISD::SETGE:
00549   case ISD::SETOGE:
00550     LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
00551     break;
00552   case ISD::SETLT:
00553   case ISD::SETOLT:
00554     LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
00555     break;
00556   case ISD::SETLE:
00557   case ISD::SETOLE:
00558     LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
00559     break;
00560   case ISD::SETGT:
00561   case ISD::SETOGT:
00562     LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
00563     break;
00564   case ISD::SETUO:
00565     LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
00566     break;
00567   case ISD::SETO:
00568     LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : RTLIB::O_F64;
00569     break;
00570   default:
00571     LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
00572     switch (CCCode) {
00573     case ISD::SETONE:
00574       // SETONE = SETOLT | SETOGT
00575       LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
00576       // Fallthrough
00577     case ISD::SETUGT:
00578       LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
00579       break;
00580     case ISD::SETUGE:
00581       LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
00582       break;
00583     case ISD::SETULT:
00584       LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
00585       break;
00586     case ISD::SETULE:
00587       LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
00588       break;
00589     case ISD::SETUEQ:
00590       LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
00591       break;
00592     default: assert(false && "Do not know how to soften this setcc!");
00593     }
00594   }
00595 
00596   MVT RetVT = MVT::i32; // FIXME: is this the correct return type?
00597   SDValue Ops[2] = { LHSInt, RHSInt };
00598   NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/, dl);
00599   NewRHS = DAG.getConstant(0, RetVT);
00600   CCCode = TLI.getCmpLibcallCC(LC1);
00601   if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
00602     SDValue Tmp = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT),
00603                                 NewLHS, NewRHS, DAG.getCondCode(CCCode));
00604     NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/, dl);
00605     NewLHS = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), NewLHS,
00606                          NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2)));
00607     NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS);
00608     NewRHS = SDValue();
00609   }
00610 }
00611 
00612 SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) {
00613   return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0),
00614                      GetSoftenedFloat(N->getOperand(0)));
00615 }
00616 
00617 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
00618   MVT SVT = N->getOperand(0).getValueType();
00619   MVT RVT = N->getValueType(0);
00620 
00621   RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT);
00622   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");
00623 
00624   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00625   return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
00626 }
00627 
00628 SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
00629   SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
00630   ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
00631   SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
00632 
00633   // If SoftenSetCCOperands returned a scalar, we need to compare the result
00634   // against zero to select between true and false values.
00635   if (NewRHS.getNode() == 0) {
00636     NewRHS = DAG.getConstant(0, NewLHS.getValueType());
00637     CCCode = ISD::SETNE;
00638   }
00639 
00640   // Update N to have the operands specified.
00641   return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
00642                                 DAG.getCondCode(CCCode), NewLHS, NewRHS,
00643                                 N->getOperand(4));
00644 }
00645 
00646 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) {
00647   MVT RVT = N->getValueType(0);
00648   RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
00649   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
00650   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00651   return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
00652 }
00653 
00654 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) {
00655   MVT RVT = N->getValueType(0);
00656   RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
00657   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
00658   SDValue Op = GetSoftenedFloat(N->getOperand(0));
00659   return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
00660 }
00661 
00662 SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
00663   SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
00664   ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
00665   SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
00666 
00667   // If SoftenSetCCOperands returned a scalar, we need to compare the result
00668   // against zero to select between true and false values.
00669   if (NewRHS.getNode() == 0) {
00670     NewRHS = DAG.getConstant(0, NewLHS.getValueType());
00671     CCCode = ISD::SETNE;
00672   }
00673 
00674   // Update N to have the operands specified.
00675   return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
00676                                 N->getOperand(2), N->getOperand(3),
00677                                 DAG.getCondCode(CCCode));
00678 }
00679 
00680 SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) {
00681   SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
00682   ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
00683   SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
00684 
00685   // If SoftenSetCCOperands returned a scalar, use it.
00686   if (NewRHS.getNode() == 0) {
00687     assert(NewLHS.getValueType() == N->getValueType(0) &&
00688            "Unexpected setcc expansion!");
00689     return NewLHS;
00690   }
00691 
00692   // Otherwise, update N to have the operands specified.
00693   return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
00694                                 DAG.getCondCode(CCCode));
00695 }
00696 
00697 SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) {
00698   assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
00699   assert(OpNo == 1 && "Can only soften the stored value!");
00700   StoreSDNode *ST = cast<StoreSDNode>(N);
00701   SDValue Val = ST->getValue();
00702   DebugLoc dl = N->getDebugLoc();
00703 
00704   if (ST->isTruncatingStore())
00705     // Do an FP_ROUND followed by a non-truncating store.
00706     Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(),
00707                                           Val, DAG.getIntPtrConstant(0)));
00708   else
00709     Val = GetSoftenedFloat(Val);
00710 
00711   return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(),
00712                       ST->getSrcValue(), ST->getSrcValueOffset(),
00713                       ST->isVolatile(), ST->getAlignment());
00714 }
00715 
00716 
00717 //===----------------------------------------------------------------------===//
00718 //  Float Result Expansion
00719 //===----------------------------------------------------------------------===//
00720 
00721 /// ExpandFloatResult - This method is called when the specified result of the
00722 /// specified node is found to need expansion.  At this point, the node may also
00723 /// have invalid operands or may have other results that need promotion, we just
00724 /// know that (at least) one result needs expansion.
00725 void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
00726   DEBUG(cerr << "Expand float result: "; N->dump(&DAG); cerr << "\n");
00727   SDValue Lo, Hi;
00728   Lo = Hi = SDValue();
00729 
00730   // See if the target wants to custom expand this node.
00731   if (CustomLowerResults(N, N->getValueType(ResNo), true))
00732     return;
00733 
00734   switch (N->getOpcode()) {
00735   default:
00736 #ifndef NDEBUG
00737     cerr << "ExpandFloatResult #" << ResNo << ": ";
00738     N->dump(&DAG); cerr << "\n";
00739 #endif
00740     assert(0 && "Do not know how to expand the result of this operator!");
00741     abort();
00742 
00743   case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
00744   case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
00745   case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;
00746   case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
00747 
00748   case ISD::BIT_CONVERT:        ExpandRes_BIT_CONVERT(N, Lo, Hi); break;
00749   case ISD::BUILD_PAIR:         ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
00750   case ISD::EXTRACT_ELEMENT:    ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
00751   case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
00752   case ISD::VAARG:              ExpandRes_VAARG(N, Lo, Hi); break;
00753 
00754   case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break;
00755   case ISD::FABS:       ExpandFloatRes_FABS(N, Lo, Hi); break;
00756   case ISD::FADD:       ExpandFloatRes_FADD(N, Lo, Hi); break;
00757   case ISD::FCEIL:      ExpandFloatRes_FCEIL(N, Lo, Hi); break;
00758   case ISD::FCOS:       ExpandFloatRes_FCOS(N, Lo, Hi); break;
00759   case ISD::FDIV:       ExpandFloatRes_FDIV(N, Lo, Hi); break;
00760   case ISD::FEXP:       ExpandFloatRes_FEXP(N, Lo, Hi); break;
00761   case ISD::FEXP2:      ExpandFloatRes_FEXP2(N, Lo, Hi); break;
00762   case ISD::FFLOOR:     ExpandFloatRes_FFLOOR(N, Lo, Hi); break;
00763   case ISD::FLOG:       ExpandFloatRes_FLOG(N, Lo, Hi); break;
00764   case ISD::FLOG2:      ExpandFloatRes_FLOG2(N, Lo, Hi); break;
00765   case ISD::FLOG10:     ExpandFloatRes_FLOG10(N, Lo, Hi); break;
00766   case ISD::FMUL:       ExpandFloatRes_FMUL(N, Lo, Hi); break;
00767   case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break;
00768   case ISD::FNEG:       ExpandFloatRes_FNEG(N, Lo, Hi); break;
00769   case ISD::FP_EXTEND:  ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break;
00770   case ISD::FPOW:       ExpandFloatRes_FPOW(N, Lo, Hi); break;
00771   case ISD::FPOWI:      ExpandFloatRes_FPOWI(N, Lo, Hi); break;
00772   case ISD::FRINT:      ExpandFloatRes_FRINT(N, Lo, Hi); break;
00773   case ISD::FSIN:       ExpandFloatRes_FSIN(N, Lo, Hi); break;
00774   case ISD::FSQRT:      ExpandFloatRes_FSQRT(N, Lo, Hi); break;
00775   case ISD::FSUB:       ExpandFloatRes_FSUB(N, Lo, Hi); break;
00776   case ISD::FTRUNC:     ExpandFloatRes_FTRUNC(N, Lo, Hi); break;
00777   case ISD::LOAD:       ExpandFloatRes_LOAD(N, Lo, Hi); break;
00778   case ISD::SINT_TO_FP:
00779   case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break;
00780   }
00781 
00782   // If Lo/Hi is null, the sub-method took care of registering results etc.
00783   if (Lo.getNode())
00784     SetExpandedFloat(SDValue(N, ResNo), Lo, Hi);
00785 }
00786 
00787 void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo,
00788                                                  SDValue &Hi) {
00789   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00790   assert(NVT.getSizeInBits() == integerPartWidth &&
00791          "Do not know how to expand this float constant!");
00792   APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt();
00793   Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1,
00794                                        &C.getRawData()[1])), NVT);
00795   Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1,
00796                                        &C.getRawData()[0])), NVT);
00797 }
00798 
00799 void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo,
00800                                            SDValue &Hi) {
00801   assert(N->getValueType(0) == MVT::ppcf128 &&
00802          "Logic only correct for ppcf128!");
00803   DebugLoc dl = N->getDebugLoc();
00804   SDValue Tmp;
00805   GetExpandedFloat(N->getOperand(0), Lo, Tmp);
00806   Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp);
00807   // Lo = Hi==fabs(Hi) ? Lo : -Lo;
00808   Lo = DAG.getNode(ISD::SELECT_CC, dl, Lo.getValueType(), Tmp, Hi, Lo,
00809                    DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo),
00810                    DAG.getCondCode(ISD::SETEQ));
00811 }
00812 
00813 void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo,
00814                                            SDValue &Hi) {
00815   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00816                                          RTLIB::ADD_F32, RTLIB::ADD_F64,
00817                                          RTLIB::ADD_F80, RTLIB::ADD_PPCF128),
00818                             N, false);
00819   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00820          "Call lowered wrongly!");
00821   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00822 }
00823 
00824 void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N,
00825                                             SDValue &Lo, SDValue &Hi) {
00826   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00827                                          RTLIB::CEIL_F32, RTLIB::CEIL_F64,
00828                                          RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128),
00829                             N, false);
00830   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00831          "Call lowered wrongly!");
00832   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00833 }
00834 
00835 void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N,
00836                                            SDValue &Lo, SDValue &Hi) {
00837   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00838                                          RTLIB::COS_F32, RTLIB::COS_F64,
00839                                          RTLIB::COS_F80, RTLIB::COS_PPCF128),
00840                             N, false);
00841   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00842          "Call lowered wrongly!");
00843   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00844 }
00845 
00846 void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo,
00847                                            SDValue &Hi) {
00848   SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
00849   SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
00850                                           RTLIB::DIV_F32,
00851                                           RTLIB::DIV_F64,
00852                                           RTLIB::DIV_F80,
00853                                           RTLIB::DIV_PPCF128),
00854                              N->getValueType(0), Ops, 2, false,
00855                              N->getDebugLoc());
00856   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00857          "Call lowered wrongly!");
00858   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00859 }
00860 
00861 void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N,
00862                                            SDValue &Lo, SDValue &Hi) {
00863   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00864                                          RTLIB::EXP_F32, RTLIB::EXP_F64,
00865                                          RTLIB::EXP_F80, RTLIB::EXP_PPCF128),
00866                             N, false);
00867   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00868          "Call lowered wrongly!");
00869   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00870 }
00871 
00872 void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N,
00873                                             SDValue &Lo, SDValue &Hi) {
00874   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00875                                          RTLIB::EXP2_F32, RTLIB::EXP2_F64,
00876                                          RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128),
00877                             N, false);
00878   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00879          "Call lowered wrongly!");
00880   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00881 }
00882 
00883 void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N,
00884                                              SDValue &Lo, SDValue &Hi) {
00885   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00886                                          RTLIB::FLOOR_F32,RTLIB::FLOOR_F64,
00887                                          RTLIB::FLOOR_F80,RTLIB::FLOOR_PPCF128),
00888                             N, false);
00889   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00890          "Call lowered wrongly!");
00891   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00892 }
00893 
00894 void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N,
00895                                            SDValue &Lo, SDValue &Hi) {
00896   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00897                                          RTLIB::LOG_F32, RTLIB::LOG_F64,
00898                                          RTLIB::LOG_F80, RTLIB::LOG_PPCF128),
00899                             N, false);
00900   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00901          "Call lowered wrongly!");
00902   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00903 }
00904 
00905 void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N,
00906                                             SDValue &Lo, SDValue &Hi) {
00907   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00908                                          RTLIB::LOG2_F32, RTLIB::LOG2_F64,
00909                                          RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128),
00910                             N, false);
00911   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00912          "Call lowered wrongly!");
00913   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00914 }
00915 
00916 void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N,
00917                                              SDValue &Lo, SDValue &Hi) {
00918   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00919                                          RTLIB::LOG10_F32,RTLIB::LOG10_F64,
00920                                          RTLIB::LOG10_F80,RTLIB::LOG10_PPCF128),
00921                             N, false);
00922   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00923          "Call lowered wrongly!");
00924   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00925 }
00926 
00927 void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo,
00928                                            SDValue &Hi) {
00929   SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
00930   SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
00931                                           RTLIB::MUL_F32,
00932                                           RTLIB::MUL_F64,
00933                                           RTLIB::MUL_F80,
00934                                           RTLIB::MUL_PPCF128),
00935                              N->getValueType(0), Ops, 2, false,
00936                              N->getDebugLoc());
00937   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00938          "Call lowered wrongly!");
00939   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00940 }
00941 
00942 void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N,
00943                                                  SDValue &Lo, SDValue &Hi) {
00944   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00945                                          RTLIB::NEARBYINT_F32,
00946                                          RTLIB::NEARBYINT_F64,
00947                                          RTLIB::NEARBYINT_F80,
00948                                          RTLIB::NEARBYINT_PPCF128),
00949                             N, false);
00950   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00951          "Call lowered wrongly!");
00952   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00953 }
00954 
00955 void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo,
00956                                            SDValue &Hi) {
00957   DebugLoc dl = N->getDebugLoc();
00958   GetExpandedFloat(N->getOperand(0), Lo, Hi);
00959   Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo);
00960   Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi);
00961 }
00962 
00963 void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo,
00964                                                 SDValue &Hi) {
00965   MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
00966   Hi = DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), NVT, N->getOperand(0));
00967   Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
00968 }
00969 
00970 void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N,
00971                                            SDValue &Lo, SDValue &Hi) {
00972   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00973                                          RTLIB::POW_F32, RTLIB::POW_F64,
00974                                          RTLIB::POW_F80, RTLIB::POW_PPCF128),
00975                             N, false);
00976   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00977          "Call lowered wrongly!");
00978   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00979 }
00980 
00981 void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N,
00982                                             SDValue &Lo, SDValue &Hi) {
00983   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00984                                          RTLIB::POWI_F32, RTLIB::POWI_F64,
00985                                          RTLIB::POWI_F80, RTLIB::POWI_PPCF128),
00986                             N, false);
00987   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00988          "Call lowered wrongly!");
00989   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
00990 }
00991 
00992 void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N,
00993                                             SDValue &Lo, SDValue &Hi) {
00994   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
00995                                          RTLIB::RINT_F32, RTLIB::RINT_F64,
00996                                          RTLIB::RINT_F80, RTLIB::RINT_PPCF128),
00997                             N, false);
00998   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
00999          "Call lowered wrongly!");
01000   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
01001 }
01002 
01003 void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N,
01004                                            SDValue &Lo, SDValue &Hi) {
01005   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
01006                                          RTLIB::SIN_F32, RTLIB::SIN_F64,
01007                                          RTLIB::SIN_F80, RTLIB::SIN_PPCF128),
01008                             N, false);
01009   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
01010          "Call lowered wrongly!");
01011   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
01012 }
01013 
01014 void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N,
01015                                             SDValue &Lo, SDValue &Hi) {
01016   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
01017                                          RTLIB::SQRT_F32, RTLIB::SQRT_F64,
01018                                          RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128),
01019                             N, false);
01020   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
01021          "Call lowered wrongly!");
01022   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
01023 }
01024 
01025 void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo,
01026                                            SDValue &Hi) {
01027   SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
01028   SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
01029                                           RTLIB::SUB_F32,
01030                                           RTLIB::SUB_F64,
01031                                           RTLIB::SUB_F80,
01032                                           RTLIB::SUB_PPCF128),
01033                              N->getValueType(0), Ops, 2, false,
01034                              N->getDebugLoc());
01035   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
01036          "Call lowered wrongly!");
01037   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
01038 }
01039 
01040 void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N,
01041                                              SDValue &Lo, SDValue &Hi) {
01042   SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
01043                                          RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
01044                                          RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128),
01045                             N, false);
01046   assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
01047          "Call lowered wrongly!");
01048   Lo = Call.getOperand(0); Hi = Call.getOperand(1);
01049 }
01050 
01051 void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
01052                                            SDValue &Hi) {
01053   if (ISD::isNormalLoad(N)) {
01054     ExpandRes_NormalLoad(N, Lo, Hi);
01055     return;
01056   }
01057 
01058   assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
01059   LoadSDNode *LD = cast<LoadSDNode>(N);
01060   SDValue Chain = LD->getChain();
01061   SDValue Ptr = LD->getBasePtr();
01062   DebugLoc dl = N->getDebugLoc();
01063 
01064   MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0));
01065   assert(NVT.isByteSized() && "Expanded type not byte sized!");
01066   assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?");
01067 
01068   Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr,
01069                       LD->getSrcValue(), LD->getSrcValueOffset(),
01070                       LD->getMemoryVT(),
01071                       LD->isVolatile(), LD->getAlignment());
01072 
01073   // Remember the chain.
01074   Chain = Hi.getValue(1);
01075 
01076   // The low part is zero.
01077   Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
01078 
01079   // Modified the chain - switch anything that used the old chain to use the
01080   // new one.
01081   ReplaceValueWith(SDValue(LD, 1), Chain);
01082 }
01083 
01084 void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
01085                                                  SDValue &Hi) {
01086   assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!");
01087   MVT VT = N->getValueType(0);
01088   MVT NVT = TLI.getTypeToTransformTo(VT);
01089   SDValue Src = N->getOperand(0);
01090   MVT SrcVT = Src.getValueType();
01091   bool isSigned = N->getOpcode() == ISD::SINT_TO_FP;
01092   DebugLoc dl = N->getDebugLoc();
01093 
01094   // First do an SINT_TO_FP, whether the original was signed or unsigned.
01095   // When promoting partial word types to i32 we must honor the signedness,
01096   // though.
01097   if (SrcVT.bitsLE(MVT::i32)) {
01098     // The integer can be represented exactly in an f64.
01099     Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
01100                       MVT::i32, Src);
01101     Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
01102     Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src);
01103   } else {
01104     RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
01105     if (SrcVT.bitsLE(MVT::i64)) {
01106       Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
01107                         MVT::i64, Src);
01108       LC = RTLIB::SINTTOFP_I64_PPCF128;
01109     } else if (SrcVT.bitsLE(MVT::i128)) {
01110       Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i128, Src);
01111       LC = RTLIB::SINTTOFP_I128_PPCF128;
01112     }
01113     assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
01114 
01115     Hi = MakeLibCall(LC, VT, &Src, 1, true, dl);
01116     assert(Hi.getNode()->getOpcode() == ISD::BUILD_PAIR &&
01117            "Call lowered wrongly!");
01118     Lo = Hi.getOperand(0); Hi = Hi.getOperand(1);
01119   }
01120 
01121   if (isSigned)
01122     return;
01123 
01124   // Unsigned - fix up the SINT_TO_FP value just calculated.
01125   Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi);
01126   SrcVT = Src.getValueType();
01127 
01128   // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128.
01129   static const uint64_t TwoE32[]  = { 0x41f0000000000000LL, 0 };
01130   static const uint64_t TwoE64[]  = { 0x43f0000000000000LL, 0 };
01131   static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
01132   const uint64_t *Parts = 0;
01133 
01134   switch (SrcVT.getSimpleVT()) {
01135   default:
01136     assert(false && "Unsupported UINT_TO_FP!");
01137   case MVT::i32:
01138     Parts = TwoE32;
01139     break;
01140   case MVT::i64:
01141     Parts = TwoE64;
01142     break;
01143   case MVT::i128:
01144     Parts = TwoE128;
01145     break;
01146   }
01147 
01148   Lo = DAG.getNode(ISD::FADD, dl, VT, Hi,
01149                    DAG.getConstantFP(APFloat(APInt(128, 2, Parts)),
01150                                      MVT::ppcf128));
01151   Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT),
01152                    Lo, Hi, DAG.getCondCode(ISD::SETLT));
01153   Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(1));
01154   Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(0));
01155 }
01156 
01157 
01158 //===----------------------------------------------------------------------===//
01159 //  Float Operand Expansion
01160 //===----------------------------------------------------------------------===//
01161 
01162 /// ExpandFloatOperand - This method is called when the specified operand of the
01163 /// specified node is found to need expansion.  At this point, all of the result
01164 /// types of the node are known to be legal, but other operands of the node may
01165 /// need promotion or expansion as well as the specified one.
01166 bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
01167   DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n");
01168   SDValue Res = SDValue();
01169 
01170   if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
01171       == TargetLowering::Custom)
01172     Res = TLI.LowerOperation(SDValue(N, 0), DAG);
01173 
01174   if (Res.getNode() == 0) {
01175     switch (N->getOpcode()) {
01176     default:
01177   #ifndef NDEBUG
01178       cerr << "ExpandFloatOperand Op #" << OpNo << ": ";
01179       N->dump(&DAG); cerr << "\n";
01180   #endif
01181       assert(0 && "Do not know how to expand this operator's operand!");
01182       abort();
01183 
01184     case ISD::BIT_CONVERT:     Res = ExpandOp_BIT_CONVERT(N); break;
01185     case ISD::BUILD_VECTOR:    Res = ExpandOp_BUILD_VECTOR(N); break;
01186     case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
01187 
01188     case ISD::BR_CC:      Res = ExpandFloatOp_BR_CC(N); break;
01189     case ISD::FP_ROUND:   Res = ExpandFloatOp_FP_ROUND(N); break;
01190     case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break;
01191     case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break;
01192     case ISD::SELECT_CC:  Res = ExpandFloatOp_SELECT_CC(N); break;
01193     case ISD::SETCC:      Res = ExpandFloatOp_SETCC(N); break;
01194     case ISD::STORE:      Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N),
01195                                                     OpNo); break;
01196     }
01197   }
01198 
01199   // If the result is null, the sub-method took care of registering results etc.
01200   if (!Res.getNode()) return false;
01201 
01202   // If the result is N, the sub-method updated N in place.  Tell the legalizer
01203   // core about this.
01204   if (Res.getNode() == N)
01205     return true;
01206 
01207   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
01208          "Invalid operand expansion");
01209 
01210   ReplaceValueWith(SDValue(N, 0), Res);
01211   return false;
01212 }
01213 
01214 /// FloatExpandSetCCOperands - Expand the operands of a comparison.  This code
01215 /// is shared among BR_CC, SELECT_CC, and SETCC handlers.
01216 void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
01217                                                 SDValue &NewRHS,
01218                                                 ISD::CondCode &CCCode,
01219                                                 DebugLoc dl) {
01220   SDValue LHSLo, LHSHi, RHSLo, RHSHi;
01221   GetExpandedFloat(NewLHS, LHSLo, LHSHi);
01222   GetExpandedFloat(NewRHS, RHSLo, RHSHi);
01223 
01224   MVT VT = NewLHS.getValueType();
01225   assert(VT == MVT::ppcf128 && "Unsupported setcc type!");
01226 
01227   // FIXME:  This generated code sucks.  We want to generate
01228   //         FCMPU crN, hi1, hi2
01229   //         BNE crN, L:
01230   //         FCMPU crN, lo1, lo2
01231   // The following can be improved, but not that much.
01232   SDValue Tmp1, Tmp2, Tmp3;
01233   Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
01234                       LHSHi, RHSHi, ISD::SETOEQ);
01235   Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()),
01236                       LHSLo, RHSLo, CCCode);
01237   Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
01238   Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
01239                       LHSHi, RHSHi, ISD::SETUNE);
01240   Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
01241                       LHSHi, RHSHi, CCCode);
01242   Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
01243   NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3);
01244   NewRHS = SDValue();   // LHS is the result, not a compare.
01245 }
01246 
01247 SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) {
01248   SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
01249   ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
01250   FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
01251 
01252   // If ExpandSetCCOperands returned a scalar, we need to compare the result
01253   // against zero to select between true and false values.
01254   if (NewRHS.getNode() == 0) {
01255     NewRHS = DAG.getConstant(0, NewLHS.getValueType());
01256     CCCode = ISD::SETNE;
01257   }
01258 
01259   // Update N to have the operands specified.
01260   return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
01261                                 DAG.getCondCode(CCCode), NewLHS, NewRHS,
01262                                 N->getOperand(4));
01263 }
01264 
01265 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) {
01266   assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
01267          "Logic only correct for ppcf128!");
01268   SDValue Lo, Hi;
01269   GetExpandedFloat(N->getOperand(0), Lo, Hi);
01270   // Round it the rest of the way (e.g. to f32) if needed.
01271   return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(),
01272                      N->getValueType(0), Hi, N->getOperand(1));
01273 }
01274 
01275 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) {
01276   MVT RVT = N->getValueType(0);
01277   DebugLoc dl = N->getDebugLoc();
01278 
01279   // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
01280   // PPC (the libcall is not available).  FIXME: Do this in a less hacky way.
01281   if (RVT == MVT::i32) {
01282     assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
01283            "Logic only correct for ppcf128!");
01284     SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128,
01285                               N->getOperand(0), DAG.getValueType(MVT::f64));
01286     Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res,
01287                       DAG.getIntPtrConstant(1));
01288     return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res);
01289   }
01290 
01291   RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
01292   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
01293   return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false, dl);
01294 }
01295 
01296 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) {
01297   MVT RVT = N->getValueType(0);
01298   DebugLoc dl = N->getDebugLoc();
01299 
01300   // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
01301   // PPC (the libcall is not available).  FIXME: Do this in a less hacky way.
01302   if (RVT == MVT::i32) {
01303     assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
01304            "Logic only correct for ppcf128!");
01305     const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
01306     APFloat APF = APFloat(APInt(128, 2, TwoE31));
01307     SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128);
01308     //  X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
01309     // FIXME: generated code sucks.
01310     return DAG.getNode(ISD::SELECT_CC, dl, MVT::i32, N->getOperand(0), Tmp,
01311                        DAG.getNode(ISD::ADD, dl, MVT::i32,
01312                                    DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32,
01313                                                DAG.getNode(ISD::FSUB, dl,
01314                                                            MVT::ppcf128,
01315                                                            N->getOperand(0),
01316                                                            Tmp)),
01317                                    DAG.getConstant(0x80000000, MVT::i32)),
01318                        DAG.getNode(ISD::FP_TO_SINT, dl,
01319                                    MVT::i32, N->getOperand(0)),
01320                        DAG.getCondCode(ISD::SETGE));
01321   }
01322 
01323   RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
01324   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
01325   return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false, dl);
01326 }
01327 
01328 SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
01329   SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
01330   ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
01331   FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
01332 
01333   // If ExpandSetCCOperands returned a scalar, we need to compare the result
01334   // against zero to select between true and false values.
01335   if (NewRHS.getNode() == 0) {
01336     NewRHS = DAG.getConstant(0, NewLHS.getValueType());
01337     CCCode = ISD::SETNE;
01338   }
01339 
01340   // Update N to have the operands specified.
01341   return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
01342                                 N->getOperand(2), N->getOperand(3),
01343                                 DAG.getCondCode(CCCode));
01344 }
01345 
01346 SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) {
01347   SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
01348   ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
01349   FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
01350 
01351   // If ExpandSetCCOperands returned a scalar, use it.
01352   if (NewRHS.getNode() == 0) {
01353     assert(NewLHS.getValueType() == N->getValueType(0) &&
01354            "Unexpected setcc expansion!");
01355     return NewLHS;
01356   }
01357 
01358   // Otherwise, update N to have the operands specified.
01359   return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
01360                                 DAG.getCondCode(CCCode));
01361 }
01362 
01363 SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
01364   if (ISD::isNormalStore(N))
01365     return ExpandOp_NormalStore(N, OpNo);
01366 
01367   assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
01368   assert(OpNo == 1 && "Can only expand the stored value so far");
01369   StoreSDNode *ST = cast<StoreSDNode>(N);
01370 
01371   SDValue Chain = ST->getChain();
01372   SDValue Ptr = ST->getBasePtr();
01373 
01374   MVT NVT = TLI.getTypeToTransformTo(ST->getValue().getValueType());
01375   assert(NVT.isByteSized() && "Expanded type not byte sized!");
01376   assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?");
01377 
01378   SDValue Lo, Hi;
01379   GetExpandedOp(ST->getValue(), Lo, Hi);
01380 
01381   return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr,
01382                            ST->getSrcValue(), ST->getSrcValueOffset(),
01383                            ST->getMemoryVT(),
01384                            ST->isVolatile(), ST->getAlignment());
01385 }