//===-- PPCFastISel.cpp - PowerPC FastISel implementation -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the PowerPC-specific support for the FastISel class. Some
// of the target-specific code is generated by tablegen in the file
// PPCGenFastISel.inc, which is #included here.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/PPCPredicates.h"
#include "PPC.h"
#include "PPCCallingConv.h"
#include "PPCISelLowering.h"
#include "PPCMachineFunctionInfo.h"
#include "PPCSelectionDAGInfo.h"
#include "PPCSubtarget.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Operator.h"
#include "llvm/Target/TargetMachine.h"

//===----------------------------------------------------------------------===//
//
// TBD:
//   fastLowerArguments: Handle simple cases.
//   PPCMaterializeGV: Handle TLS.
//   SelectCall: Handle function pointers.
//   SelectCall: Handle multi-register return values.
//   SelectCall: Optimize away nops for local calls.
//   processCallArgs: Handle bit-converted arguments.
//   finishCall: Handle multi-register return values.
//   PPCComputeAddress: Handle parameter references as FrameIndex's.
//   PPCEmitCmp: Handle immediate as operand 1.
//   SelectCall: Handle small byval arguments.
//   SelectIntrinsicCall: Implement.
//   SelectSelect: Implement.
//   Consider factoring isTypeLegal into the base class.
//   Implement switches and jump tables.
//
//===----------------------------------------------------------------------===//
using namespace llvm;

#define DEBUG_TYPE "ppcfastisel"

namespace {

struct Address {
  enum {
    RegBase,
    FrameIndexBase
  } BaseType;

  union {
    unsigned Reg;
    int FI;
  } Base;

  int64_t Offset;

  // Innocuous defaults for our address.
  Address()
   : BaseType(RegBase), Offset(0) {
     Base.Reg = 0;
   }
};

class PPCFastISel final : public FastISel {

  const TargetMachine &TM;
  const PPCSubtarget *Subtarget;
  PPCFunctionInfo *PPCFuncInfo;
  const TargetInstrInfo &TII;
  const TargetLowering &TLI;
  LLVMContext *Context;

  public:
    explicit PPCFastISel(FunctionLoweringInfo &FuncInfo,
                         const TargetLibraryInfo *LibInfo,
                         const LibcallLoweringInfo *LibcallLowering)
        : FastISel(FuncInfo, LibInfo, LibcallLowering),
          TM(FuncInfo.MF->getTarget()),
          Subtarget(&FuncInfo.MF->getSubtarget<PPCSubtarget>()),
          PPCFuncInfo(FuncInfo.MF->getInfo<PPCFunctionInfo>()),
          TII(*Subtarget->getInstrInfo()), TLI(*Subtarget->getTargetLowering()),
          Context(&FuncInfo.Fn->getContext()) {}

    // Backend specific FastISel code.
  private:
    bool fastSelectInstruction(const Instruction *I) override;
    Register fastMaterializeConstant(const Constant *C) override;
    Register fastMaterializeAlloca(const AllocaInst *AI) override;
    bool tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
                             const LoadInst *LI) override;
    bool fastLowerArguments() override;
    Register fastEmit_i(MVT Ty, MVT RetTy, unsigned Opc, uint64_t Imm) override;
    Register fastEmitInst_ri(unsigned MachineInstOpcode,
                             const TargetRegisterClass *RC, Register Op0,
                             uint64_t Imm);
    Register fastEmitInst_r(unsigned MachineInstOpcode,
                            const TargetRegisterClass *RC, Register Op0);
    Register fastEmitInst_rr(unsigned MachineInstOpcode,
                             const TargetRegisterClass *RC, Register Op0,
                             Register Op1);

    bool fastLowerCall(CallLoweringInfo &CLI) override;

  // Instruction selection routines.
  private:
    bool SelectLoad(const Instruction *I);
    bool SelectStore(const Instruction *I);
    bool SelectBranch(const Instruction *I);
    bool SelectIndirectBr(const Instruction *I);
    bool SelectFPExt(const Instruction *I);
    bool SelectFPTrunc(const Instruction *I);
    bool SelectIToFP(const Instruction *I, bool IsSigned);
    bool SelectFPToI(const Instruction *I, bool IsSigned);
    bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode);
    bool SelectRet(const Instruction *I);
    bool SelectTrunc(const Instruction *I);
    bool SelectIntExt(const Instruction *I);

  // Utility routines.
  private:
    bool isTypeLegal(Type *Ty, MVT &VT);
    bool isLoadTypeLegal(Type *Ty, MVT &VT);
    bool isValueAvailable(const Value *V) const;
    bool isVSFRCRegClass(const TargetRegisterClass *RC) const {
      return RC->getID() == PPC::VSFRCRegClassID;
    }
    bool isVSSRCRegClass(const TargetRegisterClass *RC) const {
      return RC->getID() == PPC::VSSRCRegClassID;
    }
    Register copyRegToRegClass(const TargetRegisterClass *ToRC, Register SrcReg,
                               RegState Flag = {}, unsigned SubReg = 0) {
      Register TmpReg = createResultReg(ToRC);
      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
              TII.get(TargetOpcode::COPY), TmpReg).addReg(SrcReg, Flag, SubReg);
      return TmpReg;
    }
    bool PPCEmitCmp(const Value *Src1Value, const Value *Src2Value, bool isZExt,
                    Register DestReg, const PPC::Predicate Pred);
    bool PPCEmitLoad(MVT VT, Register &ResultReg, Address &Addr,
                     const TargetRegisterClass *RC, bool IsZExt = true,
                     unsigned FP64LoadOpc = PPC::LFD);
    bool PPCEmitStore(MVT VT, Register SrcReg, Address &Addr);
    bool PPCComputeAddress(const Value *Obj, Address &Addr);
    void PPCSimplifyAddress(Address &Addr, bool &UseOffset, Register &IndexReg);
    bool PPCEmitIntExt(MVT SrcVT, Register SrcReg, MVT DestVT, Register DestReg,
                       bool IsZExt);
    Register PPCMaterializeFP(const ConstantFP *CFP, MVT VT);
    Register PPCMaterializeGV(const GlobalValue *GV, MVT VT);
    Register PPCMaterializeInt(const ConstantInt *CI, MVT VT,
                               bool UseSExt = true);
    Register PPCMaterialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);
    Register PPCMaterialize64BitInt(int64_t Imm, const TargetRegisterClass *RC);
    Register PPCMoveToIntReg(const Instruction *I, MVT VT, Register SrcReg,
                             bool IsSigned);
    Register PPCMoveToFPReg(MVT VT, Register SrcReg, bool IsSigned);

  // Call handling routines.
  private:
    bool processCallArgs(SmallVectorImpl<Value *> &Args,
                         SmallVectorImpl<Register> &ArgRegs,
                         SmallVectorImpl<MVT> &ArgVTs,
                         SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
                         SmallVectorImpl<unsigned> &RegArgs, CallingConv::ID CC,
                         unsigned &NumBytes, bool IsVarArg);
    bool finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes);

  private:
  #include "PPCGenFastISel.inc"

};

} // end anonymous namespace

static std::optional<PPC::Predicate> getComparePred(CmpInst::Predicate Pred) {
    switch (Pred) {
    // These are not representable with any single compare.
    case CmpInst::FCMP_FALSE:
    case CmpInst::FCMP_TRUE:
    // Major concern about the following 6 cases is NaN result. The comparison
    // result consists of 4 bits, indicating lt, eq, gt and un (unordered),
    // only one of which will be set. The result is generated by fcmpu
    // instruction. However, bc instruction only inspects one of the first 3
    // bits, so when un is set, bc instruction may jump to an undesired
    // place.
    //
    // More specifically, if we expect an unordered comparison and un is set, we
    // expect to always go to true branch; in such case UEQ, UGT and ULT still
    // give false, which are undesired; but UNE, UGE, ULE happen to give true,
    // since they are tested by inspecting !eq, !lt, !gt, respectively.
    //
    // Similarly, for ordered comparison, when un is set, we always expect the
    // result to be false. In such case OGT, OLT and OEQ is good, since they are
    // actually testing GT, LT, and EQ respectively, which are false. OGE, OLE
    // and ONE are tested through !lt, !gt and !eq, and these are true.
    case CmpInst::FCMP_UEQ:
    case CmpInst::FCMP_UGT:
    case CmpInst::FCMP_ULT:
    case CmpInst::FCMP_OGE:
    case CmpInst::FCMP_OLE:
    case CmpInst::FCMP_ONE:
    default:
      return std::nullopt;

    case CmpInst::FCMP_OEQ:
    case CmpInst::ICMP_EQ:
      return PPC::PRED_EQ;

    case CmpInst::FCMP_OGT:
    case CmpInst::ICMP_UGT:
    case CmpInst::ICMP_SGT:
      return PPC::PRED_GT;

    case CmpInst::FCMP_UGE:
    case CmpInst::ICMP_UGE:
    case CmpInst::ICMP_SGE:
      return PPC::PRED_GE;

    case CmpInst::FCMP_OLT:
    case CmpInst::ICMP_ULT:
    case CmpInst::ICMP_SLT:
      return PPC::PRED_LT;

    case CmpInst::FCMP_ULE:
    case CmpInst::ICMP_ULE:
    case CmpInst::ICMP_SLE:
      return PPC::PRED_LE;

    case CmpInst::FCMP_UNE:
    case CmpInst::ICMP_NE:
      return PPC::PRED_NE;

    case CmpInst::FCMP_ORD:
      return PPC::PRED_NU;

    case CmpInst::FCMP_UNO:
      return PPC::PRED_UN;
  }
}

// Determine whether the type Ty is simple enough to be handled by
// fast-isel, and return its equivalent machine type in VT.
// FIXME: Copied directly from ARM -- factor into base class?
bool PPCFastISel::isTypeLegal(Type *Ty, MVT &VT) {
  EVT Evt = TLI.getValueType(DL, Ty, true);

  // Only handle simple types.
  if (Evt == MVT::Other || !Evt.isSimple()) return false;
  VT = Evt.getSimpleVT();

  // Handle all legal types, i.e. a register that will directly hold this
  // value.
  return TLI.isTypeLegal(VT);
}

// Determine whether the type Ty is simple enough to be handled by
// fast-isel as a load target, and return its equivalent machine type in VT.
bool PPCFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
  if (isTypeLegal(Ty, VT)) return true;

  // If this is a type than can be sign or zero-extended to a basic operation
  // go ahead and accept it now.
  if (VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) {
    return true;
  }

  return false;
}

