brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.7 KiB · ac32426 Raw
731 lines · cpp
1//===-- Mips16ISelLowering.h - Mips16 DAG Lowering Interface ----*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Subclass of MipsTargetLowering specialized for mips16.10//11//===----------------------------------------------------------------------===//12#include "Mips16ISelLowering.h"13#include "MCTargetDesc/MipsBaseInfo.h"14#include "Mips16HardFloatInfo.h"15#include "MipsMachineFunction.h"16#include "MipsRegisterInfo.h"17#include "MipsTargetMachine.h"18#include "llvm/CodeGen/MachineInstrBuilder.h"19#include "llvm/CodeGen/TargetInstrInfo.h"20#include "llvm/Support/CommandLine.h"21 22using namespace llvm;23 24#define DEBUG_TYPE "mips-lower"25 26static cl::opt<bool> DontExpandCondPseudos16(27  "mips16-dont-expand-cond-pseudo",28  cl::init(false),29  cl::desc("Don't expand conditional move related "30           "pseudos for Mips 16"),31  cl::Hidden);32 33namespace {34struct Mips16IntrinsicHelperType{35  const char* Name;36  const char* Helper;37 38  bool operator<(const Mips16IntrinsicHelperType &RHS) const {39    return std::strcmp(Name, RHS.Name) < 0;40  }41  bool operator==(const Mips16IntrinsicHelperType &RHS) const {42    return std::strcmp(Name, RHS.Name) == 0;43  }44};45} // namespace46 47static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = {48  {"__fixunsdfsi", "__mips16_call_stub_2" },49  {"ceil",  "__mips16_call_stub_df_2"},50  {"ceilf", "__mips16_call_stub_sf_1"},51  {"copysign",  "__mips16_call_stub_df_10"},52  {"copysignf", "__mips16_call_stub_sf_5"},53  {"cos",  "__mips16_call_stub_df_2"},54  {"cosf", "__mips16_call_stub_sf_1"},55  {"exp2",  "__mips16_call_stub_df_2"},56  {"exp2f", "__mips16_call_stub_sf_1"},57  {"floor",  "__mips16_call_stub_df_2"},58  {"floorf", "__mips16_call_stub_sf_1"},59  {"log2",  "__mips16_call_stub_df_2"},60  {"log2f", "__mips16_call_stub_sf_1"},61  {"nearbyint",  "__mips16_call_stub_df_2"},62  {"nearbyintf", "__mips16_call_stub_sf_1"},63  {"rint",  "__mips16_call_stub_df_2"},64  {"rintf", "__mips16_call_stub_sf_1"},65  {"sin",  "__mips16_call_stub_df_2"},66  {"sinf", "__mips16_call_stub_sf_1"},67  {"sqrt",  "__mips16_call_stub_df_2"},68  {"sqrtf", "__mips16_call_stub_sf_1"},69  {"trunc",  "__mips16_call_stub_df_2"},70  {"truncf", "__mips16_call_stub_sf_1"},71};72 73Mips16TargetLowering::Mips16TargetLowering(const MipsTargetMachine &TM,74                                           const MipsSubtarget &STI)75    : MipsTargetLowering(TM, STI) {76 77  // Set up the register classes78  addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);79 80  setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, LibCall);81  setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, LibCall);82  setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, LibCall);83  setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, LibCall);84  setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i32, LibCall);85  setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i32, LibCall);86  setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i32, LibCall);87  setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i32, LibCall);88  setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i32, LibCall);89  setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i32, LibCall);90  setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i32, LibCall);91  setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i32, LibCall);92  setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, LibCall);93 94  setOperationAction(ISD::ROTR, MVT::i32,  Expand);95  setOperationAction(ISD::ROTR, MVT::i64,  Expand);96  setOperationAction(ISD::BSWAP, MVT::i32, Expand);97  setOperationAction(ISD::BSWAP, MVT::i64, Expand);98 99  computeRegisterProperties(STI.getRegisterInfo());100}101 102const MipsTargetLowering *103llvm::createMips16TargetLowering(const MipsTargetMachine &TM,104                                 const MipsSubtarget &STI) {105  return new Mips16TargetLowering(TM, STI);106}107 108bool Mips16TargetLowering::allowsMisalignedMemoryAccesses(109    EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *Fast) const {110  return false;111}112 113MachineBasicBlock *114Mips16TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,115                                                  MachineBasicBlock *BB) const {116  switch (MI.getOpcode()) {117  default:118    return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);119  case Mips::SelBeqZ:120    return emitSel16(Mips::BeqzRxImm16, MI, BB);121  case Mips::SelBneZ:122    return emitSel16(Mips::BnezRxImm16, MI, BB);123  case Mips::SelTBteqZCmpi:124    return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);125  case Mips::SelTBteqZSlti:126    return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);127  case Mips::SelTBteqZSltiu:128    return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);129  case Mips::SelTBtneZCmpi:130    return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);131  case Mips::SelTBtneZSlti:132    return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);133  case Mips::SelTBtneZSltiu:134    return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);135  case Mips::SelTBteqZCmp:136    return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);137  case Mips::SelTBteqZSlt:138    return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);139  case Mips::SelTBteqZSltu:140    return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);141  case Mips::SelTBtneZCmp:142    return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);143  case Mips::SelTBtneZSlt:144    return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);145  case Mips::SelTBtneZSltu:146    return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);147  case Mips::BteqzT8CmpX16:148    return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);149  case Mips::BteqzT8SltX16:150    return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);151  case Mips::BteqzT8SltuX16:152    // TBD: figure out a way to get this or remove the instruction153    // altogether.154    return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);155  case Mips::BtnezT8CmpX16:156    return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);157  case Mips::BtnezT8SltX16:158    return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);159  case Mips::BtnezT8SltuX16:160    // TBD: figure out a way to get this or remove the instruction161    // altogether.162    return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);163  case Mips::BteqzT8CmpiX16: return emitFEXT_T8I8I16_ins(164    Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);165  case Mips::BteqzT8SltiX16: return emitFEXT_T8I8I16_ins(166    Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);167  case Mips::BteqzT8SltiuX16: return emitFEXT_T8I8I16_ins(168    Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);169  case Mips::BtnezT8CmpiX16: return emitFEXT_T8I8I16_ins(170    Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);171  case Mips::BtnezT8SltiX16: return emitFEXT_T8I8I16_ins(172    Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);173  case Mips::BtnezT8SltiuX16: return emitFEXT_T8I8I16_ins(174    Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);175    break;176  case Mips::SltCCRxRy16:177    return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);178    break;179  case Mips::SltiCCRxImmX16:180    return emitFEXT_CCRXI16_ins181      (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);182  case Mips::SltiuCCRxImmX16:183    return emitFEXT_CCRXI16_ins184      (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);185  case Mips::SltuCCRxRy16:186    return emitFEXT_CCRX16_ins187      (Mips::SltuRxRy16, MI, BB);188  }189}190 191bool Mips16TargetLowering::isEligibleForTailCallOptimization(192    const CCState &CCInfo, unsigned NextStackOffset,193    const MipsFunctionInfo &FI) const {194  // No tail call optimization for mips16.195  return false;196}197 198//199// The Mips16 hard float is a crazy quilt inherited from gcc. I have a much200// cleaner way to do all of this but it will have to wait until the traditional201// gcc mechanism is completed.202//203// For Pic, in order for Mips16 code to call Mips32 code which according the abi204// have either arguments or returned values placed in floating point registers,205// we use a set of helper functions. (This includes functions which return type206//  complex which on Mips are returned in a pair of floating point registers).207//208// This is an encoding that we inherited from gcc.209// In Mips traditional O32, N32 ABI, floating point numbers are passed in210// floating point argument registers 1,2 only when the first and optionally211// the second arguments are float (sf) or double (df).212// For Mips16 we are only concerned with the situations where floating point213// arguments are being passed in floating point registers by the ABI, because214// Mips16 mode code cannot execute floating point instructions to load those215// values and hence helper functions are needed.216// The possibilities are (), (sf), (sf, sf), (sf, df), (df), (df, sf), (df, df)217// the helper function suffixs for these are:218//                        0,  1,    5,        9,         2,   6,        10219// this suffix can then be calculated as follows:220// for a given argument Arg:221//     Arg1x, Arg2x = 1 :  Arg is sf222//                    2 :  Arg is df223//                    0:   Arg is neither sf or df224// So this stub is the string for number Arg1x + Arg2x*4.225// However not all numbers between 0 and 10 are possible, we check anyway and226// assert if the impossible exists.227//228 229unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber230  (ArgListTy &Args) const {231  unsigned int resultNum = 0;232  if (Args.size() >= 1) {233    Type *t = Args[0].Ty;234    if (t->isFloatTy()) {235      resultNum = 1;236    }237    else if (t->isDoubleTy()) {238      resultNum = 2;239    }240  }241  if (resultNum) {242    if (Args.size() >=2) {243      Type *t = Args[1].Ty;244      if (t->isFloatTy()) {245        resultNum += 4;246      }247      else if (t->isDoubleTy()) {248        resultNum += 8;249      }250    }251  }252  return resultNum;253}254 255//256// Prefixes are attached to stub numbers depending on the return type.257// return type: float  sf_258//              double df_259//              single complex sc_260//              double complext dc_261//              others  NO PREFIX262//263//264// The full name of a helper function is__mips16_call_stub +265//    return type dependent prefix + stub number266//267// FIXME: This is something that probably should be in a different source file268// and perhaps done differently but my main purpose is to not waste runtime269// on something that we can enumerate in the source. Another possibility is270// to have a python script to generate these mapping tables. This will do271// for now. There are a whole series of helper function mapping arrays, one272// for each return type class as outlined above. There there are 11 possible273// entries. Ones with 0 are ones which should never be selected.274//275// All the arrays are similar except for ones which return neither276// sf, df, sc, dc, in which we only care about ones which have sf or df as a277// first parameter.278//279#define P_ "__mips16_call_stub_"280#define MAX_STUB_NUMBER 10281#define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"282#define T P "0" , T1283#define P P_284static char const * vMips16Helper[MAX_STUB_NUMBER+1] =285  {nullptr, T1 };286#undef P287#define P P_ "sf_"288static char const * sfMips16Helper[MAX_STUB_NUMBER+1] =289  { T };290#undef P291#define P P_ "df_"292static char const * dfMips16Helper[MAX_STUB_NUMBER+1] =293  { T };294#undef P295#define P P_ "sc_"296static char const * scMips16Helper[MAX_STUB_NUMBER+1] =297  { T };298#undef P299#define P P_ "dc_"300static char const * dcMips16Helper[MAX_STUB_NUMBER+1] =301  { T };302#undef P303#undef P_304 305 306const char* Mips16TargetLowering::307  getMips16HelperFunction308    (Type* RetTy, ArgListTy &Args, bool &needHelper) const {309  const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);310#ifndef NDEBUG311  const unsigned int maxStubNum = 10;312  assert(stubNum <= maxStubNum);313  const bool validStubNum[maxStubNum+1] =314    {true, true, true, false, false, true, true, false, false, true, true};315  assert(validStubNum[stubNum]);316#endif317  const char *result;318  if (RetTy->isFloatTy()) {319    result = sfMips16Helper[stubNum];320  }321  else if (RetTy ->isDoubleTy()) {322    result = dfMips16Helper[stubNum];323  } else if (StructType *SRetTy = dyn_cast<StructType>(RetTy)) {324    // check if it's complex325    if (SRetTy->getNumElements() == 2) {326      if ((SRetTy->getElementType(0)->isFloatTy()) &&327          (SRetTy->getElementType(1)->isFloatTy())) {328        result = scMips16Helper[stubNum];329      } else if ((SRetTy->getElementType(0)->isDoubleTy()) &&330                 (SRetTy->getElementType(1)->isDoubleTy())) {331        result = dcMips16Helper[stubNum];332      } else {333        llvm_unreachable("Uncovered condition");334      }335    } else {336      llvm_unreachable("Uncovered condition");337    }338  } else {339    if (stubNum == 0) {340      needHelper = false;341      return "";342    }343    result = vMips16Helper[stubNum];344  }345  needHelper = true;346  return result;347}348 349static bool isMips16HardFloatLibcall(StringRef Name) {350  // FIXME: Use getSupportedLibcallImpl instead of blindly parsing the name.351  iota_range<RTLIB::LibcallImpl> ParsedLibcalls =352      RTLIB::RuntimeLibcallsInfo::lookupLibcallImplName(Name);353  return !ParsedLibcalls.empty() &&354         binary_search(MipsSubtarget::HardFloatLibCalls,355                       *ParsedLibcalls.begin());356}357 358void Mips16TargetLowering::359getOpndList(SmallVectorImpl<SDValue> &Ops,360            std::deque< std::pair<unsigned, SDValue> > &RegsToPass,361            bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,362            bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,363            SDValue Chain) const {364  SelectionDAG &DAG = CLI.DAG;365  MachineFunction &MF = DAG.getMachineFunction();366  MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();367  const char* Mips16HelperFunction = nullptr;368  bool NeedMips16Helper = false;369 370  if (Subtarget.inMips16HardFloat()) {371    //372    // currently we don't have symbols tagged with the mips16 or mips32373    // qualifier so we will assume that we don't know what kind it is.374    // and generate the helper375    //376    bool LookupHelper = true;377    if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {378      if (isMips16HardFloatLibcall(S->getSymbol()))379        LookupHelper = false;380      else {381        const char *Symbol = S->getSymbol();382        Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };383        const Mips16HardFloatInfo::FuncSignature *Signature =384            Mips16HardFloatInfo::findFuncSignature(Symbol);385        if (!IsPICCall && Signature &&386            FuncInfo->StubsNeeded.try_emplace(Symbol, Signature).second) {387          //388          // S2 is normally saved if the stub is for a function which389          // returns a float or double value and is not otherwise. This is390          // because more work is required after the function the stub391          // is calling completes, and so the stub cannot directly return392          // and the stub has no stack space to store the return address so393          // S2 is used for that purpose.394          // In order to take advantage of not saving S2, we need to also395          // optimize the call in the stub and this requires some further396          // functionality in MipsAsmPrinter which we don't have yet.397          // So for now we always save S2. The optimization will be done398          // in a follow-on patch.399          //400          if (true || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet))401            FuncInfo->setSaveS2();402        }403        // one more look at list of intrinsics404        const Mips16IntrinsicHelperType *Helper =405            llvm::lower_bound(Mips16IntrinsicHelper, IntrinsicFind);406        if (Helper != std::end(Mips16IntrinsicHelper) &&407            *Helper == IntrinsicFind) {408          Mips16HelperFunction = Helper->Helper;409          NeedMips16Helper = true;410          LookupHelper = false;411        }412 413      }414    } else if (GlobalAddressSDNode *G =415                   dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {416 417      if (isMips16HardFloatLibcall(G->getGlobal()->getName()))418        LookupHelper = false;419    }420    if (LookupHelper)421      Mips16HelperFunction =422        getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);423  }424 425  SDValue JumpTarget = Callee;426 427  // T9 should contain the address of the callee function if428  // -relocation-model=pic or it is an indirect call.429  if (IsPICCall || !GlobalOrExternal) {430    unsigned V0Reg = Mips::V0;431    if (NeedMips16Helper) {432      RegsToPass.push_front(std::make_pair(V0Reg, Callee));433      JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction,434                                         getPointerTy(DAG.getDataLayout()));435      ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);436      JumpTarget = getAddrGlobal(S, CLI.DL, JumpTarget.getValueType(), DAG,437                                 MipsII::MO_GOT, Chain,438                                 FuncInfo->callPtrInfo(MF, S->getSymbol()));439    } else440      RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));441  }442 443  Ops.push_back(JumpTarget);444 445  MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,446                                  InternalLinkage, IsCallReloc, CLI, Callee,447                                  Chain);448}449 450MachineBasicBlock *451Mips16TargetLowering::emitSel16(unsigned Opc, MachineInstr &MI,452                                MachineBasicBlock *BB) const {453  if (DontExpandCondPseudos16)454    return BB;455  const TargetInstrInfo *TII = Subtarget.getInstrInfo();456  DebugLoc DL = MI.getDebugLoc();457  // To "insert" a SELECT_CC instruction, we actually have to insert the458  // diamond control-flow pattern.  The incoming instruction knows the459  // destination vreg to set, the condition code register to branch on, the460  // true/false values to select between, and a branch opcode to use.461  const BasicBlock *LLVM_BB = BB->getBasicBlock();462  MachineFunction::iterator It = ++BB->getIterator();463 464  //  thisMBB:465  //  ...466  //   TrueVal = ...467  //   setcc r1, r2, r3468  //   bNE   r1, r0, copy1MBB469  //   fallthrough --> copy0MBB470  MachineBasicBlock *thisMBB  = BB;471  MachineFunction *F = BB->getParent();472  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);473  MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB);474  F->insert(It, copy0MBB);475  F->insert(It, sinkMBB);476 477  // Transfer the remainder of BB and its successor edges to sinkMBB.478  sinkMBB->splice(sinkMBB->begin(), BB,479                  std::next(MachineBasicBlock::iterator(MI)), BB->end());480  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);481 482  // Next, add the true and fallthrough blocks as its successors.483  BB->addSuccessor(copy0MBB);484  BB->addSuccessor(sinkMBB);485 486  BuildMI(BB, DL, TII->get(Opc))487      .addReg(MI.getOperand(3).getReg())488      .addMBB(sinkMBB);489 490  //  copy0MBB:491  //   %FalseValue = ...492  //   # fallthrough to sinkMBB493  BB = copy0MBB;494 495  // Update machine-CFG edges496  BB->addSuccessor(sinkMBB);497 498  //  sinkMBB:499  //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]500  //  ...501  BB = sinkMBB;502 503  BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())504      .addReg(MI.getOperand(1).getReg())505      .addMBB(thisMBB)506      .addReg(MI.getOperand(2).getReg())507      .addMBB(copy0MBB);508 509  MI.eraseFromParent(); // The pseudo instruction is gone now.510  return BB;511}512 513MachineBasicBlock *514Mips16TargetLowering::emitSelT16(unsigned Opc1, unsigned Opc2, MachineInstr &MI,515                                 MachineBasicBlock *BB) const {516  if (DontExpandCondPseudos16)517    return BB;518  const TargetInstrInfo *TII = Subtarget.getInstrInfo();519  DebugLoc DL = MI.getDebugLoc();520  // To "insert" a SELECT_CC instruction, we actually have to insert the521  // diamond control-flow pattern.  The incoming instruction knows the522  // destination vreg to set, the condition code register to branch on, the523  // true/false values to select between, and a branch opcode to use.524  const BasicBlock *LLVM_BB = BB->getBasicBlock();525  MachineFunction::iterator It = ++BB->getIterator();526 527  //  thisMBB:528  //  ...529  //   TrueVal = ...530  //   setcc r1, r2, r3531  //   bNE   r1, r0, copy1MBB532  //   fallthrough --> copy0MBB533  MachineBasicBlock *thisMBB  = BB;534  MachineFunction *F = BB->getParent();535  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);536  MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB);537  F->insert(It, copy0MBB);538  F->insert(It, sinkMBB);539 540  // Transfer the remainder of BB and its successor edges to sinkMBB.541  sinkMBB->splice(sinkMBB->begin(), BB,542                  std::next(MachineBasicBlock::iterator(MI)), BB->end());543  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);544 545  // Next, add the true and fallthrough blocks as its successors.546  BB->addSuccessor(copy0MBB);547  BB->addSuccessor(sinkMBB);548 549  BuildMI(BB, DL, TII->get(Opc2))550      .addReg(MI.getOperand(3).getReg())551      .addReg(MI.getOperand(4).getReg());552  BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);553 554  //  copy0MBB:555  //   %FalseValue = ...556  //   # fallthrough to sinkMBB557  BB = copy0MBB;558 559  // Update machine-CFG edges560  BB->addSuccessor(sinkMBB);561 562  //  sinkMBB:563  //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]564  //  ...565  BB = sinkMBB;566 567  BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())568      .addReg(MI.getOperand(1).getReg())569      .addMBB(thisMBB)570      .addReg(MI.getOperand(2).getReg())571      .addMBB(copy0MBB);572 573  MI.eraseFromParent(); // The pseudo instruction is gone now.574  return BB;575 576}577 578MachineBasicBlock *579Mips16TargetLowering::emitSeliT16(unsigned Opc1, unsigned Opc2,580                                  MachineInstr &MI,581                                  MachineBasicBlock *BB) const {582  if (DontExpandCondPseudos16)583    return BB;584  const TargetInstrInfo *TII = Subtarget.getInstrInfo();585  DebugLoc DL = MI.getDebugLoc();586  // To "insert" a SELECT_CC instruction, we actually have to insert the587  // diamond control-flow pattern.  The incoming instruction knows the588  // destination vreg to set, the condition code register to branch on, the589  // true/false values to select between, and a branch opcode to use.590  const BasicBlock *LLVM_BB = BB->getBasicBlock();591  MachineFunction::iterator It = ++BB->getIterator();592 593  //  thisMBB:594  //  ...595  //   TrueVal = ...596  //   setcc r1, r2, r3597  //   bNE   r1, r0, copy1MBB598  //   fallthrough --> copy0MBB599  MachineBasicBlock *thisMBB  = BB;600  MachineFunction *F = BB->getParent();601  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);602  MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB);603  F->insert(It, copy0MBB);604  F->insert(It, sinkMBB);605 606  // Transfer the remainder of BB and its successor edges to sinkMBB.607  sinkMBB->splice(sinkMBB->begin(), BB,608                  std::next(MachineBasicBlock::iterator(MI)), BB->end());609  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);610 611  // Next, add the true and fallthrough blocks as its successors.612  BB->addSuccessor(copy0MBB);613  BB->addSuccessor(sinkMBB);614 615  BuildMI(BB, DL, TII->get(Opc2))616      .addReg(MI.getOperand(3).getReg())617      .addImm(MI.getOperand(4).getImm());618  BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);619 620  //  copy0MBB:621  //   %FalseValue = ...622  //   # fallthrough to sinkMBB623  BB = copy0MBB;624 625  // Update machine-CFG edges626  BB->addSuccessor(sinkMBB);627 628  //  sinkMBB:629  //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]630  //  ...631  BB = sinkMBB;632 633  BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())634      .addReg(MI.getOperand(1).getReg())635      .addMBB(thisMBB)636      .addReg(MI.getOperand(2).getReg())637      .addMBB(copy0MBB);638 639  MI.eraseFromParent(); // The pseudo instruction is gone now.640  return BB;641 642}643 644MachineBasicBlock *645Mips16TargetLowering::emitFEXT_T8I816_ins(unsigned BtOpc, unsigned CmpOpc,646                                          MachineInstr &MI,647                                          MachineBasicBlock *BB) const {648  if (DontExpandCondPseudos16)649    return BB;650  const TargetInstrInfo *TII = Subtarget.getInstrInfo();651  Register regX = MI.getOperand(0).getReg();652  Register regY = MI.getOperand(1).getReg();653  MachineBasicBlock *target = MI.getOperand(2).getMBB();654  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc))655      .addReg(regX)656      .addReg(regY);657  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);658  MI.eraseFromParent(); // The pseudo instruction is gone now.659  return BB;660}661 662MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins(663    unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned,664    MachineInstr &MI, MachineBasicBlock *BB) const {665  if (DontExpandCondPseudos16)666    return BB;667  const TargetInstrInfo *TII = Subtarget.getInstrInfo();668  Register regX = MI.getOperand(0).getReg();669  int64_t imm = MI.getOperand(1).getImm();670  MachineBasicBlock *target = MI.getOperand(2).getMBB();671  unsigned CmpOpc;672  if (isUInt<8>(imm))673    CmpOpc = CmpiOpc;674  else if ((!ImmSigned && isUInt<16>(imm)) ||675           (ImmSigned && isInt<16>(imm)))676    CmpOpc = CmpiXOpc;677  else678    llvm_unreachable("immediate field not usable");679  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc)).addReg(regX).addImm(imm);680  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);681  MI.eraseFromParent(); // The pseudo instruction is gone now.682  return BB;683}684 685static unsigned Mips16WhichOp8uOr16simm686  (unsigned shortOp, unsigned longOp, int64_t Imm) {687  if (isUInt<8>(Imm))688    return shortOp;689  else if (isInt<16>(Imm))690    return longOp;691  else692    llvm_unreachable("immediate field not usable");693}694 695MachineBasicBlock *696Mips16TargetLowering::emitFEXT_CCRX16_ins(unsigned SltOpc, MachineInstr &MI,697                                          MachineBasicBlock *BB) const {698  if (DontExpandCondPseudos16)699    return BB;700  const TargetInstrInfo *TII = Subtarget.getInstrInfo();701  Register CC = MI.getOperand(0).getReg();702  Register regX = MI.getOperand(1).getReg();703  Register regY = MI.getOperand(2).getReg();704  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc))705      .addReg(regX)706      .addReg(regY);707  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)708      .addReg(Mips::T8);709  MI.eraseFromParent(); // The pseudo instruction is gone now.710  return BB;711}712 713MachineBasicBlock *714Mips16TargetLowering::emitFEXT_CCRXI16_ins(unsigned SltiOpc, unsigned SltiXOpc,715                                           MachineInstr &MI,716                                           MachineBasicBlock *BB) const {717  if (DontExpandCondPseudos16)718    return BB;719  const TargetInstrInfo *TII = Subtarget.getInstrInfo();720  Register CC = MI.getOperand(0).getReg();721  Register regX = MI.getOperand(1).getReg();722  int64_t Imm = MI.getOperand(2).getImm();723  unsigned SltOpc = Mips16WhichOp8uOr16simm(SltiOpc, SltiXOpc, Imm);724  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc)).addReg(regX).addImm(Imm);725  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)726      .addReg(Mips::T8);727  MI.eraseFromParent(); // The pseudo instruction is gone now.728  return BB;729 730}731