brintos

brintos / llvm-project-archived public Read only

0
0
Text · 66.7 KiB · 06210b6 Raw
2169 lines · cpp
1//===- MipsFastISel.cpp - Mips FastISel implementation --------------------===//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/// \file10/// This file defines the MIPS-specific support for the FastISel class.11/// Some of the target-specific code is generated by tablegen in the file12/// MipsGenFastISel.inc, which is #included here.13///14//===----------------------------------------------------------------------===//15 16#include "MCTargetDesc/MipsABIInfo.h"17#include "MCTargetDesc/MipsBaseInfo.h"18#include "MipsCCState.h"19#include "MipsISelLowering.h"20#include "MipsInstrInfo.h"21#include "MipsMachineFunction.h"22#include "MipsSubtarget.h"23#include "MipsTargetMachine.h"24#include "llvm/ADT/APInt.h"25#include "llvm/ADT/DenseMap.h"26#include "llvm/ADT/SmallVector.h"27#include "llvm/Analysis/TargetLibraryInfo.h"28#include "llvm/CodeGen/CallingConvLower.h"29#include "llvm/CodeGen/FastISel.h"30#include "llvm/CodeGen/FunctionLoweringInfo.h"31#include "llvm/CodeGen/ISDOpcodes.h"32#include "llvm/CodeGen/MachineBasicBlock.h"33#include "llvm/CodeGen/MachineFrameInfo.h"34#include "llvm/CodeGen/MachineInstrBuilder.h"35#include "llvm/CodeGen/MachineMemOperand.h"36#include "llvm/CodeGen/MachineRegisterInfo.h"37#include "llvm/CodeGen/TargetInstrInfo.h"38#include "llvm/CodeGen/TargetLowering.h"39#include "llvm/CodeGen/ValueTypes.h"40#include "llvm/CodeGenTypes/MachineValueType.h"41#include "llvm/IR/Attributes.h"42#include "llvm/IR/CallingConv.h"43#include "llvm/IR/Constant.h"44#include "llvm/IR/Constants.h"45#include "llvm/IR/DataLayout.h"46#include "llvm/IR/Function.h"47#include "llvm/IR/GetElementPtrTypeIterator.h"48#include "llvm/IR/GlobalValue.h"49#include "llvm/IR/GlobalVariable.h"50#include "llvm/IR/InstrTypes.h"51#include "llvm/IR/Instruction.h"52#include "llvm/IR/Instructions.h"53#include "llvm/IR/IntrinsicInst.h"54#include "llvm/IR/Operator.h"55#include "llvm/IR/Type.h"56#include "llvm/IR/User.h"57#include "llvm/IR/Value.h"58#include "llvm/MC/MCContext.h"59#include "llvm/MC/MCInstrDesc.h"60#include "llvm/MC/MCSymbol.h"61#include "llvm/Support/Casting.h"62#include "llvm/Support/Compiler.h"63#include "llvm/Support/Debug.h"64#include "llvm/Support/ErrorHandling.h"65#include "llvm/Support/MathExtras.h"66#include "llvm/Support/raw_ostream.h"67#include <algorithm>68#include <array>69#include <cassert>70#include <cstdint>71 72#define DEBUG_TYPE "mips-fastisel"73 74using namespace llvm;75 76extern cl::opt<bool> EmitJalrReloc;77 78namespace {79 80class MipsFastISel final : public FastISel {81 82  // All possible address modes.83  class Address {84  public:85    enum BaseKind { RegBase, FrameIndexBase };86 87  private:88    BaseKind Kind = RegBase;89    union {90      unsigned Reg;91      int FI;92    } Base;93 94    int64_t Offset = 0;95 96    const GlobalValue *GV = nullptr;97 98  public:99    // Innocuous defaults for our address.100    Address() { Base.Reg = 0; }101 102    void setKind(BaseKind K) { Kind = K; }103    BaseKind getKind() const { return Kind; }104    bool isRegBase() const { return Kind == RegBase; }105    bool isFIBase() const { return Kind == FrameIndexBase; }106 107    void setReg(unsigned Reg) {108      assert(isRegBase() && "Invalid base register access!");109      Base.Reg = Reg;110    }111 112    unsigned getReg() const {113      assert(isRegBase() && "Invalid base register access!");114      return Base.Reg;115    }116 117    void setFI(unsigned FI) {118      assert(isFIBase() && "Invalid base frame index access!");119      Base.FI = FI;120    }121 122    unsigned getFI() const {123      assert(isFIBase() && "Invalid base frame index access!");124      return Base.FI;125    }126 127    void setOffset(int64_t Offset_) { Offset = Offset_; }128    int64_t getOffset() const { return Offset; }129    void setGlobalValue(const GlobalValue *G) { GV = G; }130    const GlobalValue *getGlobalValue() { return GV; }131  };132 133  /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can134  /// make the right decision when generating code for different targets.135  const TargetMachine &TM;136  const MipsSubtarget *Subtarget;137  const TargetInstrInfo &TII;138  const TargetLowering &TLI;139  MipsFunctionInfo *MFI;140 141  // Convenience variables to avoid some queries.142  LLVMContext *Context;143 144  bool fastLowerArguments() override;145  bool fastLowerCall(CallLoweringInfo &CLI) override;146  bool fastLowerIntrinsicCall(const IntrinsicInst *II) override;147 148  bool UnsupportedFPMode; // To allow fast-isel to proceed and just not handle149  // floating point but not reject doing fast-isel in other150  // situations151 152private:153  // Selection routines.154  bool selectLogicalOp(const Instruction *I);155  bool selectLoad(const Instruction *I);156  bool selectStore(const Instruction *I);157  bool selectBranch(const Instruction *I);158  bool selectSelect(const Instruction *I);159  bool selectCmp(const Instruction *I);160  bool selectFPExt(const Instruction *I);161  bool selectFPTrunc(const Instruction *I);162  bool selectFPToInt(const Instruction *I, bool IsSigned);163  bool selectRet(const Instruction *I);164  bool selectTrunc(const Instruction *I);165  bool selectIntExt(const Instruction *I);166  bool selectShift(const Instruction *I);167  bool selectDivRem(const Instruction *I, unsigned ISDOpcode);168 169  // Utility helper routines.170  bool isTypeLegal(Type *Ty, MVT &VT);171  bool isTypeSupported(Type *Ty, MVT &VT);172  bool isLoadTypeLegal(Type *Ty, MVT &VT);173  bool computeAddress(const Value *Obj, Address &Addr);174  bool computeCallAddress(const Value *V, Address &Addr);175  void simplifyAddress(Address &Addr);176 177  // Emit helper routines.178  bool emitCmp(unsigned DestReg, const CmpInst *CI);179  bool emitLoad(MVT VT, unsigned &ResultReg, Address &Addr);180  bool emitStore(MVT VT, unsigned SrcReg, Address &Addr);181  unsigned emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt);182  bool emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg,183 184                  bool IsZExt);185  bool emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);186 187  bool emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);188  bool emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,189                       unsigned DestReg);190  bool emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,191                       unsigned DestReg);192 193  unsigned getRegEnsuringSimpleIntegerWidening(const Value *, bool IsUnsigned);194 195  unsigned emitLogicalOp(unsigned ISDOpc, MVT RetVT, const Value *LHS,196                         const Value *RHS);197 198  unsigned materializeFP(const ConstantFP *CFP, MVT VT);199  unsigned materializeGV(const GlobalValue *GV, MVT VT);200  unsigned materializeInt(const Constant *C, MVT VT);201  unsigned materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);202  unsigned materializeExternalCallSym(MCSymbol *Syn);203 204  MachineInstrBuilder emitInst(unsigned Opc) {205    return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc));206  }207 208  MachineInstrBuilder emitInst(unsigned Opc, unsigned DstReg) {209    return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),210                   DstReg);211  }212 213  MachineInstrBuilder emitInstStore(unsigned Opc, unsigned SrcReg,214                                    unsigned MemReg, int64_t MemOffset) {215    return emitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset);216  }217 218  MachineInstrBuilder emitInstLoad(unsigned Opc, unsigned DstReg,219                                   unsigned MemReg, int64_t MemOffset) {220    return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);221  }222 223  unsigned fastEmitInst_rr(unsigned MachineInstOpcode,224                           const TargetRegisterClass *RC,225                           unsigned Op0, unsigned Op1);226 227  // for some reason, this default is not generated by tablegen228  // so we explicitly generate it here.229  unsigned fastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC,230                             unsigned Op0, uint64_t imm1, uint64_t imm2,231                             unsigned Op3) {232    return 0;233  }234 235  // Call handling routines.236private:237  CCAssignFn *CCAssignFnForCall(CallingConv::ID CC) const;238  bool processCallArgs(CallLoweringInfo &CLI, SmallVectorImpl<MVT> &ArgVTs,239                       unsigned &NumBytes);240  bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes);241 242  const MipsABIInfo &getABI() const {243    return static_cast<const MipsTargetMachine &>(TM).getABI();244  }245 246public:247  // Backend specific FastISel code.248  explicit MipsFastISel(FunctionLoweringInfo &funcInfo,249                        const TargetLibraryInfo *libInfo)250      : FastISel(funcInfo, libInfo), TM(funcInfo.MF->getTarget()),251        Subtarget(&funcInfo.MF->getSubtarget<MipsSubtarget>()),252        TII(*Subtarget->getInstrInfo()), TLI(*Subtarget->getTargetLowering()) {253    MFI = funcInfo.MF->getInfo<MipsFunctionInfo>();254    Context = &funcInfo.Fn->getContext();255    UnsupportedFPMode = Subtarget->isFP64bit() || Subtarget->useSoftFloat();256  }257 258  Register fastMaterializeAlloca(const AllocaInst *AI) override;259  Register fastMaterializeConstant(const Constant *C) override;260  bool fastSelectInstruction(const Instruction *I) override;261 262#include "MipsGenFastISel.inc"263};264 265} // end anonymous namespace266 267[[maybe_unused]] static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT,268                                     CCValAssign::LocInfo LocInfo,269                                     ISD::ArgFlagsTy ArgFlags, Type *OrigTy,270                                     CCState &State);271 272static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT,273                            CCValAssign::LocInfo LocInfo,274                            ISD::ArgFlagsTy ArgFlags, Type *OrigTy,275                            CCState &State) {276  llvm_unreachable("should not be called");277}278 279static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT,280                            CCValAssign::LocInfo LocInfo,281                            ISD::ArgFlagsTy ArgFlags, Type *OrigTy,282                            CCState &State) {283  llvm_unreachable("should not be called");284}285 286#include "MipsGenCallingConv.inc"287 288CCAssignFn *MipsFastISel::CCAssignFnForCall(CallingConv::ID CC) const {289  return CC_MipsO32;290}291 292unsigned MipsFastISel::emitLogicalOp(unsigned ISDOpc, MVT RetVT,293                                     const Value *LHS, const Value *RHS) {294  // Canonicalize immediates to the RHS first.295  if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS))296    std::swap(LHS, RHS);297 298  unsigned Opc;299  switch (ISDOpc) {300  case ISD::AND:301    Opc = Mips::AND;302    break;303  case ISD::OR:304    Opc = Mips::OR;305    break;306  case ISD::XOR:307    Opc = Mips::XOR;308    break;309  default:310    llvm_unreachable("unexpected opcode");311  }312 313  Register LHSReg = getRegForValue(LHS);314  if (!LHSReg)315    return 0;316 317  unsigned RHSReg;318  if (const auto *C = dyn_cast<ConstantInt>(RHS))319    RHSReg = materializeInt(C, MVT::i32);320  else321    RHSReg = getRegForValue(RHS);322  if (!RHSReg)323    return 0;324 325  Register ResultReg = createResultReg(&Mips::GPR32RegClass);326  if (!ResultReg)327    return 0;328 329  emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);330  return ResultReg;331}332 333Register MipsFastISel::fastMaterializeAlloca(const AllocaInst *AI) {334  assert(TLI.getValueType(DL, AI->getType(), true) == MVT::i32 &&335         "Alloca should always return a pointer.");336 337  DenseMap<const AllocaInst *, int>::iterator SI =338      FuncInfo.StaticAllocaMap.find(AI);339 340  if (SI != FuncInfo.StaticAllocaMap.end()) {341    Register ResultReg = createResultReg(&Mips::GPR32RegClass);342    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::LEA_ADDiu),343            ResultReg)344        .addFrameIndex(SI->second)345        .addImm(0);346    return ResultReg;347  }348 349  return Register();350}351 352unsigned MipsFastISel::materializeInt(const Constant *C, MVT VT) {353  if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)354    return 0;355  const TargetRegisterClass *RC = &Mips::GPR32RegClass;356  const ConstantInt *CI = cast<ConstantInt>(C);357  return materialize32BitInt(CI->getZExtValue(), RC);358}359 360unsigned MipsFastISel::materialize32BitInt(int64_t Imm,361                                           const TargetRegisterClass *RC) {362  Register ResultReg = createResultReg(RC);363 364  if (isInt<16>(Imm)) {365    unsigned Opc = Mips::ADDiu;366    emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);367    return ResultReg;368  } else if (isUInt<16>(Imm)) {369    emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);370    return ResultReg;371  }372  unsigned Lo = Imm & 0xFFFF;373  unsigned Hi = (Imm >> 16) & 0xFFFF;374  if (Lo) {375    // Both Lo and Hi have nonzero bits.376    Register TmpReg = createResultReg(RC);377    emitInst(Mips::LUi, TmpReg).addImm(Hi);378    emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);379  } else {380    emitInst(Mips::LUi, ResultReg).addImm(Hi);381  }382  return ResultReg;383}384 385unsigned MipsFastISel::materializeFP(const ConstantFP *CFP, MVT VT) {386  if (UnsupportedFPMode)387    return 0;388  int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue();389  if (VT == MVT::f32) {390    const TargetRegisterClass *RC = &Mips::FGR32RegClass;391    Register DestReg = createResultReg(RC);392    unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass);393    emitInst(Mips::MTC1, DestReg).addReg(TempReg);394    return DestReg;395  } else if (VT == MVT::f64) {396    const TargetRegisterClass *RC = &Mips::AFGR64RegClass;397    Register DestReg = createResultReg(RC);398    unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);399    unsigned TempReg2 =400        materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);401    emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);402    return DestReg;403  }404  return 0;405}406 407unsigned MipsFastISel::materializeGV(const GlobalValue *GV, MVT VT) {408  // For now 32-bit only.409  if (VT != MVT::i32)410    return 0;411  const TargetRegisterClass *RC = &Mips::GPR32RegClass;412  Register DestReg = createResultReg(RC);413  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);414  bool IsThreadLocal = GVar && GVar->isThreadLocal();415  // TLS not supported at this time.416  if (IsThreadLocal)417    return 0;418  emitInst(Mips::LW, DestReg)419      .addReg(MFI->getGlobalBaseReg(*MF))420      .addGlobalAddress(GV, 0, MipsII::MO_GOT);421  if ((GV->hasInternalLinkage() ||422       (GV->hasLocalLinkage() && !isa<Function>(GV)))) {423    Register TempReg = createResultReg(RC);424    emitInst(Mips::ADDiu, TempReg)425        .addReg(DestReg)426        .addGlobalAddress(GV, 0, MipsII::MO_ABS_LO);427    DestReg = TempReg;428  }429  return DestReg;430}431 432unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {433  const TargetRegisterClass *RC = &Mips::GPR32RegClass;434  Register DestReg = createResultReg(RC);435  emitInst(Mips::LW, DestReg)436      .addReg(MFI->getGlobalBaseReg(*MF))437      .addSym(Sym, MipsII::MO_GOT);438  return DestReg;439}440 441// Materialize a constant into a register, and return the register442// number (or zero if we failed to handle it).443Register MipsFastISel::fastMaterializeConstant(const Constant *C) {444  EVT CEVT = TLI.getValueType(DL, C->getType(), true);445 446  // Only handle simple types.447  if (!CEVT.isSimple())448    return Register();449  MVT VT = CEVT.getSimpleVT();450 451  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))452    return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);453  else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))454    return materializeGV(GV, VT);455  else if (isa<ConstantInt>(C))456    return materializeInt(C, VT);457 458  return Register();459}460 461bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {462  const User *U = nullptr;463  unsigned Opcode = Instruction::UserOp1;464  if (const Instruction *I = dyn_cast<Instruction>(Obj)) {465    // Don't walk into other basic blocks unless the object is an alloca from466    // another block, otherwise it may not have a virtual register assigned.467    if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||468        FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {469      Opcode = I->getOpcode();470      U = I;471    }472  } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {473    Opcode = C->getOpcode();474    U = C;475  }476  switch (Opcode) {477  default:478    break;479  case Instruction::BitCast:480    // Look through bitcasts.481    return computeAddress(U->getOperand(0), Addr);482  case Instruction::GetElementPtr: {483    Address SavedAddr = Addr;484    int64_t TmpOffset = Addr.getOffset();485    // Iterate through the GEP folding the constants into offsets where486    // we can.487    gep_type_iterator GTI = gep_type_begin(U);488    for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e;489         ++i, ++GTI) {490      const Value *Op = *i;491      if (StructType *STy = GTI.getStructTypeOrNull()) {492        const StructLayout *SL = DL.getStructLayout(STy);493        unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();494        TmpOffset += SL->getElementOffset(Idx);495      } else {496        uint64_t S = GTI.getSequentialElementStride(DL);497        while (true) {498          if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {499            // Constant-offset addressing.500            TmpOffset += CI->getSExtValue() * S;501            break;502          }503          if (canFoldAddIntoGEP(U, Op)) {504            // A compatible add with a constant operand. Fold the constant.505            ConstantInt *CI =506                cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));507            TmpOffset += CI->getSExtValue() * S;508            // Iterate on the other operand.509            Op = cast<AddOperator>(Op)->getOperand(0);510            continue;511          }512          // Unsupported513          goto unsupported_gep;514        }515      }516    }517    // Try to grab the base operand now.518    Addr.setOffset(TmpOffset);519    if (computeAddress(U->getOperand(0), Addr))520      return true;521    // We failed, restore everything and try the other options.522    Addr = SavedAddr;523  unsupported_gep:524    break;525  }526  case Instruction::Alloca: {527    const AllocaInst *AI = cast<AllocaInst>(Obj);528    DenseMap<const AllocaInst *, int>::iterator SI =529        FuncInfo.StaticAllocaMap.find(AI);530    if (SI != FuncInfo.StaticAllocaMap.end()) {531      Addr.setKind(Address::FrameIndexBase);532      Addr.setFI(SI->second);533      return true;534    }535    break;536  }537  }538  Addr.setReg(getRegForValue(Obj));539  return Addr.getReg() != 0;540}541 542bool MipsFastISel::computeCallAddress(const Value *V, Address &Addr) {543  const User *U = nullptr;544  unsigned Opcode = Instruction::UserOp1;545 546  if (const auto *I = dyn_cast<Instruction>(V)) {547    // Check if the value is defined in the same basic block. This information548    // is crucial to know whether or not folding an operand is valid.549    if (I->getParent() == FuncInfo.MBB->getBasicBlock()) {550      Opcode = I->getOpcode();551      U = I;552    }553  } else if (const auto *C = dyn_cast<ConstantExpr>(V)) {554    Opcode = C->getOpcode();555    U = C;556  }557 558  switch (Opcode) {559  default:560    break;561  case Instruction::BitCast:562    // Look past bitcasts if its operand is in the same BB.563      return computeCallAddress(U->getOperand(0), Addr);564    break;565  case Instruction::IntToPtr:566    // Look past no-op inttoptrs if its operand is in the same BB.567    if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==568        TLI.getPointerTy(DL))569      return computeCallAddress(U->getOperand(0), Addr);570    break;571  case Instruction::PtrToInt:572    // Look past no-op ptrtoints if its operand is in the same BB.573    if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))574      return computeCallAddress(U->getOperand(0), Addr);575    break;576  }577 578  if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {579    Addr.setGlobalValue(GV);580    return true;581  }582 583  // If all else fails, try to materialize the value in a register.584  if (!Addr.getGlobalValue()) {585    Addr.setReg(getRegForValue(V));586    return Addr.getReg() != 0;587  }588 589  return false;590}591 592bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {593  EVT evt = TLI.getValueType(DL, Ty, true);594  // Only handle simple types.595  if (evt == MVT::Other || !evt.isSimple())596    return false;597  VT = evt.getSimpleVT();598 599  // Handle all legal types, i.e. a register that will directly hold this600  // value.601  return TLI.isTypeLegal(VT);602}603 604bool MipsFastISel::isTypeSupported(Type *Ty, MVT &VT) {605  if (Ty->isVectorTy())606    return false;607 608  if (isTypeLegal(Ty, VT))609    return true;610 611  // If this is a type than can be sign or zero-extended to a basic operation612  // go ahead and accept it now.613  if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)614    return true;615 616  return false;617}618 619bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {620  if (isTypeLegal(Ty, VT))621    return true;622  // We will extend this in a later patch:623  //   If this is a type than can be sign or zero-extended to a basic operation624  //   go ahead and accept it now.625  if (VT == MVT::i8 || VT == MVT::i16)626    return true;627  return false;628}629 630// Because of how EmitCmp is called with fast-isel, you can631// end up with redundant "andi" instructions after the sequences emitted below.632// We should try and solve this issue in the future.633//634bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {635  const Value *Left = CI->getOperand(0), *Right = CI->getOperand(1);636  bool IsUnsigned = CI->isUnsigned();637  unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);638  if (LeftReg == 0)639    return false;640  unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned);641  if (RightReg == 0)642    return false;643  CmpInst::Predicate P = CI->getPredicate();644 645  switch (P) {646  default:647    return false;648  case CmpInst::ICMP_EQ: {649    Register TempReg = createResultReg(&Mips::GPR32RegClass);650    emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);651    emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);652    break;653  }654  case CmpInst::ICMP_NE: {655    Register TempReg = createResultReg(&Mips::GPR32RegClass);656    emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);657    emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);658    break;659  }660  case CmpInst::ICMP_UGT:661    emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);662    break;663  case CmpInst::ICMP_ULT:664    emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);665    break;666  case CmpInst::ICMP_UGE: {667    Register TempReg = createResultReg(&Mips::GPR32RegClass);668    emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);669    emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);670    break;671  }672  case CmpInst::ICMP_ULE: {673    Register TempReg = createResultReg(&Mips::GPR32RegClass);674    emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);675    emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);676    break;677  }678  case CmpInst::ICMP_SGT:679    emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);680    break;681  case CmpInst::ICMP_SLT:682    emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);683    break;684  case CmpInst::ICMP_SGE: {685    Register TempReg = createResultReg(&Mips::GPR32RegClass);686    emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);687    emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);688    break;689  }690  case CmpInst::ICMP_SLE: {691    Register TempReg = createResultReg(&Mips::GPR32RegClass);692    emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);693    emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);694    break;695  }696  case CmpInst::FCMP_OEQ:697  case CmpInst::FCMP_UNE:698  case CmpInst::FCMP_OLT:699  case CmpInst::FCMP_OLE:700  case CmpInst::FCMP_OGT:701  case CmpInst::FCMP_OGE: {702    if (UnsupportedFPMode)703      return false;704    bool IsFloat = Left->getType()->isFloatTy();705    bool IsDouble = Left->getType()->isDoubleTy();706    if (!IsFloat && !IsDouble)707      return false;708    unsigned Opc, CondMovOpc;709    switch (P) {710    case CmpInst::FCMP_OEQ:711      Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;712      CondMovOpc = Mips::MOVT_I;713      break;714    case CmpInst::FCMP_UNE:715      Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;716      CondMovOpc = Mips::MOVF_I;717      break;718    case CmpInst::FCMP_OLT:719      Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;720      CondMovOpc = Mips::MOVT_I;721      break;722    case CmpInst::FCMP_OLE:723      Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;724      CondMovOpc = Mips::MOVT_I;725      break;726    case CmpInst::FCMP_OGT:727      Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;728      CondMovOpc = Mips::MOVF_I;729      break;730    case CmpInst::FCMP_OGE:731      Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;732      CondMovOpc = Mips::MOVF_I;733      break;734    default:735      llvm_unreachable("Only switching of a subset of CCs.");736    }737    Register RegWithZero = createResultReg(&Mips::GPR32RegClass);738    Register RegWithOne = createResultReg(&Mips::GPR32RegClass);739    emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);740    emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);741    emitInst(Opc).addReg(Mips::FCC0, RegState::Define).addReg(LeftReg)742                 .addReg(RightReg);743    emitInst(CondMovOpc, ResultReg)744        .addReg(RegWithOne)745        .addReg(Mips::FCC0)746        .addReg(RegWithZero);747    break;748  }749  }750  return true;751}752 753bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr) {754  //755  // more cases will be handled here in following patches.756  //757  unsigned Opc;758  switch (VT.SimpleTy) {759  case MVT::i32:760    ResultReg = createResultReg(&Mips::GPR32RegClass);761    Opc = Mips::LW;762    break;763  case MVT::i16:764    ResultReg = createResultReg(&Mips::GPR32RegClass);765    Opc = Mips::LHu;766    break;767  case MVT::i8:768    ResultReg = createResultReg(&Mips::GPR32RegClass);769    Opc = Mips::LBu;770    break;771  case MVT::f32:772    if (UnsupportedFPMode)773      return false;774    ResultReg = createResultReg(&Mips::FGR32RegClass);775    Opc = Mips::LWC1;776    break;777  case MVT::f64:778    if (UnsupportedFPMode)779      return false;780    ResultReg = createResultReg(&Mips::AFGR64RegClass);781    Opc = Mips::LDC1;782    break;783  default:784    return false;785  }786  if (Addr.isRegBase()) {787    simplifyAddress(Addr);788    emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset());789    return true;790  }791  if (Addr.isFIBase()) {792    unsigned FI = Addr.getFI();793    int64_t Offset = Addr.getOffset();794    MachineFrameInfo &MFI = MF->getFrameInfo();795    MachineMemOperand *MMO = MF->getMachineMemOperand(796        MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,797        MFI.getObjectSize(FI), Align(4));798    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)799        .addFrameIndex(FI)800        .addImm(Offset)801        .addMemOperand(MMO);802    return true;803  }804  return false;805}806 807bool MipsFastISel::emitStore(MVT VT, unsigned SrcReg, Address &Addr) {808  //809  // more cases will be handled here in following patches.810  //811  unsigned Opc;812  switch (VT.SimpleTy) {813  case MVT::i8:814    Opc = Mips::SB;815    break;816  case MVT::i16:817    Opc = Mips::SH;818    break;819  case MVT::i32:820    Opc = Mips::SW;821    break;822  case MVT::f32:823    if (UnsupportedFPMode)824      return false;825    Opc = Mips::SWC1;826    break;827  case MVT::f64:828    if (UnsupportedFPMode)829      return false;830    Opc = Mips::SDC1;831    break;832  default:833    return false;834  }835  if (Addr.isRegBase()) {836    simplifyAddress(Addr);837    emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset());838    return true;839  }840  if (Addr.isFIBase()) {841    unsigned FI = Addr.getFI();842    int64_t Offset = Addr.getOffset();843    MachineFrameInfo &MFI = MF->getFrameInfo();844    MachineMemOperand *MMO = MF->getMachineMemOperand(845        MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,846        MFI.getObjectSize(FI), Align(4));847    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))848        .addReg(SrcReg)849        .addFrameIndex(FI)850        .addImm(Offset)851        .addMemOperand(MMO);852    return true;853  }854  return false;855}856 857bool MipsFastISel::selectLogicalOp(const Instruction *I) {858  MVT VT;859  if (!isTypeSupported(I->getType(), VT))860    return false;861 862  unsigned ResultReg;863  switch (I->getOpcode()) {864  default:865    llvm_unreachable("Unexpected instruction.");866  case Instruction::And:867    ResultReg = emitLogicalOp(ISD::AND, VT, I->getOperand(0), I->getOperand(1));868    break;869  case Instruction::Or:870    ResultReg = emitLogicalOp(ISD::OR, VT, I->getOperand(0), I->getOperand(1));871    break;872  case Instruction::Xor:873    ResultReg = emitLogicalOp(ISD::XOR, VT, I->getOperand(0), I->getOperand(1));874    break;875  }876 877  if (!ResultReg)878    return false;879 880  updateValueMap(I, ResultReg);881  return true;882}883 884bool MipsFastISel::selectLoad(const Instruction *I) {885  const LoadInst *LI = cast<LoadInst>(I);886 887  // Atomic loads need special handling.888  if (LI->isAtomic())889    return false;890 891  // Verify we have a legal type before going any further.892  MVT VT;893  if (!isLoadTypeLegal(LI->getType(), VT))894    return false;895 896  // Underaligned loads need special handling.897  if (LI->getAlign() < VT.getFixedSizeInBits() / 8 &&898      !Subtarget->systemSupportsUnalignedAccess())899    return false;900 901  // See if we can handle this address.902  Address Addr;903  if (!computeAddress(LI->getOperand(0), Addr))904    return false;905 906  unsigned ResultReg;907  if (!emitLoad(VT, ResultReg, Addr))908    return false;909  updateValueMap(LI, ResultReg);910  return true;911}912 913bool MipsFastISel::selectStore(const Instruction *I) {914  const StoreInst *SI = cast<StoreInst>(I);915 916  Value *Op0 = SI->getOperand(0);917  unsigned SrcReg = 0;918 919  // Atomic stores need special handling.920  if (SI->isAtomic())921    return false;922 923  // Verify we have a legal type before going any further.924  MVT VT;925  if (!isLoadTypeLegal(SI->getOperand(0)->getType(), VT))926    return false;927 928  // Underaligned stores need special handling.929  if (SI->getAlign() < VT.getFixedSizeInBits() / 8 &&930      !Subtarget->systemSupportsUnalignedAccess())931    return false;932 933  // Get the value to be stored into a register.934  SrcReg = getRegForValue(Op0);935  if (SrcReg == 0)936    return false;937 938  // See if we can handle this address.939  Address Addr;940  if (!computeAddress(SI->getOperand(1), Addr))941    return false;942 943  if (!emitStore(VT, SrcReg, Addr))944    return false;945  return true;946}947 948// This can cause a redundant sltiu to be generated.949// FIXME: try and eliminate this in a future patch.950bool MipsFastISel::selectBranch(const Instruction *I) {951  const BranchInst *BI = cast<BranchInst>(I);952  MachineBasicBlock *BrBB = FuncInfo.MBB;953  //954  // TBB is the basic block for the case where the comparison is true.955  // FBB is the basic block for the case where the comparison is false.956  // if (cond) goto TBB957  // goto FBB958  // TBB:959  //960  MachineBasicBlock *TBB = FuncInfo.getMBB(BI->getSuccessor(0));961  MachineBasicBlock *FBB = FuncInfo.getMBB(BI->getSuccessor(1));962 963  // Fold the common case of a conditional branch with a comparison964  // in the same block.965  unsigned ZExtCondReg = 0;966  if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {967    if (CI->hasOneUse() && CI->getParent() == I->getParent()) {968      ZExtCondReg = createResultReg(&Mips::GPR32RegClass);969      if (!emitCmp(ZExtCondReg, CI))970        return false;971    }972  }973 974  // For the general case, we need to mask with 1.975  if (ZExtCondReg == 0) {976    Register CondReg = getRegForValue(BI->getCondition());977    if (CondReg == 0)978      return false;979 980    ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32, true);981    if (ZExtCondReg == 0)982      return false;983  }984 985  BuildMI(*BrBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::BGTZ))986      .addReg(ZExtCondReg)987      .addMBB(TBB);988  finishCondBranch(BI->getParent(), TBB, FBB);989  return true;990}991 992bool MipsFastISel::selectCmp(const Instruction *I) {993  const CmpInst *CI = cast<CmpInst>(I);994  Register ResultReg = createResultReg(&Mips::GPR32RegClass);995  if (!emitCmp(ResultReg, CI))996    return false;997  updateValueMap(I, ResultReg);998  return true;999}1000 1001// Attempt to fast-select a floating-point extend instruction.1002bool MipsFastISel::selectFPExt(const Instruction *I) {1003  if (UnsupportedFPMode)1004    return false;1005  Value *Src = I->getOperand(0);1006  EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);1007  EVT DestVT = TLI.getValueType(DL, I->getType(), true);1008 1009  if (SrcVT != MVT::f32 || DestVT != MVT::f64)1010    return false;1011 1012  Register SrcReg =1013      getRegForValue(Src); // this must be a 32bit floating point register class1014                           // maybe we should handle this differently1015  if (!SrcReg)1016    return false;1017 1018  Register DestReg = createResultReg(&Mips::AFGR64RegClass);1019  emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);1020  updateValueMap(I, DestReg);1021  return true;1022}1023 1024bool MipsFastISel::selectSelect(const Instruction *I) {1025  assert(isa<SelectInst>(I) && "Expected a select instruction.");1026 1027  LLVM_DEBUG(dbgs() << "selectSelect\n");1028 1029  MVT VT;1030  if (!isTypeSupported(I->getType(), VT) || UnsupportedFPMode) {1031    LLVM_DEBUG(1032        dbgs() << ".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");1033    return false;1034  }1035 1036  unsigned CondMovOpc;1037  const TargetRegisterClass *RC;1038 1039  if (VT.isInteger() && !VT.isVector() && VT.getSizeInBits() <= 32) {1040    CondMovOpc = Mips::MOVN_I_I;1041    RC = &Mips::GPR32RegClass;1042  } else if (VT == MVT::f32) {1043    CondMovOpc = Mips::MOVN_I_S;1044    RC = &Mips::FGR32RegClass;1045  } else if (VT == MVT::f64) {1046    CondMovOpc = Mips::MOVN_I_D32;1047    RC = &Mips::AFGR64RegClass;1048  } else1049    return false;1050 1051  const SelectInst *SI = cast<SelectInst>(I);1052  const Value *Cond = SI->getCondition();1053  Register Src1Reg = getRegForValue(SI->getTrueValue());1054  Register Src2Reg = getRegForValue(SI->getFalseValue());1055  Register CondReg = getRegForValue(Cond);1056 1057  if (!Src1Reg || !Src2Reg || !CondReg)1058    return false;1059 1060  Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);1061  if (!ZExtCondReg)1062    return false;1063 1064  if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg, true))1065    return false;1066 1067  Register ResultReg = createResultReg(RC);1068  Register TempReg = createResultReg(RC);1069 1070  if (!ResultReg || !TempReg)1071    return false;1072 1073  emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);1074  emitInst(CondMovOpc, ResultReg)1075    .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);1076  updateValueMap(I, ResultReg);1077  return true;1078}1079 1080// Attempt to fast-select a floating-point truncate instruction.1081bool MipsFastISel::selectFPTrunc(const Instruction *I) {1082  if (UnsupportedFPMode)1083    return false;1084  Value *Src = I->getOperand(0);1085  EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);1086  EVT DestVT = TLI.getValueType(DL, I->getType(), true);1087 1088  if (SrcVT != MVT::f64 || DestVT != MVT::f32)1089    return false;1090 1091  Register SrcReg = getRegForValue(Src);1092  if (!SrcReg)1093    return false;1094 1095  Register DestReg = createResultReg(&Mips::FGR32RegClass);1096  if (!DestReg)1097    return false;1098 1099  emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);1100  updateValueMap(I, DestReg);1101  return true;1102}1103 1104// Attempt to fast-select a floating-point-to-integer conversion.1105bool MipsFastISel::selectFPToInt(const Instruction *I, bool IsSigned) {1106  if (UnsupportedFPMode)1107    return false;1108  MVT DstVT, SrcVT;1109  if (!IsSigned)1110    return false; // We don't handle this case yet. There is no native1111                  // instruction for this but it can be synthesized.1112  Type *DstTy = I->getType();1113  if (!isTypeLegal(DstTy, DstVT))1114    return false;1115 1116  if (DstVT != MVT::i32)1117    return false;1118 1119  Value *Src = I->getOperand(0);1120  Type *SrcTy = Src->getType();1121  if (!isTypeLegal(SrcTy, SrcVT))1122    return false;1123 1124  if (SrcVT != MVT::f32 && SrcVT != MVT::f64)1125    return false;1126 1127  Register SrcReg = getRegForValue(Src);1128  if (SrcReg == 0)1129    return false;1130 1131  // Determine the opcode for the conversion, which takes place1132  // entirely within FPRs.1133  Register DestReg = createResultReg(&Mips::GPR32RegClass);1134  Register TempReg = createResultReg(&Mips::FGR32RegClass);1135  unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;1136 1137  // Generate the convert.1138  emitInst(Opc, TempReg).addReg(SrcReg);1139  emitInst(Mips::MFC1, DestReg).addReg(TempReg);1140 1141  updateValueMap(I, DestReg);1142  return true;1143}1144 1145bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,1146                                   SmallVectorImpl<MVT> &OutVTs,1147                                   unsigned &NumBytes) {1148  CallingConv::ID CC = CLI.CallConv;1149  SmallVector<CCValAssign, 16> ArgLocs;1150  SmallVector<Type *, 16> ArgTys;1151  for (const ArgListEntry &Arg : CLI.Args)1152    ArgTys.push_back(Arg.Val->getType());1153  CCState CCInfo(CC, false, *FuncInfo.MF, ArgLocs, *Context);1154  CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,1155                             CCAssignFnForCall(CC));1156  // Get a count of how many bytes are to be pushed on the stack.1157  NumBytes = CCInfo.getStackSize();1158  // This is the minimum argument area used for A0-A3.1159  if (NumBytes < 16)1160    NumBytes = 16;1161 1162  emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);1163  // Process the args.1164  MVT firstMVT;1165  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {1166    CCValAssign &VA = ArgLocs[i];1167    const Value *ArgVal = CLI.OutVals[VA.getValNo()];1168    MVT ArgVT = OutVTs[VA.getValNo()];1169 1170    if (i == 0) {1171      firstMVT = ArgVT;1172      if (ArgVT == MVT::f32) {1173        VA.convertToReg(Mips::F12);1174      } else if (ArgVT == MVT::f64) {1175        if (Subtarget->isFP64bit())1176          VA.convertToReg(Mips::D6_64);1177        else1178          VA.convertToReg(Mips::D6);1179      }1180    } else if (i == 1) {1181      if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {1182        if (ArgVT == MVT::f32) {1183          VA.convertToReg(Mips::F14);1184        } else if (ArgVT == MVT::f64) {1185          if (Subtarget->isFP64bit())1186            VA.convertToReg(Mips::D7_64);1187          else1188            VA.convertToReg(Mips::D7);1189        }1190      }1191    }1192    if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||1193         (ArgVT == MVT::i8)) &&1194        VA.isMemLoc()) {1195      switch (VA.getLocMemOffset()) {1196      case 0:1197        VA.convertToReg(Mips::A0);1198        break;1199      case 4:1200        VA.convertToReg(Mips::A1);1201        break;1202      case 8:1203        VA.convertToReg(Mips::A2);1204        break;1205      case 12:1206        VA.convertToReg(Mips::A3);1207        break;1208      default:1209        break;1210      }1211    }1212    Register ArgReg = getRegForValue(ArgVal);1213    if (!ArgReg)1214      return false;1215 1216    // Handle arg promotion: SExt, ZExt, AExt.1217    switch (VA.getLocInfo()) {1218    case CCValAssign::Full:1219      break;1220    case CCValAssign::AExt:1221    case CCValAssign::SExt: {1222      MVT DestVT = VA.getLocVT();1223      MVT SrcVT = ArgVT;1224      ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, /*isZExt=*/false);1225      if (!ArgReg)1226        return false;1227      break;1228    }1229    case CCValAssign::ZExt: {1230      MVT DestVT = VA.getLocVT();1231      MVT SrcVT = ArgVT;1232      ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, /*isZExt=*/true);1233      if (!ArgReg)1234        return false;1235      break;1236    }1237    default:1238      llvm_unreachable("Unknown arg promotion!");1239    }1240 1241    // Now copy/store arg to correct locations.1242    if (VA.isRegLoc() && !VA.needsCustom()) {1243      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,1244              TII.get(TargetOpcode::COPY), VA.getLocReg()).addReg(ArgReg);1245      CLI.OutRegs.push_back(VA.getLocReg());1246    } else if (VA.needsCustom()) {1247      llvm_unreachable("Mips does not use custom args.");1248      return false;1249    } else {1250      //1251      // FIXME: This path will currently return false. It was copied1252      // from the AArch64 port and should be essentially fine for Mips too.1253      // The work to finish up this path will be done in a follow-on patch.1254      //1255      assert(VA.isMemLoc() && "Assuming store on stack.");1256      // Don't emit stores for undef values.1257      if (isa<UndefValue>(ArgVal))1258        continue;1259 1260      // Need to store on the stack.1261      // FIXME: This alignment is incorrect but this path is disabled1262      // for now (will return false). We need to determine the right alignment1263      // based on the normal alignment for the underlying machine type.1264      //1265      unsigned ArgSize = alignTo(ArgVT.getSizeInBits(), 4);1266 1267      unsigned BEAlign = 0;1268      if (ArgSize < 8 && !Subtarget->isLittle())1269        BEAlign = 8 - ArgSize;1270 1271      Address Addr;1272      Addr.setKind(Address::RegBase);1273      Addr.setReg(Mips::SP);1274      Addr.setOffset(VA.getLocMemOffset() + BEAlign);1275 1276      Align Alignment = DL.getABITypeAlign(ArgVal->getType());1277      MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(1278          MachinePointerInfo::getStack(*FuncInfo.MF, Addr.getOffset()),1279          MachineMemOperand::MOStore, ArgVT.getStoreSize(), Alignment);1280      (void)(MMO);1281      // if (!emitStore(ArgVT, ArgReg, Addr, MMO))1282      return false; // can't store on the stack yet.1283    }1284  }1285 1286  return true;1287}1288 1289bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,1290                              unsigned NumBytes) {1291  CallingConv::ID CC = CLI.CallConv;1292  emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);1293  if (RetVT != MVT::isVoid) {1294    SmallVector<CCValAssign, 16> RVLocs;1295    MipsCCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);1296 1297    CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);1298 1299    // Only handle a single return value.1300    if (RVLocs.size() != 1)1301      return false;1302    // Copy all of the result registers out of their specified physreg.1303    MVT CopyVT = RVLocs[0].getValVT();1304    // Special handling for extended integers.1305    if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)1306      CopyVT = MVT::i32;1307 1308    Register ResultReg = createResultReg(TLI.getRegClassFor(CopyVT));1309    if (!ResultReg)1310      return false;1311    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,1312            TII.get(TargetOpcode::COPY),1313            ResultReg).addReg(RVLocs[0].getLocReg());1314    CLI.InRegs.push_back(RVLocs[0].getLocReg());1315 1316    CLI.ResultReg = ResultReg;1317    CLI.NumResultRegs = 1;1318  }1319  return true;1320}1321 1322bool MipsFastISel::fastLowerArguments() {1323  LLVM_DEBUG(dbgs() << "fastLowerArguments\n");1324 1325  if (!FuncInfo.CanLowerReturn) {1326    LLVM_DEBUG(dbgs() << ".. gave up (!CanLowerReturn)\n");1327    return false;1328  }1329 1330  const Function *F = FuncInfo.Fn;1331  if (F->isVarArg()) {1332    LLVM_DEBUG(dbgs() << ".. gave up (varargs)\n");1333    return false;1334  }1335 1336  CallingConv::ID CC = F->getCallingConv();1337  if (CC != CallingConv::C) {1338    LLVM_DEBUG(dbgs() << ".. gave up (calling convention is not C)\n");1339    return false;1340  }1341 1342  std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,1343                                           Mips::A3}};1344  std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};1345  std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};1346  auto NextGPR32 = GPR32ArgRegs.begin();1347  auto NextFGR32 = FGR32ArgRegs.begin();1348  auto NextAFGR64 = AFGR64ArgRegs.begin();1349 1350  struct AllocatedReg {1351    const TargetRegisterClass *RC;1352    unsigned Reg;1353    AllocatedReg(const TargetRegisterClass *RC, unsigned Reg)1354        : RC(RC), Reg(Reg) {}1355  };1356 1357  // Only handle simple cases. i.e. All arguments are directly mapped to1358  // registers of the appropriate type.1359  SmallVector<AllocatedReg, 4> Allocation;1360  for (const auto &FormalArg : F->args()) {1361    if (FormalArg.hasAttribute(Attribute::InReg) ||1362        FormalArg.hasAttribute(Attribute::StructRet) ||1363        FormalArg.hasAttribute(Attribute::ByVal)) {1364      LLVM_DEBUG(dbgs() << ".. gave up (inreg, structret, byval)\n");1365      return false;1366    }1367 1368    Type *ArgTy = FormalArg.getType();1369    if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {1370      LLVM_DEBUG(dbgs() << ".. gave up (struct, array, or vector)\n");1371      return false;1372    }1373 1374    EVT ArgVT = TLI.getValueType(DL, ArgTy);1375    LLVM_DEBUG(dbgs() << ".. " << FormalArg.getArgNo() << ": "1376                      << ArgVT << "\n");1377    if (!ArgVT.isSimple()) {1378      LLVM_DEBUG(dbgs() << ".. .. gave up (not a simple type)\n");1379      return false;1380    }1381 1382    switch (ArgVT.getSimpleVT().SimpleTy) {1383    case MVT::i1:1384    case MVT::i8:1385    case MVT::i16:1386      if (!FormalArg.hasAttribute(Attribute::SExt) &&1387          !FormalArg.hasAttribute(Attribute::ZExt)) {1388        // It must be any extend, this shouldn't happen for clang-generated IR1389        // so just fall back on SelectionDAG.1390        LLVM_DEBUG(dbgs() << ".. .. gave up (i8/i16 arg is not extended)\n");1391        return false;1392      }1393 1394      if (NextGPR32 == GPR32ArgRegs.end()) {1395        LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");1396        return false;1397      }1398 1399      LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");1400      Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);1401 1402      // Allocating any GPR32 prohibits further use of floating point arguments.1403      NextFGR32 = FGR32ArgRegs.end();1404      NextAFGR64 = AFGR64ArgRegs.end();1405      break;1406 1407    case MVT::i32:1408      if (FormalArg.hasAttribute(Attribute::ZExt)) {1409        // The O32 ABI does not permit a zero-extended i32.1410        LLVM_DEBUG(dbgs() << ".. .. gave up (i32 arg is zero extended)\n");1411        return false;1412      }1413 1414      if (NextGPR32 == GPR32ArgRegs.end()) {1415        LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");1416        return false;1417      }1418 1419      LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");1420      Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);1421 1422      // Allocating any GPR32 prohibits further use of floating point arguments.1423      NextFGR32 = FGR32ArgRegs.end();1424      NextAFGR64 = AFGR64ArgRegs.end();1425      break;1426 1427    case MVT::f32:1428      if (UnsupportedFPMode) {1429        LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");1430        return false;1431      }1432      if (NextFGR32 == FGR32ArgRegs.end()) {1433        LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of FGR32 arguments)\n");1434        return false;1435      }1436      LLVM_DEBUG(dbgs() << ".. .. FGR32(" << *NextFGR32 << ")\n");1437      Allocation.emplace_back(&Mips::FGR32RegClass, *NextFGR32++);1438      // Allocating an FGR32 also allocates the super-register AFGR64, and1439      // ABI rules require us to skip the corresponding GPR32.1440      if (NextGPR32 != GPR32ArgRegs.end())1441        NextGPR32++;1442      if (NextAFGR64 != AFGR64ArgRegs.end())1443        NextAFGR64++;1444      break;1445 1446    case MVT::f64:1447      if (UnsupportedFPMode) {1448        LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");1449        return false;1450      }1451      if (NextAFGR64 == AFGR64ArgRegs.end()) {1452        LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of AFGR64 arguments)\n");1453        return false;1454      }1455      LLVM_DEBUG(dbgs() << ".. .. AFGR64(" << *NextAFGR64 << ")\n");1456      Allocation.emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);1457      // Allocating an FGR32 also allocates the super-register AFGR64, and1458      // ABI rules require us to skip the corresponding GPR32 pair.1459      if (NextGPR32 != GPR32ArgRegs.end())1460        NextGPR32++;1461      if (NextGPR32 != GPR32ArgRegs.end())1462        NextGPR32++;1463      if (NextFGR32 != FGR32ArgRegs.end())1464        NextFGR32++;1465      break;1466 1467    default:1468      LLVM_DEBUG(dbgs() << ".. .. gave up (unknown type)\n");1469      return false;1470    }1471  }1472 1473  for (const auto &FormalArg : F->args()) {1474    unsigned ArgNo = FormalArg.getArgNo();1475    unsigned SrcReg = Allocation[ArgNo].Reg;1476    Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);1477    // FIXME: Unfortunately it's necessary to emit a copy from the livein copy.1478    // Without this, EmitLiveInCopies may eliminate the livein if its only1479    // use is a bitcast (which isn't turned into an instruction).1480    Register ResultReg = createResultReg(Allocation[ArgNo].RC);1481    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,1482            TII.get(TargetOpcode::COPY), ResultReg)1483        .addReg(DstReg, getKillRegState(true));1484    updateValueMap(&FormalArg, ResultReg);1485  }1486 1487  // Calculate the size of the incoming arguments area.1488  // We currently reject all the cases where this would be non-zero.1489  unsigned IncomingArgSizeInBytes = 0;1490 1491  // Account for the reserved argument area on ABI's that have one (O32).1492  // It seems strange to do this on the caller side but it's necessary in1493  // SelectionDAG's implementation.1494  IncomingArgSizeInBytes = std::min(getABI().GetCalleeAllocdArgSizeInBytes(CC),1495                                    IncomingArgSizeInBytes);1496 1497  MF->getInfo<MipsFunctionInfo>()->setFormalArgInfo(IncomingArgSizeInBytes,1498                                                    false);1499 1500  return true;1501}1502 1503bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {1504  CallingConv::ID CC = CLI.CallConv;1505  bool IsTailCall = CLI.IsTailCall;1506  bool IsVarArg = CLI.IsVarArg;1507  const Value *Callee = CLI.Callee;1508  MCSymbol *Symbol = CLI.Symbol;1509 1510  // Do not handle FastCC.1511  if (CC == CallingConv::Fast)1512    return false;1513 1514  // Allow SelectionDAG isel to handle tail calls.1515  if (IsTailCall)1516    return false;1517 1518  // Let SDISel handle vararg functions.1519  if (IsVarArg)1520    return false;1521 1522  // FIXME: Only handle *simple* calls for now.1523  MVT RetVT;1524  if (CLI.RetTy->isVoidTy())1525    RetVT = MVT::isVoid;1526  else if (!isTypeSupported(CLI.RetTy, RetVT))1527    return false;1528 1529  for (auto Flag : CLI.OutFlags)1530    if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal())1531      return false;1532 1533  // Set up the argument vectors.1534  SmallVector<MVT, 16> OutVTs;1535  OutVTs.reserve(CLI.OutVals.size());1536 1537  for (auto *Val : CLI.OutVals) {1538    MVT VT;1539    if (!isTypeLegal(Val->getType(), VT) &&1540        !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))1541      return false;1542 1543    // We don't handle vector parameters yet.1544    if (VT.isVector() || VT.getSizeInBits() > 64)1545      return false;1546 1547    OutVTs.push_back(VT);1548  }1549 1550  Address Addr;1551  if (!computeCallAddress(Callee, Addr))1552    return false;1553 1554  // Handle the arguments now that we've gotten them.1555  unsigned NumBytes;1556  if (!processCallArgs(CLI, OutVTs, NumBytes))1557    return false;1558 1559  if (!Addr.getGlobalValue())1560    return false;1561 1562  // Issue the call.1563  unsigned DestAddress;1564  if (Symbol)1565    DestAddress = materializeExternalCallSym(Symbol);1566  else1567    DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);1568  emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);1569  MachineInstrBuilder MIB =1570      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::JALR),1571              Mips::RA).addReg(Mips::T9);1572 1573  // Add implicit physical register uses to the call.1574  for (auto Reg : CLI.OutRegs)1575    MIB.addReg(Reg, RegState::Implicit);1576 1577  // Add a register mask with the call-preserved registers.1578  // Proper defs for return values will be added by setPhysRegsDeadExcept().1579  MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));1580 1581  CLI.Call = MIB;1582 1583  if (EmitJalrReloc && !Subtarget->inMips16Mode()) {1584    // Attach callee address to the instruction, let asm printer emit1585    // .reloc R_MIPS_JALR.1586    if (Symbol)1587      MIB.addSym(Symbol, MipsII::MO_JALR);1588    else1589      MIB.addSym(FuncInfo.MF->getContext().getOrCreateSymbol(1590	                   Addr.getGlobalValue()->getName()), MipsII::MO_JALR);1591  }1592 1593  // Finish off the call including any return values.1594  return finishCall(CLI, RetVT, NumBytes);1595}1596 1597bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {1598  switch (II->getIntrinsicID()) {1599  default:1600    return false;1601  case Intrinsic::bswap: {1602    Type *RetTy = II->getCalledFunction()->getReturnType();1603 1604    MVT VT;1605    if (!isTypeSupported(RetTy, VT))1606      return false;1607 1608    Register SrcReg = getRegForValue(II->getOperand(0));1609    if (SrcReg == 0)1610      return false;1611    Register DestReg = createResultReg(&Mips::GPR32RegClass);1612    if (DestReg == 0)1613      return false;1614    if (VT == MVT::i16) {1615      if (Subtarget->hasMips32r2()) {1616        emitInst(Mips::WSBH, DestReg).addReg(SrcReg);1617        updateValueMap(II, DestReg);1618        return true;1619      } else {1620        unsigned TempReg[3];1621        for (unsigned &R : TempReg) {1622          R = createResultReg(&Mips::GPR32RegClass);1623          if (R == 0)1624            return false;1625        }1626        emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);1627        emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);1628        emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);1629        emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);1630        updateValueMap(II, DestReg);1631        return true;1632      }1633    } else if (VT == MVT::i32) {1634      if (Subtarget->hasMips32r2()) {1635        Register TempReg = createResultReg(&Mips::GPR32RegClass);1636        emitInst(Mips::WSBH, TempReg).addReg(SrcReg);1637        emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);1638        updateValueMap(II, DestReg);1639        return true;1640      } else {1641        unsigned TempReg[8];1642        for (unsigned &R : TempReg) {1643          R = createResultReg(&Mips::GPR32RegClass);1644          if (R == 0)1645            return false;1646        }1647 1648        emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);1649        emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);1650        emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);1651        emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);1652 1653        emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);1654        emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);1655 1656        emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);1657        emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);1658        emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);1659        updateValueMap(II, DestReg);1660        return true;1661      }1662    }1663    return false;1664  }1665  case Intrinsic::memcpy:1666  case Intrinsic::memmove: {1667    const auto *MTI = cast<MemTransferInst>(II);1668    // Don't handle volatile.1669    if (MTI->isVolatile())1670      return false;1671    if (!MTI->getLength()->getType()->isIntegerTy(32))1672      return false;1673    const char *IntrMemName = isa<MemCpyInst>(II) ? "memcpy" : "memmove";1674    return lowerCallTo(II, IntrMemName, II->arg_size() - 1);1675  }1676  case Intrinsic::memset: {1677    const MemSetInst *MSI = cast<MemSetInst>(II);1678    // Don't handle volatile.1679    if (MSI->isVolatile())1680      return false;1681    if (!MSI->getLength()->getType()->isIntegerTy(32))1682      return false;1683    return lowerCallTo(II, "memset", II->arg_size() - 1);1684  }1685  }1686  return false;1687}1688 1689bool MipsFastISel::selectRet(const Instruction *I) {1690  const Function &F = *I->getParent()->getParent();1691  const ReturnInst *Ret = cast<ReturnInst>(I);1692 1693  LLVM_DEBUG(dbgs() << "selectRet\n");1694 1695  if (!FuncInfo.CanLowerReturn)1696    return false;1697 1698  // Build a list of return value registers.1699  SmallVector<unsigned, 4> RetRegs;1700 1701  if (Ret->getNumOperands() > 0) {1702    CallingConv::ID CC = F.getCallingConv();1703 1704    // Do not handle FastCC.1705    if (CC == CallingConv::Fast)1706      return false;1707 1708    SmallVector<ISD::OutputArg, 4> Outs;1709    GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);1710 1711    // Analyze operands of the call, assigning locations to each operand.1712    SmallVector<CCValAssign, 16> ValLocs;1713    MipsCCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs,1714                       I->getContext());1715    CCAssignFn *RetCC = RetCC_Mips;1716    CCInfo.AnalyzeReturn(Outs, RetCC);1717 1718    // Only handle a single return value for now.1719    if (ValLocs.size() != 1)1720      return false;1721 1722    CCValAssign &VA = ValLocs[0];1723    const Value *RV = Ret->getOperand(0);1724 1725    // Don't bother handling odd stuff for now.1726    if ((VA.getLocInfo() != CCValAssign::Full) &&1727        (VA.getLocInfo() != CCValAssign::BCvt))1728      return false;1729 1730    // Only handle register returns for now.1731    if (!VA.isRegLoc())1732      return false;1733 1734    Register Reg = getRegForValue(RV);1735    if (Reg == 0)1736      return false;1737 1738    unsigned SrcReg = Reg + VA.getValNo();1739    Register DestReg = VA.getLocReg();1740    // Avoid a cross-class copy. This is very unlikely.1741    if (!MRI.getRegClass(SrcReg)->contains(DestReg))1742      return false;1743 1744    EVT RVEVT = TLI.getValueType(DL, RV->getType());1745    if (!RVEVT.isSimple())1746      return false;1747 1748    if (RVEVT.isVector())1749      return false;1750 1751    MVT RVVT = RVEVT.getSimpleVT();1752    if (RVVT == MVT::f128)1753      return false;1754 1755    // Do not handle FGR64 returns for now.1756    if (RVVT == MVT::f64 && UnsupportedFPMode) {1757      LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode\n");1758      return false;1759    }1760 1761    MVT DestVT = VA.getValVT();1762    // Special handling for extended integers.1763    if (RVVT != DestVT) {1764      if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)1765        return false;1766 1767      if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) {1768        bool IsZExt = Outs[0].Flags.isZExt();1769        SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);1770        if (SrcReg == 0)1771          return false;1772      }1773    }1774 1775    // Make the copy.1776    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,1777            TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);1778 1779    // Add register to return instruction.1780    RetRegs.push_back(VA.getLocReg());1781  }1782  MachineInstrBuilder MIB = emitInst(Mips::RetRA);1783  for (unsigned Reg : RetRegs)1784    MIB.addReg(Reg, RegState::Implicit);1785  return true;1786}1787 1788bool MipsFastISel::selectTrunc(const Instruction *I) {1789  // The high bits for a type smaller than the register size are assumed to be1790  // undefined.1791  Value *Op = I->getOperand(0);1792 1793  EVT SrcVT, DestVT;1794  SrcVT = TLI.getValueType(DL, Op->getType(), true);1795  DestVT = TLI.getValueType(DL, I->getType(), true);1796 1797  if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)1798    return false;1799  if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)1800    return false;1801 1802  Register SrcReg = getRegForValue(Op);1803  if (!SrcReg)1804    return false;1805 1806  // Because the high bits are undefined, a truncate doesn't generate1807  // any code.1808  updateValueMap(I, SrcReg);1809  return true;1810}1811 1812bool MipsFastISel::selectIntExt(const Instruction *I) {1813  Type *DestTy = I->getType();1814  Value *Src = I->getOperand(0);1815  Type *SrcTy = Src->getType();1816 1817  bool isZExt = isa<ZExtInst>(I);1818  Register SrcReg = getRegForValue(Src);1819  if (!SrcReg)1820    return false;1821 1822  EVT SrcEVT, DestEVT;1823  SrcEVT = TLI.getValueType(DL, SrcTy, true);1824  DestEVT = TLI.getValueType(DL, DestTy, true);1825  if (!SrcEVT.isSimple())1826    return false;1827  if (!DestEVT.isSimple())1828    return false;1829 1830  MVT SrcVT = SrcEVT.getSimpleVT();1831  MVT DestVT = DestEVT.getSimpleVT();1832  Register ResultReg = createResultReg(&Mips::GPR32RegClass);1833 1834  if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))1835    return false;1836  updateValueMap(I, ResultReg);1837  return true;1838}1839 1840bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,1841                                   unsigned DestReg) {1842  unsigned ShiftAmt;1843  switch (SrcVT.SimpleTy) {1844  default:1845    return false;1846  case MVT::i8:1847    ShiftAmt = 24;1848    break;1849  case MVT::i16:1850    ShiftAmt = 16;1851    break;1852  }1853  Register TempReg = createResultReg(&Mips::GPR32RegClass);1854  emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);1855  emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);1856  return true;1857}1858 1859bool MipsFastISel::emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,1860                                   unsigned DestReg) {1861  switch (SrcVT.SimpleTy) {1862  default:1863    return false;1864  case MVT::i8:1865    emitInst(Mips::SEB, DestReg).addReg(SrcReg);1866    break;1867  case MVT::i16:1868    emitInst(Mips::SEH, DestReg).addReg(SrcReg);1869    break;1870  }1871  return true;1872}1873 1874bool MipsFastISel::emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,1875                               unsigned DestReg) {1876  if ((DestVT != MVT::i32) && (DestVT != MVT::i16))1877    return false;1878  if (Subtarget->hasMips32r2())1879    return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);1880  return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);1881}1882 1883bool MipsFastISel::emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,1884                               unsigned DestReg) {1885  int64_t Imm;1886 1887  switch (SrcVT.SimpleTy) {1888  default:1889    return false;1890  case MVT::i1:1891    Imm = 1;1892    break;1893  case MVT::i8:1894    Imm = 0xff;1895    break;1896  case MVT::i16:1897    Imm = 0xffff;1898    break;1899  }1900 1901  emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);1902  return true;1903}1904 1905bool MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,1906                              unsigned DestReg, bool IsZExt) {1907  // FastISel does not have plumbing to deal with extensions where the SrcVT or1908  // DestVT are odd things, so test to make sure that they are both types we can1909  // handle (i1/i8/i16/i32 for SrcVT and i8/i16/i32/i64 for DestVT), otherwise1910  // bail out to SelectionDAG.1911  if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||1912      ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))1913    return false;1914  if (IsZExt)1915    return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);1916  return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);1917}1918 1919unsigned MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,1920                                  bool isZExt) {1921  unsigned DestReg = createResultReg(&Mips::GPR32RegClass);1922  bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);1923  return Success ? DestReg : 0;1924}1925 1926bool MipsFastISel::selectDivRem(const Instruction *I, unsigned ISDOpcode) {1927  EVT DestEVT = TLI.getValueType(DL, I->getType(), true);1928  if (!DestEVT.isSimple())1929    return false;1930 1931  MVT DestVT = DestEVT.getSimpleVT();1932  if (DestVT != MVT::i32)1933    return false;1934 1935  unsigned DivOpc;1936  switch (ISDOpcode) {1937  default:1938    return false;1939  case ISD::SDIV:1940  case ISD::SREM:1941    DivOpc = Mips::SDIV;1942    break;1943  case ISD::UDIV:1944  case ISD::UREM:1945    DivOpc = Mips::UDIV;1946    break;1947  }1948 1949  Register Src0Reg = getRegForValue(I->getOperand(0));1950  Register Src1Reg = getRegForValue(I->getOperand(1));1951  if (!Src0Reg || !Src1Reg)1952    return false;1953 1954  emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);1955  if (!isa<ConstantInt>(I->getOperand(1)) ||1956      dyn_cast<ConstantInt>(I->getOperand(1))->isZero()) {1957    emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);1958  }1959 1960  Register ResultReg = createResultReg(&Mips::GPR32RegClass);1961  if (!ResultReg)1962    return false;1963 1964  unsigned MFOpc = (ISDOpcode == ISD::SREM || ISDOpcode == ISD::UREM)1965                       ? Mips::MFHI1966                       : Mips::MFLO;1967  emitInst(MFOpc, ResultReg);1968 1969  updateValueMap(I, ResultReg);1970  return true;1971}1972 1973bool MipsFastISel::selectShift(const Instruction *I) {1974  MVT RetVT;1975 1976  if (!isTypeSupported(I->getType(), RetVT))1977    return false;1978 1979  Register ResultReg = createResultReg(&Mips::GPR32RegClass);1980  if (!ResultReg)1981    return false;1982 1983  unsigned Opcode = I->getOpcode();1984  const Value *Op0 = I->getOperand(0);1985  Register Op0Reg = getRegForValue(Op0);1986  if (!Op0Reg)1987    return false;1988 1989  // If AShr or LShr, then we need to make sure the operand0 is sign extended.1990  if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {1991    Register TempReg = createResultReg(&Mips::GPR32RegClass);1992    if (!TempReg)1993      return false;1994 1995    MVT Op0MVT = TLI.getValueType(DL, Op0->getType(), true).getSimpleVT();1996    bool IsZExt = Opcode == Instruction::LShr;1997    if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))1998      return false;1999 2000    Op0Reg = TempReg;2001  }2002 2003  if (const auto *C = dyn_cast<ConstantInt>(I->getOperand(1))) {2004    uint64_t ShiftVal = C->getZExtValue();2005 2006    switch (Opcode) {2007    default:2008      llvm_unreachable("Unexpected instruction.");2009    case Instruction::Shl:2010      Opcode = Mips::SLL;2011      break;2012    case Instruction::AShr:2013      Opcode = Mips::SRA;2014      break;2015    case Instruction::LShr:2016      Opcode = Mips::SRL;2017      break;2018    }2019 2020    emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);2021    updateValueMap(I, ResultReg);2022    return true;2023  }2024 2025  Register Op1Reg = getRegForValue(I->getOperand(1));2026  if (!Op1Reg)2027    return false;2028 2029  switch (Opcode) {2030  default:2031    llvm_unreachable("Unexpected instruction.");2032  case Instruction::Shl:2033    Opcode = Mips::SLLV;2034    break;2035  case Instruction::AShr:2036    Opcode = Mips::SRAV;2037    break;2038  case Instruction::LShr:2039    Opcode = Mips::SRLV;2040    break;2041  }2042 2043  emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);2044  updateValueMap(I, ResultReg);2045  return true;2046}2047 2048bool MipsFastISel::fastSelectInstruction(const Instruction *I) {2049  switch (I->getOpcode()) {2050  default:2051    break;2052  case Instruction::Load:2053    return selectLoad(I);2054  case Instruction::Store:2055    return selectStore(I);2056  case Instruction::SDiv:2057    if (!selectBinaryOp(I, ISD::SDIV))2058      return selectDivRem(I, ISD::SDIV);2059    return true;2060  case Instruction::UDiv:2061    if (!selectBinaryOp(I, ISD::UDIV))2062      return selectDivRem(I, ISD::UDIV);2063    return true;2064  case Instruction::SRem:2065    if (!selectBinaryOp(I, ISD::SREM))2066      return selectDivRem(I, ISD::SREM);2067    return true;2068  case Instruction::URem:2069    if (!selectBinaryOp(I, ISD::UREM))2070      return selectDivRem(I, ISD::UREM);2071    return true;2072  case Instruction::Shl:2073  case Instruction::LShr:2074  case Instruction::AShr:2075    return selectShift(I);2076  case Instruction::And:2077  case Instruction::Or:2078  case Instruction::Xor:2079    return selectLogicalOp(I);2080  case Instruction::Br:2081    return selectBranch(I);2082  case Instruction::Ret:2083    return selectRet(I);2084  case Instruction::Trunc:2085    return selectTrunc(I);2086  case Instruction::ZExt:2087  case Instruction::SExt:2088    return selectIntExt(I);2089  case Instruction::FPTrunc:2090    return selectFPTrunc(I);2091  case Instruction::FPExt:2092    return selectFPExt(I);2093  case Instruction::FPToSI:2094    return selectFPToInt(I, /*isSigned*/ true);2095  case Instruction::FPToUI:2096    return selectFPToInt(I, /*isSigned*/ false);2097  case Instruction::ICmp:2098  case Instruction::FCmp:2099    return selectCmp(I);2100  case Instruction::Select:2101    return selectSelect(I);2102  }2103  return false;2104}2105 2106unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(const Value *V,2107                                                           bool IsUnsigned) {2108  Register VReg = getRegForValue(V);2109  if (VReg == 0)2110    return 0;2111  MVT VMVT = TLI.getValueType(DL, V->getType(), true).getSimpleVT();2112 2113  if (VMVT == MVT::i1)2114    return 0;2115 2116  if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {2117    Register TempReg = createResultReg(&Mips::GPR32RegClass);2118    if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))2119      return 0;2120    VReg = TempReg;2121  }2122  return VReg;2123}2124 2125void MipsFastISel::simplifyAddress(Address &Addr) {2126  if (!isInt<16>(Addr.getOffset())) {2127    unsigned TempReg =2128        materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);2129    Register DestReg = createResultReg(&Mips::GPR32RegClass);2130    emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());2131    Addr.setReg(DestReg);2132    Addr.setOffset(0);2133  }2134}2135 2136unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,2137                                       const TargetRegisterClass *RC,2138                                       unsigned Op0, unsigned Op1) {2139  // We treat the MUL instruction in a special way because it clobbers2140  // the HI0 & LO0 registers. The TableGen definition of this instruction can2141  // mark these registers only as implicitly defined. As a result, the2142  // register allocator runs out of registers when this instruction is2143  // followed by another instruction that defines the same registers too.2144  // We can fix this by explicitly marking those registers as dead.2145  if (MachineInstOpcode == Mips::MUL) {2146    Register ResultReg = createResultReg(RC);2147    const MCInstrDesc &II = TII.get(MachineInstOpcode);2148    Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs());2149    Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1);2150    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)2151      .addReg(Op0)2152      .addReg(Op1)2153      .addReg(Mips::HI0, RegState::ImplicitDefine | RegState::Dead)2154      .addReg(Mips::LO0, RegState::ImplicitDefine | RegState::Dead);2155    return ResultReg;2156  }2157 2158  return FastISel::fastEmitInst_rr(MachineInstOpcode, RC, Op0, Op1);2159}2160 2161namespace llvm {2162 2163FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,2164                               const TargetLibraryInfo *libInfo) {2165  return new MipsFastISel(funcInfo, libInfo);2166}2167 2168} // end namespace llvm2169