bool PPCFastISel::isValueAvailable(const Value *V) const {
  if (!isa<Instruction>(V))
    return true;

  const auto *I = cast<Instruction>(V);
  return FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB;
}

// Given a value Obj, create an Address object Addr that represents its
// address.  Return false if we can't handle it.
bool PPCFastISel::PPCComputeAddress(const Value *Obj, Address &Addr) {
  const User *U = nullptr;
  unsigned Opcode = Instruction::UserOp1;
  if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
    // Don't walk into other basic blocks unless the object is an alloca from
    // another block, otherwise it may not have a virtual register assigned.
    if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
        FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {
      Opcode = I->getOpcode();
      U = I;
    }
  } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
    Opcode = C->getOpcode();
    U = C;
  }

  switch (Opcode) {
    default:
      break;
    case Instruction::BitCast:
      // Look through bitcasts.
      return PPCComputeAddress(U->getOperand(0), Addr);
    case Instruction::IntToPtr:
      // Look past no-op inttoptrs.
      if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==
          TLI.getPointerTy(DL))
        return PPCComputeAddress(U->getOperand(0), Addr);
      break;
    case Instruction::PtrToInt:
      // Look past no-op ptrtoints.
      if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
        return PPCComputeAddress(U->getOperand(0), Addr);
      break;
    case Instruction::GetElementPtr: {
      Address SavedAddr = Addr;
      int64_t TmpOffset = Addr.Offset;

      // Iterate through the GEP folding the constants into offsets where
      // we can.
      gep_type_iterator GTI = gep_type_begin(U);
      for (User::const_op_iterator II = U->op_begin() + 1, IE = U->op_end();
           II != IE; ++II, ++GTI) {
        const Value *Op = *II;
        if (StructType *STy = GTI.getStructTypeOrNull()) {
          const StructLayout *SL = DL.getStructLayout(STy);
          unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
          TmpOffset += SL->getElementOffset(Idx);
        } else {
          uint64_t S = GTI.getSequentialElementStride(DL);
          for (;;) {
            if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
              // Constant-offset addressing.
              TmpOffset += CI->getSExtValue() * S;
              break;
            }
            if (canFoldAddIntoGEP(U, Op)) {
              // A compatible add with a constant operand. Fold the constant.
              ConstantInt *CI =
              cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
              TmpOffset += CI->getSExtValue() * S;
              // Iterate on the other operand.
              Op = cast<AddOperator>(Op)->getOperand(0);
              continue;
            }
            // Unsupported
            goto unsupported_gep;
          }
        }
      }

      // Try to grab the base operand now.
      Addr.Offset = TmpOffset;
      if (PPCComputeAddress(U->getOperand(0), Addr)) return true;

      // We failed, restore everything and try the other options.
      Addr = SavedAddr;

      unsupported_gep:
      break;
    }
    case Instruction::Alloca: {
      const AllocaInst *AI = cast<AllocaInst>(Obj);
      auto SI = FuncInfo.StaticAllocaMap.find(AI);
      if (SI != FuncInfo.StaticAllocaMap.end()) {
        Addr.BaseType = Address::FrameIndexBase;
        Addr.Base.FI = SI->second;
        return true;
      }
      break;
    }
  }

  // FIXME: References to parameters fall through to the behavior
  // below.  They should be able to reference a frame index since
  // they are stored to the stack, so we can get "ld rx, offset(r1)"
  // instead of "addi ry, r1, offset / ld rx, 0(ry)".  Obj will
  // just contain the parameter.  Try to handle this with a FI.

  // Try to get this in a register if nothing else has worked.
  if (Addr.Base.Reg == 0)
    Addr.Base.Reg = getRegForValue(Obj);

  // Prevent assignment of base register to X0, which is inappropriate
  // for loads and stores alike.
  if (Addr.Base.Reg != 0)
    MRI.setRegClass(Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);

  return Addr.Base.Reg != 0;
}

// Fix up some addresses that can't be used directly.  For example, if
// an offset won't fit in an instruction field, we may need to move it
// into an index register.
void PPCFastISel::PPCSimplifyAddress(Address &Addr, bool &UseOffset,
                                     Register &IndexReg) {

  // Check whether the offset fits in the instruction field.
  if (!isInt<16>(Addr.Offset))
    UseOffset = false;

  // If this is a stack pointer and the offset needs to be simplified then
  // put the alloca address into a register, set the base type back to
  // register and continue. This should almost never happen.
  if (!UseOffset && Addr.BaseType == Address::FrameIndexBase) {
    Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDI8),
            ResultReg).addFrameIndex(Addr.Base.FI).addImm(0);
    Addr.Base.Reg = ResultReg;
    Addr.BaseType = Address::RegBase;
  }

  if (!UseOffset) {
    IntegerType *OffsetTy = Type::getInt64Ty(*Context);
    const ConstantInt *Offset = ConstantInt::getSigned(OffsetTy, Addr.Offset);
    IndexReg = PPCMaterializeInt(Offset, MVT::i64);
    assert(IndexReg && "Unexpected error in PPCMaterializeInt!");
  }
}

// Emit a load instruction if possible, returning true if we succeeded,
// otherwise false.  See commentary below for how the register class of
// the load is determined.
bool PPCFastISel::PPCEmitLoad(MVT VT, Register &ResultReg, Address &Addr,
                              const TargetRegisterClass *RC,
                              bool IsZExt, unsigned FP64LoadOpc) {
  unsigned Opc;
  bool UseOffset = true;
  bool HasSPE = Subtarget->hasSPE();

  // If ResultReg is given, it determines the register class of the load.
  // Otherwise, RC is the register class to use.  If the result of the
  // load isn't anticipated in this block, both may be zero, in which
  // case we must make a conservative guess.  In particular, don't assign
  // R0 or X0 to the result register, as the result may be used in a load,
  // store, add-immediate, or isel that won't permit this.  (Though
  // perhaps the spill and reload of live-exit values would handle this?)
  const TargetRegisterClass *UseRC =
    (ResultReg ? MRI.getRegClass(ResultReg) :
     (RC ? RC :
      (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
       (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
        (VT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
         &PPC::GPRC_and_GPRC_NOR0RegClass)))));

  bool Is32BitInt = UseRC->hasSuperClassEq(&PPC::GPRCRegClass);

  switch (VT.SimpleTy) {
    default: // e.g., vector types not handled
      return false;
    case MVT::i8:
      Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
      break;
    case MVT::i16:
      Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
                    : (Is32BitInt ? PPC::LHA : PPC::LHA8));
      break;
    case MVT::i32:
      Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
                    : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
      if ((Opc == PPC::LWA || Opc == PPC::LWA_32) && ((Addr.Offset & 3) != 0))
        UseOffset = false;
      break;
    case MVT::i64:
      Opc = PPC::LD;
      assert(UseRC->hasSuperClassEq(&PPC::G8RCRegClass) &&
             "64-bit load with 32-bit target??");
      UseOffset = ((Addr.Offset & 3) == 0);
      break;
    case MVT::f32:
      Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
      break;
    case MVT::f64:
      Opc = FP64LoadOpc;
      break;
  }

  // If necessary, materialize the offset into a register and use
  // the indexed form.  Also handle stack pointers with special needs.
  Register IndexReg;
  PPCSimplifyAddress(Addr, UseOffset, IndexReg);

  // If this is a potential VSX load with an offset of 0, a VSX indexed load can
  // be used.
  bool IsVSSRC = isVSSRCRegClass(UseRC);
  bool IsVSFRC = isVSFRCRegClass(UseRC);
  bool Is32VSXLoad = IsVSSRC && Opc == PPC::LFS;
  bool Is64VSXLoad = IsVSFRC && Opc == PPC::LFD;
  if ((Is32VSXLoad || Is64VSXLoad) &&
      (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
      (Addr.Offset == 0)) {
    UseOffset = false;
  }

  if (!ResultReg)
    ResultReg = createResultReg(UseRC);

  // Note: If we still have a frame index here, we know the offset is
  // in range, as otherwise PPCSimplifyAddress would have converted it
  // into a RegBase.
  if (Addr.BaseType == Address::FrameIndexBase) {
    // VSX only provides an indexed load.
    if (Is32VSXLoad || Is64VSXLoad) return false;

    MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
        MachinePointerInfo::getFixedStack(*FuncInfo.MF, Addr.Base.FI,
                                          Addr.Offset),
        MachineMemOperand::MOLoad, MFI.getObjectSize(Addr.Base.FI),
        MFI.getObjectAlign(Addr.Base.FI));

    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
      .addImm(Addr.Offset).addFrameIndex(Addr.Base.FI).addMemOperand(MMO);

  // Base reg with offset in range.
  } else if (UseOffset) {
    // VSX only provides an indexed load.
    if (Is32VSXLoad || Is64VSXLoad) return false;

    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
      .addImm(Addr.Offset).addReg(Addr.Base.Reg);

  // Indexed form.
  } else {
    // Get the RR opcode corresponding to the RI one.  FIXME: It would be
    // preferable to use the ImmToIdxMap from PPCRegisterInfo.cpp, but it
    // is hard to get at.
    switch (Opc) {
      default:        llvm_unreachable("Unexpected opcode!");
      case PPC::LBZ:    Opc = PPC::LBZX;    break;
      case PPC::LBZ8:   Opc = PPC::LBZX8;   break;
      case PPC::LHZ:    Opc = PPC::LHZX;    break;
      case PPC::LHZ8:   Opc = PPC::LHZX8;   break;
      case PPC::LHA:    Opc = PPC::LHAX;    break;
      case PPC::LHA8:   Opc = PPC::LHAX8;   break;
      case PPC::LWZ:    Opc = PPC::LWZX;    break;
      case PPC::LWZ8:   Opc = PPC::LWZX8;   break;
      case PPC::LWA:    Opc = PPC::LWAX;    break;
      case PPC::LWA_32: Opc = PPC::LWAX_32; break;
      case PPC::LD:     Opc = PPC::LDX;     break;
      case PPC::LFS:    Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX; break;
      case PPC::LFD:    Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX; break;
      case PPC::EVLDD:  Opc = PPC::EVLDDX;  break;
      case PPC::SPELWZ: Opc = PPC::SPELWZX;    break;
    }

    auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),
                       ResultReg);

    // If we have an index register defined we use it in the store inst,
    // otherwise we use X0 as base as it makes the vector instructions to
    // use zero in the computation of the effective address regardless the
    // content of the register.
    if (IndexReg)
      MIB.addReg(Addr.Base.Reg).addReg(IndexReg);
    else
      MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
  }

  return true;
}

