LLVM API Documentation

Mips16ISelLowering.cpp
Go to the documentation of this file.
00001 //===-- Mips16ISelLowering.h - Mips16 DAG Lowering Interface ----*- C++ -*-===//
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 // Subclass of MipsTargetLowering specialized for mips16.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 #include "Mips16ISelLowering.h"
00014 #include "MCTargetDesc/MipsBaseInfo.h"
00015 #include "Mips16HardFloatInfo.h"
00016 #include "MipsMachineFunction.h"
00017 #include "MipsRegisterInfo.h"
00018 #include "MipsTargetMachine.h"
00019 #include "llvm/ADT/StringRef.h"
00020 #include "llvm/CodeGen/MachineInstrBuilder.h"
00021 #include "llvm/Support/CommandLine.h"
00022 #include "llvm/Target/TargetInstrInfo.h"
00023 #include <string>
00024 
00025 using namespace llvm;
00026 
00027 #define DEBUG_TYPE "mips-lower"
00028 
00029 static cl::opt<bool> DontExpandCondPseudos16(
00030   "mips16-dont-expand-cond-pseudo",
00031   cl::init(false),
00032   cl::desc("Don't expand conditional move related "
00033            "pseudos for Mips 16"),
00034   cl::Hidden);
00035 
00036 namespace {
00037 struct Mips16Libcall {
00038   RTLIB::Libcall Libcall;
00039   const char *Name;
00040 
00041   bool operator<(const Mips16Libcall &RHS) const {
00042     return std::strcmp(Name, RHS.Name) < 0;
00043   }
00044 };
00045 
00046 struct Mips16IntrinsicHelperType{
00047   const char* Name;
00048   const char* Helper;
00049 
00050   bool operator<(const Mips16IntrinsicHelperType &RHS) const {
00051     return std::strcmp(Name, RHS.Name) < 0;
00052   }
00053   bool operator==(const Mips16IntrinsicHelperType &RHS) const {
00054     return std::strcmp(Name, RHS.Name) == 0;
00055   }
00056 };
00057 }
00058 
00059 // Libcalls for which no helper is generated. Sorted by name for binary search.
00060 static const Mips16Libcall HardFloatLibCalls[] = {
00061   { RTLIB::ADD_F64, "__mips16_adddf3" },
00062   { RTLIB::ADD_F32, "__mips16_addsf3" },
00063   { RTLIB::DIV_F64, "__mips16_divdf3" },
00064   { RTLIB::DIV_F32, "__mips16_divsf3" },
00065   { RTLIB::OEQ_F64, "__mips16_eqdf2" },
00066   { RTLIB::OEQ_F32, "__mips16_eqsf2" },
00067   { RTLIB::FPEXT_F32_F64, "__mips16_extendsfdf2" },
00068   { RTLIB::FPTOSINT_F64_I32, "__mips16_fix_truncdfsi" },
00069   { RTLIB::FPTOSINT_F32_I32, "__mips16_fix_truncsfsi" },
00070   { RTLIB::SINTTOFP_I32_F64, "__mips16_floatsidf" },
00071   { RTLIB::SINTTOFP_I32_F32, "__mips16_floatsisf" },
00072   { RTLIB::UINTTOFP_I32_F64, "__mips16_floatunsidf" },
00073   { RTLIB::UINTTOFP_I32_F32, "__mips16_floatunsisf" },
00074   { RTLIB::OGE_F64, "__mips16_gedf2" },
00075   { RTLIB::OGE_F32, "__mips16_gesf2" },
00076   { RTLIB::OGT_F64, "__mips16_gtdf2" },
00077   { RTLIB::OGT_F32, "__mips16_gtsf2" },
00078   { RTLIB::OLE_F64, "__mips16_ledf2" },
00079   { RTLIB::OLE_F32, "__mips16_lesf2" },
00080   { RTLIB::OLT_F64, "__mips16_ltdf2" },
00081   { RTLIB::OLT_F32, "__mips16_ltsf2" },
00082   { RTLIB::MUL_F64, "__mips16_muldf3" },
00083   { RTLIB::MUL_F32, "__mips16_mulsf3" },
00084   { RTLIB::UNE_F64, "__mips16_nedf2" },
00085   { RTLIB::UNE_F32, "__mips16_nesf2" },
00086   { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_dc" }, // No associated libcall.
00087   { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_df" }, // No associated libcall.
00088   { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sc" }, // No associated libcall.
00089   { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sf" }, // No associated libcall.
00090   { RTLIB::SUB_F64, "__mips16_subdf3" },
00091   { RTLIB::SUB_F32, "__mips16_subsf3" },
00092   { RTLIB::FPROUND_F64_F32, "__mips16_truncdfsf2" },
00093   { RTLIB::UO_F64, "__mips16_unorddf2" },
00094   { RTLIB::UO_F32, "__mips16_unordsf2" }
00095 };
00096 
00097 static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = {
00098   {"__fixunsdfsi", "__mips16_call_stub_2" },
00099   {"ceil",  "__mips16_call_stub_df_2"},
00100   {"ceilf", "__mips16_call_stub_sf_1"},
00101   {"copysign",  "__mips16_call_stub_df_10"},
00102   {"copysignf", "__mips16_call_stub_sf_5"},
00103   {"cos",  "__mips16_call_stub_df_2"},
00104   {"cosf", "__mips16_call_stub_sf_1"},
00105   {"exp2",  "__mips16_call_stub_df_2"},
00106   {"exp2f", "__mips16_call_stub_sf_1"},
00107   {"floor",  "__mips16_call_stub_df_2"},
00108   {"floorf", "__mips16_call_stub_sf_1"},
00109   {"log2",  "__mips16_call_stub_df_2"},
00110   {"log2f", "__mips16_call_stub_sf_1"},
00111   {"nearbyint",  "__mips16_call_stub_df_2"},
00112   {"nearbyintf", "__mips16_call_stub_sf_1"},
00113   {"rint",  "__mips16_call_stub_df_2"},
00114   {"rintf", "__mips16_call_stub_sf_1"},
00115   {"sin",  "__mips16_call_stub_df_2"},
00116   {"sinf", "__mips16_call_stub_sf_1"},
00117   {"sqrt",  "__mips16_call_stub_df_2"},
00118   {"sqrtf", "__mips16_call_stub_sf_1"},
00119   {"trunc",  "__mips16_call_stub_df_2"},
00120   {"truncf", "__mips16_call_stub_sf_1"},
00121 };
00122 
00123 Mips16TargetLowering::Mips16TargetLowering(MipsTargetMachine &TM,
00124                                            const MipsSubtarget &STI)
00125     : MipsTargetLowering(TM, STI) {
00126 
00127   // Set up the register classes
00128   addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
00129 
00130   if (!TM.Options.UseSoftFloat)
00131     setMips16HardFloatLibCalls();
00132 
00133   setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Expand);
00134   setOperationAction(ISD::ATOMIC_CMP_SWAP,    MVT::i32,   Expand);
00135   setOperationAction(ISD::ATOMIC_SWAP,        MVT::i32,   Expand);
00136   setOperationAction(ISD::ATOMIC_LOAD_ADD,    MVT::i32,   Expand);
00137   setOperationAction(ISD::ATOMIC_LOAD_SUB,    MVT::i32,   Expand);
00138   setOperationAction(ISD::ATOMIC_LOAD_AND,    MVT::i32,   Expand);
00139   setOperationAction(ISD::ATOMIC_LOAD_OR,     MVT::i32,   Expand);
00140   setOperationAction(ISD::ATOMIC_LOAD_XOR,    MVT::i32,   Expand);
00141   setOperationAction(ISD::ATOMIC_LOAD_NAND,   MVT::i32,   Expand);
00142   setOperationAction(ISD::ATOMIC_LOAD_MIN,    MVT::i32,   Expand);
00143   setOperationAction(ISD::ATOMIC_LOAD_MAX,    MVT::i32,   Expand);
00144   setOperationAction(ISD::ATOMIC_LOAD_UMIN,   MVT::i32,   Expand);
00145   setOperationAction(ISD::ATOMIC_LOAD_UMAX,   MVT::i32,   Expand);
00146 
00147   setOperationAction(ISD::ROTR, MVT::i32,  Expand);
00148   setOperationAction(ISD::ROTR, MVT::i64,  Expand);
00149   setOperationAction(ISD::BSWAP, MVT::i32, Expand);
00150   setOperationAction(ISD::BSWAP, MVT::i64, Expand);
00151 
00152   computeRegisterProperties();
00153 }
00154 
00155 const MipsTargetLowering *
00156 llvm::createMips16TargetLowering(MipsTargetMachine &TM,
00157                                  const MipsSubtarget &STI) {
00158   return new Mips16TargetLowering(TM, STI);
00159 }
00160 
00161 bool
00162 Mips16TargetLowering::allowsMisalignedMemoryAccesses(EVT VT,
00163                                                      unsigned,
00164                                                      unsigned,
00165                                                      bool *Fast) const {
00166   return false;
00167 }
00168 
00169 MachineBasicBlock *
00170 Mips16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
00171                                                   MachineBasicBlock *BB) const {
00172   switch (MI->getOpcode()) {
00173   default:
00174     return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
00175   case Mips::SelBeqZ:
00176     return emitSel16(Mips::BeqzRxImm16, MI, BB);
00177   case Mips::SelBneZ:
00178     return emitSel16(Mips::BnezRxImm16, MI, BB);
00179   case Mips::SelTBteqZCmpi:
00180     return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);
00181   case Mips::SelTBteqZSlti:
00182     return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);
00183   case Mips::SelTBteqZSltiu:
00184     return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);
00185   case Mips::SelTBtneZCmpi:
00186     return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);
00187   case Mips::SelTBtneZSlti:
00188     return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);
00189   case Mips::SelTBtneZSltiu:
00190     return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);
00191   case Mips::SelTBteqZCmp:
00192     return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
00193   case Mips::SelTBteqZSlt:
00194     return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
00195   case Mips::SelTBteqZSltu:
00196     return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
00197   case Mips::SelTBtneZCmp:
00198     return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
00199   case Mips::SelTBtneZSlt:
00200     return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
00201   case Mips::SelTBtneZSltu:
00202     return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
00203   case Mips::BteqzT8CmpX16:
00204     return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
00205   case Mips::BteqzT8SltX16:
00206     return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
00207   case Mips::BteqzT8SltuX16:
00208     // TBD: figure out a way to get this or remove the instruction
00209     // altogether.
00210     return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
00211   case Mips::BtnezT8CmpX16:
00212     return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
00213   case Mips::BtnezT8SltX16:
00214     return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
00215   case Mips::BtnezT8SltuX16:
00216     // TBD: figure out a way to get this or remove the instruction
00217     // altogether.
00218     return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
00219   case Mips::BteqzT8CmpiX16: return emitFEXT_T8I8I16_ins(
00220     Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
00221   case Mips::BteqzT8SltiX16: return emitFEXT_T8I8I16_ins(
00222     Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
00223   case Mips::BteqzT8SltiuX16: return emitFEXT_T8I8I16_ins(
00224     Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
00225   case Mips::BtnezT8CmpiX16: return emitFEXT_T8I8I16_ins(
00226     Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
00227   case Mips::BtnezT8SltiX16: return emitFEXT_T8I8I16_ins(
00228     Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
00229   case Mips::BtnezT8SltiuX16: return emitFEXT_T8I8I16_ins(
00230     Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
00231     break;
00232   case Mips::SltCCRxRy16:
00233     return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
00234     break;
00235   case Mips::SltiCCRxImmX16:
00236     return emitFEXT_CCRXI16_ins
00237       (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);
00238   case Mips::SltiuCCRxImmX16:
00239     return emitFEXT_CCRXI16_ins
00240       (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);
00241   case Mips::SltuCCRxRy16:
00242     return emitFEXT_CCRX16_ins
00243       (Mips::SltuRxRy16, MI, BB);
00244   }
00245 }
00246 
00247 bool Mips16TargetLowering::
00248 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
00249                                   unsigned NextStackOffset,
00250                                   const MipsFunctionInfo& FI) const {
00251   // No tail call optimization for mips16.
00252   return false;
00253 }
00254 
00255 void Mips16TargetLowering::setMips16HardFloatLibCalls() {
00256   for (unsigned I = 0; I != array_lengthof(HardFloatLibCalls); ++I) {
00257     assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) &&
00258            "Array not sorted!");
00259     if (HardFloatLibCalls[I].Libcall != RTLIB::UNKNOWN_LIBCALL)
00260       setLibcallName(HardFloatLibCalls[I].Libcall, HardFloatLibCalls[I].Name);
00261   }
00262 
00263   setLibcallName(RTLIB::O_F64, "__mips16_unorddf2");
00264   setLibcallName(RTLIB::O_F32, "__mips16_unordsf2");
00265 }
00266 
00267 //
00268 // The Mips16 hard float is a crazy quilt inherited from gcc. I have a much
00269 // cleaner way to do all of this but it will have to wait until the traditional
00270 // gcc mechanism is completed.
00271 //
00272 // For Pic, in order for Mips16 code to call Mips32 code which according the abi
00273 // have either arguments or returned values placed in floating point registers,
00274 // we use a set of helper functions. (This includes functions which return type
00275 //  complex which on Mips are returned in a pair of floating point registers).
00276 //
00277 // This is an encoding that we inherited from gcc.
00278 // In Mips traditional O32, N32 ABI, floating point numbers are passed in
00279 // floating point argument registers 1,2 only when the first and optionally
00280 // the second arguments are float (sf) or double (df).
00281 // For Mips16 we are only concerned with the situations where floating point
00282 // arguments are being passed in floating point registers by the ABI, because
00283 // Mips16 mode code cannot execute floating point instructions to load those
00284 // values and hence helper functions are needed.
00285 // The possibilities are (), (sf), (sf, sf), (sf, df), (df), (df, sf), (df, df)
00286 // the helper function suffixs for these are:
00287 //                        0,  1,    5,        9,         2,   6,        10
00288 // this suffix can then be calculated as follows:
00289 // for a given argument Arg:
00290 //     Arg1x, Arg2x = 1 :  Arg is sf
00291 //                    2 :  Arg is df
00292 //                    0:   Arg is neither sf or df
00293 // So this stub is the string for number Arg1x + Arg2x*4.
00294 // However not all numbers between 0 and 10 are possible, we check anyway and
00295 // assert if the impossible exists.
00296 //
00297 
00298 unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
00299   (ArgListTy &Args) const {
00300   unsigned int resultNum = 0;
00301   if (Args.size() >= 1) {
00302     Type *t = Args[0].Ty;
00303     if (t->isFloatTy()) {
00304       resultNum = 1;
00305     }
00306     else if (t->isDoubleTy()) {
00307       resultNum = 2;
00308     }
00309   }
00310   if (resultNum) {
00311     if (Args.size() >=2) {
00312       Type *t = Args[1].Ty;
00313       if (t->isFloatTy()) {
00314         resultNum += 4;
00315       }
00316       else if (t->isDoubleTy()) {
00317         resultNum += 8;
00318       }
00319     }
00320   }
00321   return resultNum;
00322 }
00323 
00324 //
00325 // prefixs are attached to stub numbers depending on the return type .
00326 // return type: float  sf_
00327 //              double df_
00328 //              single complex sc_
00329 //              double complext dc_
00330 //              others  NO PREFIX
00331 //
00332 //
00333 // The full name of a helper function is__mips16_call_stub +
00334 //    return type dependent prefix + stub number
00335 //
00336 //
00337 // This is something that probably should be in a different source file and
00338 // perhaps done differently but my main purpose is to not waste runtime
00339 // on something that we can enumerate in the source. Another possibility is
00340 // to have a python script to generate these mapping tables. This will do
00341 // for now. There are a whole series of helper function mapping arrays, one
00342 // for each return type class as outlined above. There there are 11 possible
00343 //  entries. Ones with 0 are ones which should never be selected
00344 //
00345 // All the arrays are similar except for ones which return neither
00346 // sf, df, sc, dc, in which only care about ones which have sf or df as a
00347 // first parameter.
00348 //
00349 #define P_ "__mips16_call_stub_"
00350 #define MAX_STUB_NUMBER 10
00351 #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
00352 #define T P "0" , T1
00353 #define P P_
00354 static char const * vMips16Helper[MAX_STUB_NUMBER+1] =
00355   {nullptr, T1 };
00356 #undef P
00357 #define P P_ "sf_"
00358 static char const * sfMips16Helper[MAX_STUB_NUMBER+1] =
00359   { T };
00360 #undef P
00361 #define P P_ "df_"
00362 static char const * dfMips16Helper[MAX_STUB_NUMBER+1] =
00363   { T };
00364 #undef P
00365 #define P P_ "sc_"
00366 static char const * scMips16Helper[MAX_STUB_NUMBER+1] =
00367   { T };
00368 #undef P
00369 #define P P_ "dc_"
00370 static char const * dcMips16Helper[MAX_STUB_NUMBER+1] =
00371   { T };
00372 #undef P
00373 #undef P_
00374 
00375 
00376 const char* Mips16TargetLowering::
00377   getMips16HelperFunction
00378     (Type* RetTy, ArgListTy &Args, bool &needHelper) const {
00379   const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
00380 #ifndef NDEBUG
00381   const unsigned int maxStubNum = 10;
00382   assert(stubNum <= maxStubNum);
00383   const bool validStubNum[maxStubNum+1] =
00384     {true, true, true, false, false, true, true, false, false, true, true};
00385   assert(validStubNum[stubNum]);
00386 #endif
00387   const char *result;
00388   if (RetTy->isFloatTy()) {
00389     result = sfMips16Helper[stubNum];
00390   }
00391   else if (RetTy ->isDoubleTy()) {
00392     result = dfMips16Helper[stubNum];
00393   }
00394   else if (RetTy->isStructTy()) {
00395     // check if it's complex
00396     if (RetTy->getNumContainedTypes() == 2) {
00397       if ((RetTy->getContainedType(0)->isFloatTy()) &&
00398           (RetTy->getContainedType(1)->isFloatTy())) {
00399         result = scMips16Helper[stubNum];
00400       }
00401       else if ((RetTy->getContainedType(0)->isDoubleTy()) &&
00402                (RetTy->getContainedType(1)->isDoubleTy())) {
00403         result = dcMips16Helper[stubNum];
00404       }
00405       else {
00406         llvm_unreachable("Uncovered condition");
00407       }
00408     }
00409     else {
00410       llvm_unreachable("Uncovered condition");
00411     }
00412   }
00413   else {
00414     if (stubNum == 0) {
00415       needHelper = false;
00416       return "";
00417     }
00418     result = vMips16Helper[stubNum];
00419   }
00420   needHelper = true;
00421   return result;
00422 }
00423 
00424 void Mips16TargetLowering::
00425 getOpndList(SmallVectorImpl<SDValue> &Ops,
00426             std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
00427             bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
00428             CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
00429   SelectionDAG &DAG = CLI.DAG;
00430   MachineFunction &MF = DAG.getMachineFunction();
00431   MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
00432   const char* Mips16HelperFunction = nullptr;
00433   bool NeedMips16Helper = false;
00434 
00435   if (Subtarget.inMips16HardFloat()) {
00436     //
00437     // currently we don't have symbols tagged with the mips16 or mips32
00438     // qualifier so we will assume that we don't know what kind it is.
00439     // and generate the helper
00440     //
00441     bool LookupHelper = true;
00442     if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
00443       Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() };
00444 
00445       if (std::binary_search(std::begin(HardFloatLibCalls),
00446                              std::end(HardFloatLibCalls), Find))
00447         LookupHelper = false;
00448       else {
00449         const char *Symbol = S->getSymbol();
00450         Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };
00451         const Mips16HardFloatInfo::FuncSignature *Signature =
00452             Mips16HardFloatInfo::findFuncSignature(Symbol);
00453         if (!IsPICCall && (Signature && (FuncInfo->StubsNeeded.find(Symbol) ==
00454                                          FuncInfo->StubsNeeded.end()))) {
00455           FuncInfo->StubsNeeded[Symbol] = Signature;
00456           //
00457           // S2 is normally saved if the stub is for a function which
00458           // returns a float or double value and is not otherwise. This is
00459           // because more work is required after the function the stub
00460           // is calling completes, and so the stub cannot directly return
00461           // and the stub has no stack space to store the return address so
00462           // S2 is used for that purpose.
00463           // In order to take advantage of not saving S2, we need to also
00464           // optimize the call in the stub and this requires some further
00465           // functionality in MipsAsmPrinter which we don't have yet.
00466           // So for now we always save S2. The optimization will be done
00467           // in a follow-on patch.
00468           //
00469           if (1 || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet))
00470             FuncInfo->setSaveS2();
00471         }
00472         // one more look at list of intrinsics
00473         const Mips16IntrinsicHelperType *Helper =
00474             std::lower_bound(std::begin(Mips16IntrinsicHelper),
00475                              std::end(Mips16IntrinsicHelper), IntrinsicFind);
00476         if (Helper != std::end(Mips16IntrinsicHelper) &&
00477             *Helper == IntrinsicFind) {
00478           Mips16HelperFunction = Helper->Helper;
00479           NeedMips16Helper = true;
00480           LookupHelper = false;
00481         }
00482 
00483       }
00484     } else if (GlobalAddressSDNode *G =
00485                    dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
00486       Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL,
00487                              G->getGlobal()->getName().data() };
00488 
00489       if (std::binary_search(std::begin(HardFloatLibCalls),
00490                              std::end(HardFloatLibCalls), Find))
00491         LookupHelper = false;
00492     }
00493     if (LookupHelper)
00494       Mips16HelperFunction =
00495         getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
00496   }
00497 
00498   SDValue JumpTarget = Callee;
00499 
00500   // T9 should contain the address of the callee function if
00501   // -reloction-model=pic or it is an indirect call.
00502   if (IsPICCall || !GlobalOrExternal) {
00503     unsigned V0Reg = Mips::V0;
00504     if (NeedMips16Helper) {
00505       RegsToPass.push_front(std::make_pair(V0Reg, Callee));
00506       JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, getPointerTy());
00507       ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);
00508       JumpTarget = getAddrGlobal(S, JumpTarget.getValueType(), DAG,
00509                                  MipsII::MO_GOT, Chain,
00510                                  FuncInfo->callPtrInfo(S->getSymbol()));
00511     } else
00512       RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
00513   }
00514 
00515   Ops.push_back(JumpTarget);
00516 
00517   MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
00518                                   InternalLinkage, CLI, Callee, Chain);
00519 }
00520 
00521 MachineBasicBlock *Mips16TargetLowering::
00522 emitSel16(unsigned Opc, MachineInstr *MI, MachineBasicBlock *BB) const {
00523   if (DontExpandCondPseudos16)
00524     return BB;
00525   const TargetInstrInfo *TII =
00526       getTargetMachine().getSubtargetImpl()->getInstrInfo();
00527   DebugLoc DL = MI->getDebugLoc();
00528   // To "insert" a SELECT_CC instruction, we actually have to insert the
00529   // diamond control-flow pattern.  The incoming instruction knows the
00530   // destination vreg to set, the condition code register to branch on, the
00531   // true/false values to select between, and a branch opcode to use.
00532   const BasicBlock *LLVM_BB = BB->getBasicBlock();
00533   MachineFunction::iterator It = BB;
00534   ++It;
00535 
00536   //  thisMBB:
00537   //  ...
00538   //   TrueVal = ...
00539   //   setcc r1, r2, r3
00540   //   bNE   r1, r0, copy1MBB
00541   //   fallthrough --> copy0MBB
00542   MachineBasicBlock *thisMBB  = BB;
00543   MachineFunction *F = BB->getParent();
00544   MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
00545   MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB);
00546   F->insert(It, copy0MBB);
00547   F->insert(It, sinkMBB);
00548 
00549   // Transfer the remainder of BB and its successor edges to sinkMBB.
00550   sinkMBB->splice(sinkMBB->begin(), BB,
00551                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
00552   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
00553 
00554   // Next, add the true and fallthrough blocks as its successors.
00555   BB->addSuccessor(copy0MBB);
00556   BB->addSuccessor(sinkMBB);
00557 
00558   BuildMI(BB, DL, TII->get(Opc)).addReg(MI->getOperand(3).getReg())
00559     .addMBB(sinkMBB);
00560 
00561   //  copy0MBB:
00562   //   %FalseValue = ...
00563   //   # fallthrough to sinkMBB
00564   BB = copy0MBB;
00565 
00566   // Update machine-CFG edges
00567   BB->addSuccessor(sinkMBB);
00568 
00569   //  sinkMBB:
00570   //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
00571   //  ...
00572   BB = sinkMBB;
00573 
00574   BuildMI(*BB, BB->begin(), DL,
00575           TII->get(Mips::PHI), MI->getOperand(0).getReg())
00576     .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB)
00577     .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB);
00578 
00579   MI->eraseFromParent();   // The pseudo instruction is gone now.
00580   return BB;
00581 }
00582 
00583 MachineBasicBlock *Mips16TargetLowering::emitSelT16
00584   (unsigned Opc1, unsigned Opc2,
00585    MachineInstr *MI, MachineBasicBlock *BB) const {
00586   if (DontExpandCondPseudos16)
00587     return BB;
00588   const TargetInstrInfo *TII =
00589       getTargetMachine().getSubtargetImpl()->getInstrInfo();
00590   DebugLoc DL = MI->getDebugLoc();
00591   // To "insert" a SELECT_CC instruction, we actually have to insert the
00592   // diamond control-flow pattern.  The incoming instruction knows the
00593   // destination vreg to set, the condition code register to branch on, the
00594   // true/false values to select between, and a branch opcode to use.
00595   const BasicBlock *LLVM_BB = BB->getBasicBlock();
00596   MachineFunction::iterator It = BB;
00597   ++It;
00598 
00599   //  thisMBB:
00600   //  ...
00601   //   TrueVal = ...
00602   //   setcc r1, r2, r3
00603   //   bNE   r1, r0, copy1MBB
00604   //   fallthrough --> copy0MBB
00605   MachineBasicBlock *thisMBB  = BB;
00606   MachineFunction *F = BB->getParent();
00607   MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
00608   MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB);
00609   F->insert(It, copy0MBB);
00610   F->insert(It, sinkMBB);
00611 
00612   // Transfer the remainder of BB and its successor edges to sinkMBB.
00613   sinkMBB->splice(sinkMBB->begin(), BB,
00614                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
00615   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
00616 
00617   // Next, add the true and fallthrough blocks as its successors.
00618   BB->addSuccessor(copy0MBB);
00619   BB->addSuccessor(sinkMBB);
00620 
00621   BuildMI(BB, DL, TII->get(Opc2)).addReg(MI->getOperand(3).getReg())
00622     .addReg(MI->getOperand(4).getReg());
00623   BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
00624 
00625   //  copy0MBB:
00626   //   %FalseValue = ...
00627   //   # fallthrough to sinkMBB
00628   BB = copy0MBB;
00629 
00630   // Update machine-CFG edges
00631   BB->addSuccessor(sinkMBB);
00632 
00633   //  sinkMBB:
00634   //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
00635   //  ...
00636   BB = sinkMBB;
00637 
00638   BuildMI(*BB, BB->begin(), DL,
00639           TII->get(Mips::PHI), MI->getOperand(0).getReg())
00640     .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB)
00641     .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB);
00642 
00643   MI->eraseFromParent();   // The pseudo instruction is gone now.
00644   return BB;
00645 
00646 }
00647 
00648 MachineBasicBlock *Mips16TargetLowering::emitSeliT16
00649   (unsigned Opc1, unsigned Opc2,
00650    MachineInstr *MI, MachineBasicBlock *BB) const {
00651   if (DontExpandCondPseudos16)
00652     return BB;
00653   const TargetInstrInfo *TII =
00654       getTargetMachine().getSubtargetImpl()->getInstrInfo();
00655   DebugLoc DL = MI->getDebugLoc();
00656   // To "insert" a SELECT_CC instruction, we actually have to insert the
00657   // diamond control-flow pattern.  The incoming instruction knows the
00658   // destination vreg to set, the condition code register to branch on, the
00659   // true/false values to select between, and a branch opcode to use.
00660   const BasicBlock *LLVM_BB = BB->getBasicBlock();
00661   MachineFunction::iterator It = BB;
00662   ++It;
00663 
00664   //  thisMBB:
00665   //  ...
00666   //   TrueVal = ...
00667   //   setcc r1, r2, r3
00668   //   bNE   r1, r0, copy1MBB
00669   //   fallthrough --> copy0MBB
00670   MachineBasicBlock *thisMBB  = BB;
00671   MachineFunction *F = BB->getParent();
00672   MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
00673   MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB);
00674   F->insert(It, copy0MBB);
00675   F->insert(It, sinkMBB);
00676 
00677   // Transfer the remainder of BB and its successor edges to sinkMBB.
00678   sinkMBB->splice(sinkMBB->begin(), BB,
00679                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
00680   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
00681 
00682   // Next, add the true and fallthrough blocks as its successors.
00683   BB->addSuccessor(copy0MBB);
00684   BB->addSuccessor(sinkMBB);
00685 
00686   BuildMI(BB, DL, TII->get(Opc2)).addReg(MI->getOperand(3).getReg())
00687     .addImm(MI->getOperand(4).getImm());
00688   BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
00689 
00690   //  copy0MBB:
00691   //   %FalseValue = ...
00692   //   # fallthrough to sinkMBB
00693   BB = copy0MBB;
00694 
00695   // Update machine-CFG edges
00696   BB->addSuccessor(sinkMBB);
00697 
00698   //  sinkMBB:
00699   //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
00700   //  ...
00701   BB = sinkMBB;
00702 
00703   BuildMI(*BB, BB->begin(), DL,
00704           TII->get(Mips::PHI), MI->getOperand(0).getReg())
00705     .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB)
00706     .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB);
00707 
00708   MI->eraseFromParent();   // The pseudo instruction is gone now.
00709   return BB;
00710 
00711 }
00712 
00713 MachineBasicBlock
00714   *Mips16TargetLowering::emitFEXT_T8I816_ins(unsigned BtOpc, unsigned CmpOpc,
00715                                              MachineInstr *MI,
00716                                              MachineBasicBlock *BB) const {
00717   if (DontExpandCondPseudos16)
00718     return BB;
00719   const TargetInstrInfo *TII =
00720       getTargetMachine().getSubtargetImpl()->getInstrInfo();
00721   unsigned regX = MI->getOperand(0).getReg();
00722   unsigned regY = MI->getOperand(1).getReg();
00723   MachineBasicBlock *target = MI->getOperand(2).getMBB();
00724   BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(CmpOpc)).addReg(regX)
00725     .addReg(regY);
00726   BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(BtOpc)).addMBB(target);
00727   MI->eraseFromParent();   // The pseudo instruction is gone now.
00728   return BB;
00729 }
00730 
00731 MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins(
00732   unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned,
00733   MachineInstr *MI,  MachineBasicBlock *BB) const {
00734   if (DontExpandCondPseudos16)
00735     return BB;
00736   const TargetInstrInfo *TII =
00737       getTargetMachine().getSubtargetImpl()->getInstrInfo();
00738   unsigned regX = MI->getOperand(0).getReg();
00739   int64_t imm = MI->getOperand(1).getImm();
00740   MachineBasicBlock *target = MI->getOperand(2).getMBB();
00741   unsigned CmpOpc;
00742   if (isUInt<8>(imm))
00743     CmpOpc = CmpiOpc;
00744   else if ((!ImmSigned && isUInt<16>(imm)) ||
00745            (ImmSigned && isInt<16>(imm)))
00746     CmpOpc = CmpiXOpc;
00747   else
00748     llvm_unreachable("immediate field not usable");
00749   BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(CmpOpc)).addReg(regX)
00750     .addImm(imm);
00751   BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(BtOpc)).addMBB(target);
00752   MI->eraseFromParent();   // The pseudo instruction is gone now.
00753   return BB;
00754 }
00755 
00756 static unsigned Mips16WhichOp8uOr16simm
00757   (unsigned shortOp, unsigned longOp, int64_t Imm) {
00758   if (isUInt<8>(Imm))
00759     return shortOp;
00760   else if (isInt<16>(Imm))
00761     return longOp;
00762   else
00763     llvm_unreachable("immediate field not usable");
00764 }
00765 
00766 MachineBasicBlock *Mips16TargetLowering::emitFEXT_CCRX16_ins(
00767   unsigned SltOpc,
00768   MachineInstr *MI,  MachineBasicBlock *BB) const {
00769   if (DontExpandCondPseudos16)
00770     return BB;
00771   const TargetInstrInfo *TII =
00772       getTargetMachine().getSubtargetImpl()->getInstrInfo();
00773   unsigned CC = MI->getOperand(0).getReg();
00774   unsigned regX = MI->getOperand(1).getReg();
00775   unsigned regY = MI->getOperand(2).getReg();
00776   BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(SltOpc)).addReg(regX).addReg(
00777       regY);
00778   BuildMI(*BB, MI, MI->getDebugLoc(),
00779           TII->get(Mips::MoveR3216), CC).addReg(Mips::T8);
00780   MI->eraseFromParent();   // The pseudo instruction is gone now.
00781   return BB;
00782 }
00783 
00784 MachineBasicBlock *Mips16TargetLowering::emitFEXT_CCRXI16_ins(
00785   unsigned SltiOpc, unsigned SltiXOpc,
00786   MachineInstr *MI,  MachineBasicBlock *BB )const {
00787   if (DontExpandCondPseudos16)
00788     return BB;
00789   const TargetInstrInfo *TII =
00790       getTargetMachine().getSubtargetImpl()->getInstrInfo();
00791   unsigned CC = MI->getOperand(0).getReg();
00792   unsigned regX = MI->getOperand(1).getReg();
00793   int64_t Imm = MI->getOperand(2).getImm();
00794   unsigned SltOpc = Mips16WhichOp8uOr16simm(SltiOpc, SltiXOpc, Imm);
00795   BuildMI(*BB, MI, MI->getDebugLoc(),
00796           TII->get(SltOpc)).addReg(regX).addImm(Imm);
00797   BuildMI(*BB, MI, MI->getDebugLoc(),
00798           TII->get(Mips::MoveR3216), CC).addReg(Mips::T8);
00799   MI->eraseFromParent();   // The pseudo instruction is gone now.
00800   return BB;
00801 
00802 }