// Attempt to fast-select a load instruction.
bool PPCFastISel::SelectLoad(const Instruction *I) {
  // FIXME: No atomic loads are supported.
  if (cast<LoadInst>(I)->isAtomic())
    return false;

  // Verify we have a legal type before going any further.
  MVT VT;
  if (!isLoadTypeLegal(I->getType(), VT))
    return false;

  // See if we can handle this address.
  Address Addr;
  if (!PPCComputeAddress(I->getOperand(0), Addr))
    return false;

  // Look at the currently assigned register for this instruction
  // to determine the required register class.  This is necessary
  // to constrain RA from using R0/X0 when this is not legal.
  Register AssignedReg = FuncInfo.ValueMap[I];
  const TargetRegisterClass *RC =
    AssignedReg ? MRI.getRegClass(AssignedReg) : nullptr;

  Register ResultReg = 0;
  if (!PPCEmitLoad(VT, ResultReg, Addr, RC, true,
                   Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
    return false;
  updateValueMap(I, ResultReg);
  return true;
}

// Emit a store instruction to store SrcReg at Addr.
bool PPCFastISel::PPCEmitStore(MVT VT, Register SrcReg, Address &Addr) {
  assert(SrcReg && "Nothing to store!");
  unsigned Opc;
  bool UseOffset = true;

  const TargetRegisterClass *RC = MRI.getRegClass(SrcReg);
  bool Is32BitInt = RC->hasSuperClassEq(&PPC::GPRCRegClass);

  switch (VT.SimpleTy) {
    default: // e.g., vector types not handled
      return false;
    case MVT::i8:
      Opc = Is32BitInt ? PPC::STB : PPC::STB8;
      break;
    case MVT::i16:
      Opc = Is32BitInt ? PPC::STH : PPC::STH8;
      break;
    case MVT::i32:
      assert(Is32BitInt && "Not GPRC for i32??");
      Opc = PPC::STW;
      break;
    case MVT::i64:
      Opc = PPC::STD;
      UseOffset = ((Addr.Offset & 3) == 0);
      break;
    case MVT::f32:
      Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
      break;
    case MVT::f64:
      Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
      break;
  }

  // If necessary, materialize the offset into a register and use
  // the indexed form.  Also handle stack pointers with special needs.
  Register IndexReg;
  PPCSimplifyAddress(Addr, UseOffset, IndexReg);

  // If this is a potential VSX store with an offset of 0, a VSX indexed store
  // can be used.
  bool IsVSSRC = isVSSRCRegClass(RC);
  bool IsVSFRC = isVSFRCRegClass(RC);
  bool Is32VSXStore = IsVSSRC && Opc == PPC::STFS;
  bool Is64VSXStore = IsVSFRC && Opc == PPC::STFD;
  if ((Is32VSXStore || Is64VSXStore) &&
      (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
      (Addr.Offset == 0)) {
    UseOffset = false;
  }

  // Note: If we still have a frame index here, we know the offset is
  // in range, as otherwise PPCSimplifyAddress would have converted it
  // into a RegBase.
  if (Addr.BaseType == Address::FrameIndexBase) {
    // VSX only provides an indexed store.
    if (Is32VSXStore || Is64VSXStore) return false;

    MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
        MachinePointerInfo::getFixedStack(*FuncInfo.MF, Addr.Base.FI,
                                          Addr.Offset),
        MachineMemOperand::MOStore, MFI.getObjectSize(Addr.Base.FI),
        MFI.getObjectAlign(Addr.Base.FI));

    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
        .addReg(SrcReg)
        .addImm(Addr.Offset)
        .addFrameIndex(Addr.Base.FI)
        .addMemOperand(MMO);

  // Base reg with offset in range.
  } else if (UseOffset) {
    // VSX only provides an indexed store.
    if (Is32VSXStore || Is64VSXStore)
      return false;

    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
      .addReg(SrcReg).addImm(Addr.Offset).addReg(Addr.Base.Reg);

  // Indexed form.
  } else {
    // Get the RR opcode corresponding to the RI one.  FIXME: It would be
    // preferable to use the ImmToIdxMap from PPCRegisterInfo.cpp, but it
    // is hard to get at.
    switch (Opc) {
      default:        llvm_unreachable("Unexpected opcode!");
      case PPC::STB:  Opc = PPC::STBX;  break;
      case PPC::STH : Opc = PPC::STHX;  break;
      case PPC::STW : Opc = PPC::STWX;  break;
      case PPC::STB8: Opc = PPC::STBX8; break;
      case PPC::STH8: Opc = PPC::STHX8; break;
      case PPC::STW8: Opc = PPC::STWX8; break;
      case PPC::STD:  Opc = PPC::STDX;  break;
      case PPC::STFS: Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX; break;
      case PPC::STFD: Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX; break;
      case PPC::EVSTDD: Opc = PPC::EVSTDDX; break;
      case PPC::SPESTW: Opc = PPC::SPESTWX; break;
    }

    auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
        .addReg(SrcReg);

    // If we have an index register defined we use it in the store inst,
    // otherwise we use X0 as base as it makes the vector instructions to
    // use zero in the computation of the effective address regardless the
    // content of the register.
    if (IndexReg)
      MIB.addReg(Addr.Base.Reg).addReg(IndexReg);
    else
      MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
  }

  return true;
}

// Attempt to fast-select a store instruction.
bool PPCFastISel::SelectStore(const Instruction *I) {
  Value *Op0 = I->getOperand(0);
  Register SrcReg;

  // FIXME: No atomics loads are supported.
  if (cast<StoreInst>(I)->isAtomic())
    return false;

  // Verify we have a legal type before going any further.
  MVT VT;
  if (!isLoadTypeLegal(Op0->getType(), VT))
    return false;

  // Get the value to be stored into a register.
  SrcReg = getRegForValue(Op0);
  if (!SrcReg)
    return false;

  // See if we can handle this address.
  Address Addr;
  if (!PPCComputeAddress(I->getOperand(1), Addr))
    return false;

  if (!PPCEmitStore(VT, SrcReg, Addr))
    return false;

  return true;
}

// Attempt to fast-select a branch instruction.
bool PPCFastISel::SelectBranch(const Instruction *I) {
  const CondBrInst *BI = cast<CondBrInst>(I);
  MachineBasicBlock *BrBB = FuncInfo.MBB;
  MachineBasicBlock *TBB = FuncInfo.getMBB(BI->getSuccessor(0));
  MachineBasicBlock *FBB = FuncInfo.getMBB(BI->getSuccessor(1));

  // For now, just try the simplest case where it's fed by a compare.
  if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
    if (isValueAvailable(CI)) {
      std::optional<PPC::Predicate> OptPPCPred =
          getComparePred(CI->getPredicate());
      if (!OptPPCPred)
        return false;

      PPC::Predicate PPCPred = *OptPPCPred;

      // Take advantage of fall-through opportunities.
      if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
        std::swap(TBB, FBB);
        PPCPred = PPC::InvertPredicate(PPCPred);
      }

      Register CondReg = createResultReg(&PPC::CRRCRegClass);

      if (!PPCEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned(),
                      CondReg, PPCPred))
        return false;

      BuildMI(*BrBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::BCC))
          .addImm(Subtarget->hasSPE() ? PPC::PRED_SPE : PPCPred)
          .addReg(CondReg)
          .addMBB(TBB);
      finishCondBranch(BI->getParent(), TBB, FBB);
      return true;
    }
  } else if (const ConstantInt *CI =
             dyn_cast<ConstantInt>(BI->getCondition())) {
    uint64_t Imm = CI->getZExtValue();
    MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB;
    fastEmitBranch(Target, MIMD.getDL());
    return true;
  }

  // FIXME: ARM looks for a case where the block containing the compare
  // has been split from the block containing the branch.  If this happens,
  // there is a vreg available containing the result of the compare.  I'm
  // not sure we can do much, as we've lost the predicate information with
  // the compare instruction -- we have a 4-bit CR but don't know which bit
  // to test here.
  return false;
}

// Attempt to emit a compare of the two source values.  Signed and unsigned
// comparisons are supported.  Return false if we can't handle it.
bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,
                             bool IsZExt, Register DestReg,
                             const PPC::Predicate Pred) {
  Type *Ty = SrcValue1->getType();
  EVT SrcEVT = TLI.getValueType(DL, Ty, true);
  if (!SrcEVT.isSimple())
    return false;
  MVT SrcVT = SrcEVT.getSimpleVT();

  if (SrcVT == MVT::i1 && Subtarget->useCRBits())
    return false;

  // See if operand 2 is an immediate encodeable in the compare.
  // FIXME: Operands are not in canonical order at -O0, so an immediate
  // operand in position 1 is a lost opportunity for now.  We are
  // similar to ARM in this regard.
  int64_t Imm = 0;
  bool UseImm = false;
  const bool HasSPE = Subtarget->hasSPE();

  // Only 16-bit integer constants can be represented in compares for
  // PowerPC.  Others will be materialized into a register.
  if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(SrcValue2)) {
    if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
        SrcVT == MVT::i8 || SrcVT == MVT::i1) {
      const APInt &CIVal = ConstInt->getValue();
      Imm = (IsZExt) ? (int64_t)CIVal.getZExtValue() :
                       (int64_t)CIVal.getSExtValue();
      if ((IsZExt && isUInt<16>(Imm)) || (!IsZExt && isInt<16>(Imm)))
        UseImm = true;
    }
  }

  Register SrcReg1 = getRegForValue(SrcValue1);
  if (!SrcReg1)
    return false;

  Register SrcReg2;
  if (!UseImm) {
    SrcReg2 = getRegForValue(SrcValue2);
    if (!SrcReg2)
      return false;
  }

  unsigned CmpOpc;
  bool NeedsExt = false;

  auto RC1 = MRI.getRegClass(SrcReg1);
  auto RC2 = SrcReg2 != 0 ? MRI.getRegClass(SrcReg2) : nullptr;

  switch (SrcVT.SimpleTy) {
    default: return false;
    case MVT::f32:
      if (HasSPE) {
        switch (Pred) {
          default: return false;
          case PPC::PRED_EQ:
            CmpOpc = PPC::EFSCMPEQ;
            break;
          case PPC::PRED_LT:
            CmpOpc = PPC::EFSCMPLT;
            break;
          case PPC::PRED_GT:
            CmpOpc = PPC::EFSCMPGT;
            break;
        }
      } else {
        CmpOpc = PPC::FCMPUS;
        if (isVSSRCRegClass(RC1))
          SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
        if (RC2 && isVSSRCRegClass(RC2))
          SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
      }
      break;
    case MVT::f64:
      if (HasSPE) {
        switch (Pred) {
          default: return false;
          case PPC::PRED_EQ:
            CmpOpc = PPC::EFDCMPEQ;
            break;
          case PPC::PRED_LT:
            CmpOpc = PPC::EFDCMPLT;
            break;
          case PPC::PRED_GT:
            CmpOpc = PPC::EFDCMPGT;
            break;
        }
      } else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
        CmpOpc = PPC::XSCMPUDP;
      } else {
        CmpOpc = PPC::FCMPUD;
      }
      break;
    case MVT::i1:
    case MVT::i8:
    case MVT::i16:
      NeedsExt = true;
      [[fallthrough]];
    case MVT::i32:
      if (!UseImm)
        CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
      else
        CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
      break;
    case MVT::i64:
      if (!UseImm)
        CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
      else
        CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
      break;
  }

  if (NeedsExt) {
    Register ExtReg = createResultReg(&PPC::GPRCRegClass);
    if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))
      return false;
    SrcReg1 = ExtReg;

    if (!UseImm) {
      Register ExtReg = createResultReg(&PPC::GPRCRegClass);
      if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))
        return false;
      SrcReg2 = ExtReg;
    }
  }

  if (!UseImm)
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc), DestReg)
      .addReg(SrcReg1).addReg(SrcReg2);
  else
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc), DestReg)
      .addReg(SrcReg1).addImm(Imm);

  return true;
}

// Attempt to fast-select a floating-point extend instruction.
bool PPCFastISel::SelectFPExt(const Instruction *I) {
  Value *Src  = I->getOperand(0);
  EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
  EVT DestVT = TLI.getValueType(DL, I->getType(), true);

  if (SrcVT != MVT::f32 || DestVT != MVT::f64)
    return false;

  Register SrcReg = getRegForValue(Src);
  if (!SrcReg)
    return false;

  // No code is generated for a FP extend.
  updateValueMap(I, SrcReg);
  return true;
}

// Attempt to fast-select a floating-point truncate instruction.
bool PPCFastISel::SelectFPTrunc(const Instruction *I) {
  Value *Src  = I->getOperand(0);
  EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
  EVT DestVT = TLI.getValueType(DL, I->getType(), true);

  if (SrcVT != MVT::f64 || DestVT != MVT::f32)
    return false;

  Register SrcReg = getRegForValue(Src);
  if (!SrcReg)
    return false;

  // Round the result to single precision.
  Register DestReg;
  auto RC = MRI.getRegClass(SrcReg);
  if (Subtarget->hasSPE()) {
    DestReg = createResultReg(&PPC::GPRCRegClass);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::EFSCFD),
            DestReg)
        .addReg(SrcReg);
  } else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
    DestReg = createResultReg(&PPC::VSSRCRegClass);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::XSRSP),
            DestReg)
        .addReg(SrcReg);
  } else {
    SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
    DestReg = createResultReg(&PPC::F4RCRegClass);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
      TII.get(PPC::FRSP), DestReg)
      .addReg(SrcReg);
  }

  updateValueMap(I, DestReg);
  return true;
}

// Move an i32 or i64 value in a GPR to an f64 value in an FPR.
// FIXME: When direct register moves are implemented (see PowerISA 2.07),
// those should be used instead of moving via a stack slot when the
// subtarget permits.
// FIXME: The code here is sloppy for the 4-byte case.  Can use a 4-byte
// stack slot and 4-byte store/load sequence.  Or just sext the 4-byte
// case to 8 bytes which produces tighter code but wastes stack space.
Register PPCFastISel::PPCMoveToFPReg(MVT SrcVT, Register SrcReg,
                                     bool IsSigned) {

  // If necessary, extend 32-bit int to 64-bit.
  if (SrcVT == MVT::i32) {
    Register TmpReg = createResultReg(&PPC::G8RCRegClass);
    if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))
      return Register();
    SrcReg = TmpReg;
  }

  // Get a stack slot 8 bytes wide, aligned on an 8-byte boundary.
  Address Addr;
  Addr.BaseType = Address::FrameIndexBase;
  Addr.Base.FI = MFI.CreateStackObject(8, Align(8), false);

  // Store the value from the GPR.
  if (!PPCEmitStore(MVT::i64, SrcReg, Addr))
    return Register();

  // Load the integer value into an FPR.  The kind of load used depends
  // on a number of conditions.
  unsigned LoadOpc = PPC::LFD;

  if (SrcVT == MVT::i32) {
    if (!IsSigned) {
      LoadOpc = PPC::LFIWZX;
      Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
    } else if (Subtarget->hasLFIWAX()) {
      LoadOpc = PPC::LFIWAX;
      Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
    }
  }

  const TargetRegisterClass *RC = &PPC::F8RCRegClass;
  Register ResultReg;
  if (!PPCEmitLoad(MVT::f64, ResultReg, Addr, RC, !IsSigned, LoadOpc))
    return Register();

  return ResultReg;
}

// Attempt to fast-select an integer-to-floating-point conversion.
// FIXME: Once fast-isel has better support for VSX, conversions using
//        direct moves should be implemented.
bool PPCFastISel::SelectIToFP(const Instruction *I, bool IsSigned) {
  MVT DstVT;
  Type *DstTy = I->getType();
  if (!isTypeLegal(DstTy, DstVT))
    return false;

  if (DstVT != MVT::f32 && DstVT != MVT::f64)
    return false;

  Value *Src = I->getOperand(0);
  EVT SrcEVT = TLI.getValueType(DL, Src->getType(), true);
  if (!SrcEVT.isSimple())
    return false;

  MVT SrcVT = SrcEVT.getSimpleVT();

  if (SrcVT != MVT::i8  && SrcVT != MVT::i16 &&
      SrcVT != MVT::i32 && SrcVT != MVT::i64)
    return false;

  Register SrcReg = getRegForValue(Src);
  if (!SrcReg)
    return false;

  // Shortcut for SPE.  Doesn't need to store/load, since it's all in the GPRs
  if (Subtarget->hasSPE()) {
    unsigned Opc;
    if (DstVT == MVT::f32)
      Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
    else
      Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;

    Register DestReg = createResultReg(&PPC::SPERCRegClass);
    // Generate the convert.
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
      .addReg(SrcReg);
    updateValueMap(I, DestReg);
    return true;
  }

  // We can only lower an unsigned convert if we have the newer
  // floating-point conversion operations.
  if (!IsSigned && !Subtarget->hasFPCVT())
    return false;

  // FIXME: For now we require the newer floating-point conversion operations
  // (which are present only on P7 and A2 server models) when converting
  // to single-precision float.  Otherwise we have to generate a lot of
  // fiddly code to avoid double rounding.  If necessary, the fiddly code
  // can be found in PPCTargetLowering::LowerINT_TO_FP().
  if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())
    return false;

  // Extend the input if necessary.
  if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {
    Register TmpReg = createResultReg(&PPC::G8RCRegClass);
    if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))
      return false;
    SrcVT = MVT::i64;
    SrcReg = TmpReg;
  }

  // Move the integer value to an FPR.
  Register FPReg = PPCMoveToFPReg(SrcVT, SrcReg, IsSigned);
  if (!FPReg)
    return false;

  // Determine the opcode for the conversion.
  const TargetRegisterClass *RC = &PPC::F8RCRegClass;
  Register DestReg = createResultReg(RC);
  unsigned Opc;

  if (DstVT == MVT::f32)
    Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;
  else
    Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;

  // Generate the convert.
  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
    .addReg(FPReg);

  updateValueMap(I, DestReg);
  return true;
}

// Move the floating-point value in SrcReg into an integer destination
// register, and return the register (or zero if we can't handle it).
// FIXME: When direct register moves are implemented (see PowerISA 2.07),
// those should be used instead of moving via a stack slot when the
// subtarget permits.
Register PPCFastISel::PPCMoveToIntReg(const Instruction *I, MVT VT,
                                      Register SrcReg, bool IsSigned) {
  // Get a stack slot 8 bytes wide, aligned on an 8-byte boundary.
  // Note that if have STFIWX available, we could use a 4-byte stack
  // slot for i32, but this being fast-isel we'll just go with the
  // easiest code gen possible.
  Address Addr;
  Addr.BaseType = Address::FrameIndexBase;
  Addr.Base.FI = MFI.CreateStackObject(8, Align(8), false);

  // Store the value from the FPR.
  if (!PPCEmitStore(MVT::f64, SrcReg, Addr))
    return Register();

  // Reload it into a GPR.  If we want an i32 on big endian, modify the
  // address to have a 4-byte offset so we load from the right place.
  if (VT == MVT::i32)
    Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;

  // Look at the currently assigned register for this instruction
  // to determine the required register class.
  Register AssignedReg = FuncInfo.ValueMap[I];
  const TargetRegisterClass *RC =
    AssignedReg ? MRI.getRegClass(AssignedReg) : nullptr;

  Register ResultReg;
  if (!PPCEmitLoad(VT, ResultReg, Addr, RC, !IsSigned))
    return Register();

  return ResultReg;
}

// Attempt to fast-select a floating-point-to-integer conversion.
// FIXME: Once fast-isel has better support for VSX, conversions using
//        direct moves should be implemented.
bool PPCFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {
  MVT DstVT, SrcVT;
  Type *DstTy = I->getType();
  if (!isTypeLegal(DstTy, DstVT))
    return false;

  if (DstVT != MVT::i32 && DstVT != MVT::i64)
    return false;

  // If we don't have FCTIDUZ, or SPE, and we need it, punt to SelectionDAG.
  if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
      !Subtarget->hasSPE())
    return false;

  Value *Src = I->getOperand(0);
  Type *SrcTy = Src->getType();
  if (!isTypeLegal(SrcTy, SrcVT))
    return false;

  if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
    return false;

  Register SrcReg = getRegForValue(Src);
  if (!SrcReg)
    return false;

  // Convert f32 to f64 or convert VSSRC to VSFRC if necessary. This is just a
  // meaningless copy to get the register class right.
  const TargetRegisterClass *InRC = MRI.getRegClass(SrcReg);
  if (InRC == &PPC::F4RCRegClass)
    SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
  else if (InRC == &PPC::VSSRCRegClass)
    SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);

  // Determine the opcode for the conversion, which takes place
  // entirely within FPRs or VSRs.
  Register DestReg;
  unsigned Opc;
  auto RC = MRI.getRegClass(SrcReg);

  if (Subtarget->hasSPE()) {
    DestReg = createResultReg(&PPC::GPRCRegClass);
    if (IsSigned)
      Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
    else
      Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
  } else if (isVSFRCRegClass(RC)) {
    DestReg = createResultReg(&PPC::VSFRCRegClass);
    if (DstVT == MVT::i32)
      Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
    else
      Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
  } else {
    DestReg = createResultReg(&PPC::F8RCRegClass);
    if (DstVT == MVT::i32)
      if (IsSigned)
        Opc = PPC::FCTIWZ;
      else
        Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
    else
      Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
  }

  // Generate the convert.
  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
    .addReg(SrcReg);

  // Now move the integer value from a float register to an integer register.
  Register IntReg = Subtarget->hasSPE()
                        ? DestReg
                        : PPCMoveToIntReg(I, DstVT, DestReg, IsSigned);

  if (!IntReg)
    return false;

  updateValueMap(I, IntReg);
  return true;
}

// Attempt to fast-select a binary integer operation that isn't already
// handled automatically.
bool PPCFastISel::SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode) {
  EVT DestVT = TLI.getValueType(DL, I->getType(), true);

  // We can get here in the case when we have a binary operation on a non-legal
  // type and the target independent selector doesn't know how to handle it.
  if (DestVT != MVT::i16 && DestVT != MVT::i8)
    return false;

  // Look at the currently assigned register for this instruction
  // to determine the required register class.  If there is no register,
  // make a conservative choice (don't assign R0).
  Register AssignedReg = FuncInfo.ValueMap[I];
  const TargetRegisterClass *RC =
    (AssignedReg ? MRI.getRegClass(AssignedReg) :
     &PPC::GPRC_and_GPRC_NOR0RegClass);
  bool IsGPRC = RC->hasSuperClassEq(&PPC::GPRCRegClass);

  unsigned Opc;
  switch (ISDOpcode) {
    default: return false;
    case ISD::ADD:
      Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
      break;
    case ISD::OR:
      Opc = IsGPRC ? PPC::OR : PPC::OR8;
      break;
    case ISD::SUB:
      Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
      break;
  }

  Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
  Register SrcReg1 = getRegForValue(I->getOperand(0));
  if (!SrcReg1)
    return false;

  // Handle case of small immediate operand.
  if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(I->getOperand(1))) {
    const APInt &CIVal = ConstInt->getValue();
    int Imm = (int)CIVal.getSExtValue();
    bool UseImm = true;
    if (isInt<16>(Imm)) {
      switch (Opc) {
        default:
          llvm_unreachable("Missing case!");
        case PPC::ADD4:
          Opc = PPC::ADDI;
          MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
          break;
        case PPC::ADD8:
          Opc = PPC::ADDI8;
          MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
          break;
        case PPC::OR:
          Opc = PPC::ORI;
          break;
        case PPC::OR8:
          Opc = PPC::ORI8;
          break;
        case PPC::SUBF:
          if (Imm == -32768)
            UseImm = false;
          else {
            Opc = PPC::ADDI;
            MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
            Imm = -Imm;
          }
          break;
        case PPC::SUBF8:
          if (Imm == -32768)
            UseImm = false;
          else {
            Opc = PPC::ADDI8;
            MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
            Imm = -Imm;
          }
          break;
      }

      if (UseImm) {
        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),
                ResultReg)
            .addReg(SrcReg1)
            .addImm(Imm);
        updateValueMap(I, ResultReg);
        return true;
      }
    }
  }

  // Reg-reg case.
  Register SrcReg2 = getRegForValue(I->getOperand(1));
  if (!SrcReg2)
    return false;

  // Reverse operands for subtract-from.
  if (ISDOpcode == ISD::SUB)
    std::swap(SrcReg1, SrcReg2);

  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
    .addReg(SrcReg1).addReg(SrcReg2);
  updateValueMap(I, ResultReg);
  return true;
}

// Handle arguments to a call that we're attempting to fast-select.
// Return false if the arguments are too complex for us at the moment.
bool PPCFastISel::processCallArgs(SmallVectorImpl<Value *> &Args,
                                  SmallVectorImpl<Register> &ArgRegs,
                                  SmallVectorImpl<MVT> &ArgVTs,
                                  SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
                                  SmallVectorImpl<unsigned> &RegArgs,
                                  CallingConv::ID CC, unsigned &NumBytes,
                                  bool IsVarArg) {
  SmallVector<CCValAssign, 16> ArgLocs;
  CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, *Context);

  // Reserve space for the linkage area on the stack.
  unsigned LinkageSize = Subtarget->getFrameLowering()->getLinkageSize();
  CCInfo.AllocateStack(LinkageSize, Align(8));

  SmallVector<Type *, 16> ArgTys;
  for (Value *Arg : Args)
    ArgTys.push_back(Arg->getType());
  CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, ArgTys, CC_PPC64_ELF_FIS);

  // Bail out if we can't handle any of the arguments.
  for (const CCValAssign &VA : ArgLocs) {
    MVT ArgVT = ArgVTs[VA.getValNo()];

    // Skip vector arguments for now, as well as long double and
    // uint128_t, and anything that isn't passed in a register.
    if (ArgVT.isVector() || ArgVT.getSizeInBits() > 64 || ArgVT == MVT::i1 ||
        !VA.isRegLoc() || VA.needsCustom())
      return false;

    // Skip bit-converted arguments for now.
    if (VA.getLocInfo() == CCValAssign::BCvt)
      return false;
  }

  // Get a count of how many bytes are to be pushed onto the stack.
  NumBytes = CCInfo.getStackSize();

  // The prolog code of the callee may store up to 8 GPR argument registers to
  // the stack, allowing va_start to index over them in memory if its varargs.
  // Because we cannot tell if this is needed on the caller side, we have to
  // conservatively assume that it is needed.  As such, make sure we have at
  // least enough stack space for the caller to store the 8 GPRs.
  // FIXME: On ELFv2, it may be unnecessary to allocate the parameter area.
  NumBytes = std::max(NumBytes, LinkageSize + 64);

  // Issue CALLSEQ_START.
  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
          TII.get(TII.getCallFrameSetupOpcode()))
    .addImm(NumBytes).addImm(0);

  // Prepare to assign register arguments.  Every argument uses up a
  // GPR protocol register even if it's passed in a floating-point
  // register (unless we're using the fast calling convention).
  unsigned NextGPR = PPC::X3;
  unsigned NextFPR = PPC::F1;

  // Process arguments.
  for (const CCValAssign &VA : ArgLocs) {
    Register Arg = ArgRegs[VA.getValNo()];
    MVT ArgVT = ArgVTs[VA.getValNo()];

    // Handle argument promotion and bitcasts.
    switch (VA.getLocInfo()) {
      default:
        llvm_unreachable("Unknown loc info!");
      case CCValAssign::Full:
        break;
      case CCValAssign::SExt: {
        MVT DestVT = VA.getLocVT();
        const TargetRegisterClass *RC =
          (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
        Register TmpReg = createResultReg(RC);
        if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg, /*IsZExt*/false))
          llvm_unreachable("Failed to emit a sext!");
        ArgVT = DestVT;
        Arg = TmpReg;
        break;
      }
      case CCValAssign::AExt:
      case CCValAssign::ZExt: {
        MVT DestVT = VA.getLocVT();
        const TargetRegisterClass *RC =
          (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
        Register TmpReg = createResultReg(RC);
        if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg, /*IsZExt*/true))
          llvm_unreachable("Failed to emit a zext!");
        ArgVT = DestVT;
        Arg = TmpReg;
        break;
      }
      case CCValAssign::BCvt: {
        // FIXME: Not yet handled.
        llvm_unreachable("Should have bailed before getting here!");
        break;
      }
    }

    // Copy this argument to the appropriate register.
    unsigned ArgReg;
    if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
      ArgReg = NextFPR++;
      if (CC != CallingConv::Fast)
        ++NextGPR;
    } else
      ArgReg = NextGPR++;

    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
            TII.get(TargetOpcode::COPY), ArgReg).addReg(Arg);
    RegArgs.push_back(ArgReg);
  }

  return true;
}

// For a call that we've determined we can fast-select, finish the
// call sequence and generate a copy to obtain the return value (if any).
bool PPCFastISel::finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes) {
  CallingConv::ID CC = CLI.CallConv;

  // Issue CallSEQ_END.
  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
          TII.get(TII.getCallFrameDestroyOpcode()))
    .addImm(NumBytes).addImm(0);

  // Next, generate a copy to obtain the return value.
  // FIXME: No multi-register return values yet, though I don't foresee
  // any real difficulties there.
  if (RetVT != MVT::isVoid) {
    SmallVector<CCValAssign, 16> RVLocs;
    CCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);
    CCInfo.AnalyzeCallResult(RetVT, CLI.RetTy, RetCC_PPC64_ELF_FIS);
    CCValAssign &VA = RVLocs[0];
    assert(RVLocs.size() == 1 && "No support for multi-reg return values!");
    assert(VA.isRegLoc() && "Can only return in registers!");

    MVT DestVT = VA.getValVT();
    MVT CopyVT = DestVT;

    // Ints smaller than a register still arrive in a full 64-bit
    // register, so make sure we recognize this.
    if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
      CopyVT = MVT::i64;

    Register SourcePhysReg = VA.getLocReg();
    Register ResultReg;

    if (RetVT == CopyVT) {
      const TargetRegisterClass *CpyRC = TLI.getRegClassFor(CopyVT);
      ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);

    // If necessary, round the floating result to single precision.
    } else if (CopyVT == MVT::f64) {
      ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::FRSP),
              ResultReg).addReg(SourcePhysReg);

    // If only the low half of a general register is needed, generate
    // a GPRC copy instead of a G8RC copy.  (EXTRACT_SUBREG can't be
    // used along the fast-isel path (not lowered), and downstream logic
    // also doesn't like a direct subreg copy on a physical reg.)
    } else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
      // Convert physical register from G8RC to GPRC.
      SourcePhysReg = (SourcePhysReg - PPC::X0) + PPC::R0;
      ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
    }

    assert(ResultReg && "ResultReg unset!");
    CLI.InRegs.push_back(SourcePhysReg);
    CLI.ResultReg = ResultReg;
    CLI.NumResultRegs = 1;
  }

  return true;
}

bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
  CallingConv::ID CC  = CLI.CallConv;
  bool IsTailCall     = CLI.IsTailCall;
  bool IsVarArg       = CLI.IsVarArg;
  const Value *Callee = CLI.Callee;
  const MCSymbol *Symbol = CLI.Symbol;

  if (!Callee && !Symbol)
    return false;

  // Allow SelectionDAG isel to handle tail calls and long calls.
  if (IsTailCall || Subtarget->useLongCalls())
    return false;

  // Let SDISel handle vararg functions.
  if (IsVarArg)
    return false;

  // If this is a PC-Rel function, let SDISel handle the call.
  if (Subtarget->isUsingPCRelativeCalls())
    return false;

  // Handle simple calls for now, with legal return types and
  // those that can be extended.
  Type *RetTy = CLI.RetTy;
  MVT RetVT;
  if (RetTy->isVoidTy())
    RetVT = MVT::isVoid;
  else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&
           RetVT != MVT::i8)
    return false;
  else if (RetVT == MVT::i1 && Subtarget->useCRBits())
    // We can't handle boolean returns when CR bits are in use.
    return false;

  // FIXME: No multi-register return values yet.
  if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
      RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
      RetVT != MVT::f64) {
    SmallVector<CCValAssign, 16> RVLocs;
    CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);
    CCInfo.AnalyzeCallResult(RetVT, RetTy, RetCC_PPC64_ELF_FIS);
    if (RVLocs.size() > 1)
      return false;
  }

  // Bail early if more than 8 arguments, as we only currently
  // handle arguments passed in registers.
  unsigned NumArgs = CLI.OutVals.size();
  if (NumArgs > 8)
    return false;

  // Set up the argument vectors.
  SmallVector<Value*, 8> Args;
  SmallVector<Register, 8> ArgRegs;
  SmallVector<MVT, 8> ArgVTs;
  SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;

  Args.reserve(NumArgs);
  ArgRegs.reserve(NumArgs);
  ArgVTs.reserve(NumArgs);
  ArgFlags.reserve(NumArgs);

  for (unsigned i = 0, ie = NumArgs; i != ie; ++i) {
    // Only handle easy calls for now.  It would be reasonably easy
    // to handle <= 8-byte structures passed ByVal in registers, but we
    // have to ensure they are right-justified in the register.
    ISD::ArgFlagsTy Flags = CLI.OutFlags[i];
    if (Flags.isInReg() || Flags.isSRet() || Flags.isNest() || Flags.isByVal())
      return false;

    Value *ArgValue = CLI.OutVals[i];
    Type *ArgTy = ArgValue->getType();
    MVT ArgVT;
    if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
      return false;

    // FIXME: FastISel cannot handle non-simple types yet, including 128-bit FP
    // types, which is passed through vector register. Skip these types and
    // fallback to default SelectionDAG based selection.
    if (ArgVT.isVector() || ArgVT == MVT::f128)
      return false;

    Register Arg = getRegForValue(ArgValue);
    if (!Arg)
      return false;

    Args.push_back(ArgValue);
    ArgRegs.push_back(Arg);
    ArgVTs.push_back(ArgVT);
    ArgFlags.push_back(Flags);
  }

  // Process the arguments.
  SmallVector<unsigned, 8> RegArgs;
  unsigned NumBytes;

  if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
                       RegArgs, CC, NumBytes, IsVarArg))
    return false;

  MachineInstrBuilder MIB;
  // FIXME: No handling for function pointers yet.  This requires
  // implementing the function descriptor (OPD) setup.
  const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
  if (!GV) {
    // patchpoints are a special case; they always dispatch to a pointer value.
    // However, we don't actually want to generate the indirect call sequence
    // here (that will be generated, as necessary, during asm printing), and
    // the call we generate here will be erased by FastISel::selectPatchpoint,
    // so don't try very hard...
    if (CLI.IsPatchPoint)
      MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::NOP));
    else
      return false;
  } else {
    // Build direct call with NOP for TOC restore.
    // FIXME: We can and should optimize away the NOP for local calls.
    MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
                  TII.get(PPC::BL8_NOP));
    // Add callee.
    MIB.addGlobalAddress(GV);
  }

  // Add implicit physical register uses to the call.
  for (unsigned Reg : RegArgs)
    MIB.addReg(Reg, RegState::Implicit);

  // Direct calls, in both the ELF V1 and V2 ABIs, need the TOC register live
  // into the call.
  PPCFuncInfo->setUsesTOCBasePtr();
  MIB.addReg(PPC::X2, RegState::Implicit);

  // Add a register mask with the call-preserved registers.  Proper
  // defs for return values will be added by setPhysRegsDeadExcept().
  MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));

  CLI.Call = MIB;

  // Finish off the call including any return values.
  return finishCall(RetVT, CLI, NumBytes);
}

// Attempt to fast-select a return instruction.
bool PPCFastISel::SelectRet(const Instruction *I) {

  if (!FuncInfo.CanLowerReturn)
    return false;

  const ReturnInst *Ret = cast<ReturnInst>(I);
  const Function &F = *I->getParent()->getParent();

  // Build a list of return value registers.
  SmallVector<Register, 4> RetRegs;
  CallingConv::ID CC = F.getCallingConv();

  if (Ret->getNumOperands() > 0) {
    SmallVector<ISD::OutputArg, 4> Outs;
    GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);

    // Analyze operands of the call, assigning locations to each operand.
    SmallVector<CCValAssign, 16> ValLocs;
    CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs, *Context);
    CCInfo.AnalyzeReturn(Outs, RetCC_PPC64_ELF_FIS);
    const Value *RV = Ret->getOperand(0);

    // FIXME: Only one output register for now.
    if (ValLocs.size() > 1)
      return false;

    // Special case for returning a constant integer of any size - materialize
    // the constant as an i64 and copy it to the return register.
    if (isa<ConstantInt>(RV) && RV->getType()->isIntegerTy()) {
      const ConstantInt *CI = cast<ConstantInt>(RV);
      CCValAssign &VA = ValLocs[0];

      Register RetReg = VA.getLocReg();
      // We still need to worry about properly extending the sign. For example,
      // we could have only a single bit or a constant that needs zero
      // extension rather than sign extension. Make sure we pass the return
      // value extension property to integer materialization.
      Register SrcReg =
          PPCMaterializeInt(CI, MVT::i64, VA.getLocInfo() != CCValAssign::ZExt);

      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
            TII.get(TargetOpcode::COPY), RetReg).addReg(SrcReg);

      RetRegs.push_back(RetReg);

    } else {
      Register Reg = getRegForValue(RV);

      if (!Reg)
        return false;

      // Copy the result values into the output registers.
      for (unsigned i = 0; i < ValLocs.size(); ++i) {

        CCValAssign &VA = ValLocs[i];
        assert(VA.isRegLoc() && "Can only return in registers!");
        RetRegs.push_back(VA.getLocReg());
        Register SrcReg = Reg + VA.getValNo();

        EVT RVEVT = TLI.getValueType(DL, RV->getType());
        if (!RVEVT.isSimple())
          return false;
        MVT RVVT = RVEVT.getSimpleVT();
        MVT DestVT = VA.getLocVT();

        if (RVVT != DestVT && RVVT != MVT::i8 &&
            RVVT != MVT::i16 && RVVT != MVT::i32)
          return false;

        if (RVVT != DestVT) {
          switch (VA.getLocInfo()) {
            default:
              llvm_unreachable("Unknown loc info!");
            case CCValAssign::Full:
              llvm_unreachable("Full value assign but types don't match?");
            case CCValAssign::AExt:
            case CCValAssign::ZExt: {
              const TargetRegisterClass *RC =
                (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
              Register TmpReg = createResultReg(RC);
              if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg, true))
                return false;
              SrcReg = TmpReg;
              break;
            }
            case CCValAssign::SExt: {
              const TargetRegisterClass *RC =
                (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
              Register TmpReg = createResultReg(RC);
              if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg, false))
                return false;
              SrcReg = TmpReg;
              break;
            }
          }
        }

        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
                TII.get(TargetOpcode::COPY), RetRegs[i])
          .addReg(SrcReg);
      }
    }
  }

  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
                                    TII.get(PPC::BLR8));

  for (Register Reg : RetRegs)
    MIB.addReg(Reg, RegState::Implicit);

  return true;
}

// Attempt to emit an integer extend of SrcReg into DestReg.  Both
// signed and zero extensions are supported.  Return false if we
// can't handle it.
bool PPCFastISel::PPCEmitIntExt(MVT SrcVT, Register SrcReg, MVT DestVT,
                                Register DestReg, bool IsZExt) {
  if (DestVT != MVT::i32 && DestVT != MVT::i64)
    return false;
  if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
    return false;

  // Signed extensions use EXTSB, EXTSH, EXTSW.
  if (!IsZExt) {
    unsigned Opc;
    if (SrcVT == MVT::i8)
      Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
    else if (SrcVT == MVT::i16)
      Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
    else {
      assert(DestVT == MVT::i64 && "Signed extend from i32 to i32??");
      Opc = PPC::EXTSW_32_64;
    }
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
      .addReg(SrcReg);

  // Unsigned 32-bit extensions use RLWINM.
  } else if (DestVT == MVT::i32) {
    unsigned MB;
    if (SrcVT == MVT::i8)
      MB = 24;
    else {
      assert(SrcVT == MVT::i16 && "Unsigned extend from i32 to i32??");
      MB = 16;
    }
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::RLWINM),
            DestReg)
      .addReg(SrcReg).addImm(/*SH=*/0).addImm(MB).addImm(/*ME=*/31);

  // Unsigned 64-bit extensions use RLDICL (with a 32-bit source).
  } else {
    unsigned MB;
    if (SrcVT == MVT::i8)
      MB = 56;
    else if (SrcVT == MVT::i16)
      MB = 48;
    else
      MB = 32;
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
            TII.get(PPC::RLDICL_32_64), DestReg)
      .addReg(SrcReg).addImm(/*SH=*/0).addImm(MB);
  }

  return true;
}

// Attempt to fast-select an indirect branch instruction.
bool PPCFastISel::SelectIndirectBr(const Instruction *I) {
  Register AddrReg = getRegForValue(I->getOperand(0));
  if (!AddrReg)
    return false;

  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::MTCTR8))
    .addReg(AddrReg);
  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::BCTR8));

  const IndirectBrInst *IB = cast<IndirectBrInst>(I);
  for (const BasicBlock *SuccBB : IB->successors())
    FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));

  return true;
}

// Attempt to fast-select an integer truncate instruction.
bool PPCFastISel::SelectTrunc(const Instruction *I) {
  Value *Src  = I->getOperand(0);
  EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
  EVT DestVT = TLI.getValueType(DL, I->getType(), true);

  if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
    return false;

  if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
    return false;

  Register SrcReg = getRegForValue(Src);
  if (!SrcReg)
    return false;

  // The only interesting case is when we need to switch register classes.
  if (SrcVT == MVT::i64)
    SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, {}, PPC::sub_32);

  updateValueMap(I, SrcReg);
  return true;
}

// Attempt to fast-select an integer extend instruction.
bool PPCFastISel::SelectIntExt(const Instruction *I) {
  Type *DestTy = I->getType();
  Value *Src = I->getOperand(0);
  Type *SrcTy = Src->getType();

  bool IsZExt = isa<ZExtInst>(I);
  Register SrcReg = getRegForValue(Src);
  if (!SrcReg) return false;

  EVT SrcEVT, DestEVT;
  SrcEVT = TLI.getValueType(DL, SrcTy, true);
  DestEVT = TLI.getValueType(DL, DestTy, true);
  if (!SrcEVT.isSimple())
    return false;
  if (!DestEVT.isSimple())
    return false;

  MVT SrcVT = SrcEVT.getSimpleVT();
  MVT DestVT = DestEVT.getSimpleVT();

  // If we know the register class needed for the result of this
  // instruction, use it.  Otherwise pick the register class of the
  // correct size that does not contain X0/R0, since we don't know
  // whether downstream uses permit that assignment.
  Register AssignedReg = FuncInfo.ValueMap[I];
  const TargetRegisterClass *RC =
    (AssignedReg ? MRI.getRegClass(AssignedReg) :
     (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
      &PPC::GPRC_and_GPRC_NOR0RegClass));
  Register ResultReg = createResultReg(RC);

  if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
    return false;

  updateValueMap(I, ResultReg);
  return true;
}

// Attempt to fast-select an instruction that wasn't handled by
// the table-generated machinery.
bool PPCFastISel::fastSelectInstruction(const Instruction *I) {

  switch (I->getOpcode()) {
    case Instruction::Load:
      return SelectLoad(I);
    case Instruction::Store:
      return SelectStore(I);
    case Instruction::CondBr:
      return SelectBranch(I);
    case Instruction::IndirectBr:
      return SelectIndirectBr(I);
    case Instruction::FPExt:
      return SelectFPExt(I);
    case Instruction::FPTrunc:
      return SelectFPTrunc(I);
    case Instruction::SIToFP:
      return SelectIToFP(I, /*IsSigned*/ true);
    case Instruction::UIToFP:
      return SelectIToFP(I, /*IsSigned*/ false);
    case Instruction::FPToSI:
      return SelectFPToI(I, /*IsSigned*/ true);
    case Instruction::FPToUI:
      return SelectFPToI(I, /*IsSigned*/ false);
    case Instruction::Add:
      return SelectBinaryIntOp(I, ISD::ADD);
    case Instruction::Or:
      return SelectBinaryIntOp(I, ISD::OR);
    case Instruction::Sub:
      return SelectBinaryIntOp(I, ISD::SUB);
    case Instruction::Ret:
      return SelectRet(I);
    case Instruction::Trunc:
      return SelectTrunc(I);
    case Instruction::ZExt:
    case Instruction::SExt:
      return SelectIntExt(I);
    // Here add other flavors of Instruction::XXX that automated
    // cases don't catch.  For example, switches are terminators
    // that aren't yet handled.
    default:
      break;
  }
  return false;
}

// Materialize a floating-point constant into a register, and return
// the register number (or zero if we failed to handle it).
Register PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
  // If this is a PC-Rel function, let SDISel handle constant pool.
  if (Subtarget->isUsingPCRelativeCalls())
    return Register();

  // No plans to handle long double here.
  if (VT != MVT::f32 && VT != MVT::f64)
    return Register();

  // All FP constants are loaded from the constant pool.
  Align Alignment = DL.getPrefTypeAlign(CFP->getType());
  unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Alignment);
  const bool HasSPE = Subtarget->hasSPE();
  const TargetRegisterClass *RC;
  if (HasSPE)
    RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
  else
    RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);

  Register DestReg = createResultReg(RC);
  CodeModel::Model CModel = TM.getCodeModel();

  MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
      MachinePointerInfo::getConstantPool(*FuncInfo.MF),
      MachineMemOperand::MOLoad, (VT == MVT::f32) ? 4 : 8, Alignment);

  unsigned Opc;

  if (HasSPE)
    Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
  else
    Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);

  Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);

  PPCFuncInfo->setUsesTOCBasePtr();
  // For small code model, generate a LF[SD](0, LDtocCPT(Idx, X2)).
  if (CModel == CodeModel::Small) {
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocCPT),
            TmpReg)
      .addConstantPoolIndex(Idx).addReg(PPC::X2);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
      .addImm(0).addReg(TmpReg).addMemOperand(MMO);
  } else {
    // Otherwise we generate LF[SD](Idx[lo], ADDIStocHA8(X2, Idx)).
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDIStocHA8),
            TmpReg).addReg(PPC::X2).addConstantPoolIndex(Idx);
    // But for large code model, we must generate a LDtocL followed
    // by the LF[SD].
    if (CModel == CodeModel::Large) {
      Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocL),
              TmpReg2).addConstantPoolIndex(Idx).addReg(TmpReg);
      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
          .addImm(0)
          .addReg(TmpReg2);
    } else
      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
        .addConstantPoolIndex(Idx, 0, PPCII::MO_TOC_LO)
        .addReg(TmpReg)
        .addMemOperand(MMO);
  }

  return DestReg;
}

// Materialize the address of a global value into a register, and return
// the register number (or zero if we failed to handle it).
Register PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
  // If this is a PC-Rel function, let SDISel handle GV materialization.
  if (Subtarget->isUsingPCRelativeCalls())
    return Register();

  assert(VT == MVT::i64 && "Non-address!");
  const TargetRegisterClass *RC = &PPC::G8RC_and_G8RC_NOX0RegClass;
  Register DestReg = createResultReg(RC);

  // Global values may be plain old object addresses, TLS object
  // addresses, constant pool entries, or jump tables.  How we generate
  // code for these may depend on small, medium, or large code model.
  CodeModel::Model CModel = TM.getCodeModel();

  // FIXME: Jump tables are not yet required because fast-isel doesn't
  // handle switches; if that changes, we need them as well.  For now,
  // what follows assumes everything's a generic (or TLS) global address.

  // FIXME: We don't yet handle the complexity of TLS.
  if (GV->isThreadLocal())
    return Register();

  PPCFuncInfo->setUsesTOCBasePtr();
  bool IsAIXTocData = TM.getTargetTriple().isOSAIX() &&
                      isa<GlobalVariable>(GV) &&
                      cast<GlobalVariable>(GV)->hasAttribute("toc-data");

  // For small code model, generate a simple TOC load.
  if (CModel == CodeModel::Small) {
    auto MIB = BuildMI(
        *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
        IsAIXTocData ? TII.get(PPC::ADDItoc8) : TII.get(PPC::LDtoc), DestReg);
    if (IsAIXTocData)
      MIB.addReg(PPC::X2).addGlobalAddress(GV);
    else
      MIB.addGlobalAddress(GV).addReg(PPC::X2);
  } else {
    // If the address is an externally defined symbol, a symbol with common
    // or externally available linkage, a non-local function address, or a
    // jump table address (not yet needed), or if we are generating code
    // for large code model, we generate:
    //       LDtocL(GV, ADDIStocHA8(%x2, GV))
    // Otherwise we generate:
    //       ADDItocL8(ADDIStocHA8(%x2, GV), GV)
    // Either way, start with the ADDIStocHA8:
    Register HighPartReg = createResultReg(RC);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDIStocHA8),
            HighPartReg).addReg(PPC::X2).addGlobalAddress(GV);

    if (Subtarget->isGVIndirectSymbol(GV)) {
      assert(!IsAIXTocData && "TOC data should always be direct.");
      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocL),
              DestReg).addGlobalAddress(GV).addReg(HighPartReg);
    } else {
      // Otherwise generate the ADDItocL8.
      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDItocL8),
              DestReg)
          .addReg(HighPartReg)
          .addGlobalAddress(GV);
    }
  }

  return DestReg;
}

// Materialize a 32-bit integer constant into a register, and return
// the register number (or zero if we failed to handle it).
Register PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
                                             const TargetRegisterClass *RC) {
  unsigned Lo = Imm & 0xFFFF;
  unsigned Hi = (Imm >> 16) & 0xFFFF;

  Register ResultReg = createResultReg(RC);
  bool IsGPRC = RC->hasSuperClassEq(&PPC::GPRCRegClass);

  if (isInt<16>(Imm))
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
            TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
      .addImm(Imm);
  else if (Lo) {
    // Both Lo and Hi have nonzero bits.
    Register TmpReg = createResultReg(RC);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
            TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
      .addImm(Hi);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
            TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
      .addReg(TmpReg).addImm(Lo);
  } else
    // Just Hi bits.
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
            TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
        .addImm(Hi);

  return ResultReg;
}

// Materialize a 64-bit integer constant into a register, and return
// the register number (or zero if we failed to handle it).
Register PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
                                             const TargetRegisterClass *RC) {
  unsigned Remainder = 0;
  unsigned Shift = 0;

  // If the value doesn't fit in 32 bits, see if we can shift it
  // so that it fits in 32 bits.
  if (!isInt<32>(Imm)) {
    Shift = llvm::countr_zero<uint64_t>(Imm);
    int64_t ImmSh = static_cast<uint64_t>(Imm) >> Shift;

    if (isInt<32>(ImmSh))
      Imm = ImmSh;
    else {
      Remainder = Imm;
      Shift = 32;
      Imm >>= 32;
    }
  }

  // Handle the high-order 32 bits (if shifted) or the whole 32 bits
  // (if not shifted).
  Register TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
  if (!Shift)
    return TmpReg1;

  // If upper 32 bits were not zero, we've built them and need to shift
  // them into place.
  Register TmpReg2;
  if (Imm) {
    TmpReg2 = createResultReg(RC);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::RLDICR),
            TmpReg2).addReg(TmpReg1).addImm(Shift).addImm(63 - Shift);
  } else
    TmpReg2 = TmpReg1;

  Register TmpReg3;
  unsigned Hi, Lo;
  if ((Hi = (Remainder >> 16) & 0xFFFF)) {
    TmpReg3 = createResultReg(RC);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ORIS8),
            TmpReg3).addReg(TmpReg2).addImm(Hi);
  } else
    TmpReg3 = TmpReg2;

  if ((Lo = Remainder & 0xFFFF)) {
    Register ResultReg = createResultReg(RC);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ORI8),
            ResultReg).addReg(TmpReg3).addImm(Lo);
    return ResultReg;
  }

  return TmpReg3;
}

// Materialize an integer constant into a register, and return
// the register number (or zero if we failed to handle it).
Register PPCFastISel::PPCMaterializeInt(const ConstantInt *CI, MVT VT,
                                        bool UseSExt) {
  // If we're using CR bit registers for i1 values, handle that as a special
  // case first.
  if (VT == MVT::i1 && Subtarget->useCRBits()) {
    Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
            TII.get(CI->isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
    return ImmReg;
  }

  if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
      VT != MVT::i1)
    return Register();

  const TargetRegisterClass *RC =
      ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
  int64_t Imm = UseSExt ? CI->getSExtValue() : CI->getZExtValue();

  // If the constant is in range, use a load-immediate.
  // Since LI will sign extend the constant we need to make sure that for
  // our zeroext constants that the sign extended constant fits into 16-bits -
  // a range of 0..0x7fff.
  if (isInt<16>(Imm)) {
    unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
    Register ImmReg = createResultReg(RC);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ImmReg)
        .addImm(Imm);
    return ImmReg;
  }

  // Construct the constant piecewise.
  if (VT == MVT::i64)
    return PPCMaterialize64BitInt(Imm, RC);
  else if (VT == MVT::i32)
    return PPCMaterialize32BitInt(Imm, RC);

  return Register();
}

// Materialize a constant into a register, and return the register
// number (or zero if we failed to handle it).
Register PPCFastISel::fastMaterializeConstant(const Constant *C) {
  EVT CEVT = TLI.getValueType(DL, C->getType(), true);

  // Only handle simple types.
  if (!CEVT.isSimple())
    return Register();
  MVT VT = CEVT.getSimpleVT();

  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
    return PPCMaterializeFP(CFP, VT);
  else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
    return PPCMaterializeGV(GV, VT);
  else if (const ConstantInt *CI = dyn_cast<ConstantInt>(C))
    // Note that the code in FunctionLoweringInfo::ComputePHILiveOutRegInfo
    // assumes that constant PHI operands will be zero extended, and failure to
    // match that assumption will cause problems if we sign extend here but
    // some user of a PHI is in a block for which we fall back to full SDAG
    // instruction selection.
    return PPCMaterializeInt(CI, VT, false);

  return Register();
}

// Materialize the address created by an alloca into a register, and
// return the register number (or zero if we failed to handle it).
Register PPCFastISel::fastMaterializeAlloca(const AllocaInst *AI) {
  auto SI = FuncInfo.StaticAllocaMap.find(AI);

  // Don't handle dynamic allocas.
  if (SI == FuncInfo.StaticAllocaMap.end())
    return Register();

  MVT VT;
  if (!isLoadTypeLegal(AI->getType(), VT))
    return Register();

  if (SI != FuncInfo.StaticAllocaMap.end()) {
    Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDI8),
            ResultReg).addFrameIndex(SI->second).addImm(0);
    return ResultReg;
  }

  return Register();
}

// Fold loads into extends when possible.
// FIXME: We can have multiple redundant extend/trunc instructions
// following a load.  The folding only picks up one.  Extend this
// to check subsequent instructions for the same pattern and remove
// them.  Thus ResultReg should be the def reg for the last redundant
// instruction in a chain, and all intervening instructions can be
// removed from parent.  Change test/CodeGen/PowerPC/fast-isel-fold.ll
// to add ELF64-NOT: rldicl to the appropriate tests when this works.
bool PPCFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
                                      const LoadInst *LI) {
  // Verify we have a legal type before going any further.
  MVT VT;
  if (!isLoadTypeLegal(LI->getType(), VT))
    return false;

  // Combine load followed by zero- or sign-extend.
  bool IsZExt = false;
  switch(MI->getOpcode()) {
    default:
      return false;

    case PPC::RLDICL:
    case PPC::RLDICL_32_64: {
      IsZExt = true;
      unsigned MB = MI->getOperand(3).getImm();
      if ((VT == MVT::i8 && MB <= 56) ||
          (VT == MVT::i16 && MB <= 48) ||
          (VT == MVT::i32 && MB <= 32))
        break;
      return false;
    }

    case PPC::RLWINM:
    case PPC::RLWINM8: {
      IsZExt = true;
      unsigned MB = MI->getOperand(3).getImm();
      if ((VT == MVT::i8 && MB <= 24) ||
          (VT == MVT::i16 && MB <= 16))
        break;
      return false;
    }

    case PPC::EXTSB:
    case PPC::EXTSB8:
    case PPC::EXTSB8_32_64:
      /* There is no sign-extending load-byte instruction. */
      return false;

    case PPC::EXTSH:
    case PPC::EXTSH8:
    case PPC::EXTSH8_32_64: {
      if (VT != MVT::i16 && VT != MVT::i8)
        return false;
      break;
    }

    case PPC::EXTSW:
    case PPC::EXTSW_32:
    case PPC::EXTSW_32_64: {
      if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8)
        return false;
      break;
    }
  }

  // See if we can handle this address.
  Address Addr;
  if (!PPCComputeAddress(LI->getOperand(0), Addr))
    return false;

  Register ResultReg = MI->getOperand(0).getReg();

  if (!PPCEmitLoad(VT, ResultReg, Addr, nullptr, IsZExt,
                   Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
    return false;

  MachineBasicBlock::iterator I(MI);
  removeDeadCode(I, std::next(I));
  return true;
}

// Attempt to lower call arguments in a faster way than done by
// the selection DAG code.
bool PPCFastISel::fastLowerArguments() {
  // Defer to normal argument lowering for now.  It's reasonably
  // efficient.  Consider doing something like ARM to handle the
  // case where all args fit in registers, no varargs, no float
  // or vector args.
  return false;
}

// Handle materializing integer constants into a register.  This is not
// automatically generated for PowerPC, so must be explicitly created here.
Register PPCFastISel::fastEmit_i(MVT Ty, MVT VT, unsigned Opc, uint64_t Imm) {

  if (Opc != ISD::Constant)
    return Register();

  // If we're using CR bit registers for i1 values, handle that as a special
  // case first.
  if (VT == MVT::i1 && Subtarget->useCRBits()) {
    Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
            TII.get(Imm == 0 ? PPC::CRUNSET : PPC::CRSET), ImmReg);
    return ImmReg;
  }

  if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
      VT != MVT::i1)
    return Register();

  const TargetRegisterClass *RC = ((VT == MVT::i64) ? &PPC::G8RCRegClass :
                                   &PPC::GPRCRegClass);
  if (VT == MVT::i64)
    return PPCMaterialize64BitInt(Imm, RC);
  else
    return PPCMaterialize32BitInt(Imm, RC);
}

// Override for ADDI and ADDI8 to set the correct register class
// on RHS operand 0.  The automatic infrastructure naively assumes
// GPRC for i32 and G8RC for i64; the concept of "no R0" is lost
// for these cases.  At the moment, none of the other automatically
// generated RI instructions require special treatment.  However, once
// SelectSelect is implemented, "isel" requires similar handling.
//
// Also be conservative about the output register class.  Avoid
// assigning R0 or X0 to the output register for GPRC and G8RC
// register classes, as any such result could be used in ADDI, etc.,
// where those regs have another meaning.
Register PPCFastISel::fastEmitInst_ri(unsigned MachineInstOpcode,
                                      const TargetRegisterClass *RC,
                                      Register Op0, uint64_t Imm) {
  if (MachineInstOpcode == PPC::ADDI)
    MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
  else if (MachineInstOpcode == PPC::ADDI8)
    MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);

  const TargetRegisterClass *UseRC =
    (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
     (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));

  return FastISel::fastEmitInst_ri(MachineInstOpcode, UseRC, Op0, Imm);
}

// Override for instructions with one register operand to avoid use of
// R0/X0.  The automatic infrastructure isn't aware of the context so
// we must be conservative.
Register PPCFastISel::fastEmitInst_r(unsigned MachineInstOpcode,
                                     const TargetRegisterClass *RC,
                                     Register Op0) {
  const TargetRegisterClass *UseRC =
    (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
     (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));

  return FastISel::fastEmitInst_r(MachineInstOpcode, UseRC, Op0);
}

// Override for instructions with two register operands to avoid use
// of R0/X0.  The automatic infrastructure isn't aware of the context
// so we must be conservative.
Register PPCFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,
                                      const TargetRegisterClass *RC,
                                      Register Op0, Register Op1) {
  const TargetRegisterClass *UseRC =
    (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
     (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));

  return FastISel::fastEmitInst_rr(MachineInstOpcode, UseRC, Op0, Op1);
}

namespace llvm {
  // Create the fast instruction selector for PowerPC64 ELF.
FastISel *PPC::createFastISel(FunctionLoweringInfo &FuncInfo,
                              const TargetLibraryInfo *LibInfo,
                              const LibcallLoweringInfo *LibcallLowering) {
  // Only available on 64-bit for now.
  const PPCSubtarget &Subtarget = FuncInfo.MF->getSubtarget<PPCSubtarget>();
  if (Subtarget.isPPC64())
    return new PPCFastISel(FuncInfo, LibInfo, LibcallLowering);
  return nullptr;
}
}
