//===- MipsRegisterBankInfo.cpp ---------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
/// \file
/// This file implements the targeting of the RegisterBankInfo class for Mips.
/// \todo This should be generated by TableGen.
//===----------------------------------------------------------------------===//

#include "MipsRegisterBankInfo.h"
#include "MipsInstrInfo.h"
#include "MipsTargetMachine.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"

#define GET_TARGET_REGBANK_IMPL

#include "MipsGenRegisterBank.inc"

namespace llvm {
namespace Mips {
enum PartialMappingIdx {
  PMI_GPR32,
  PMI_GPR64,
  PMI_SPR,
  PMI_DPR,
  PMI_MSA,
  PMI_Min = PMI_GPR32,
};

const RegisterBankInfo::PartialMapping PartMappings[]{{0, 32, GPRBRegBank},
                                                      {0, 64, GPRBRegBank},
                                                      {0, 32, FPRBRegBank},
                                                      {0, 64, FPRBRegBank},
                                                      {0, 128, FPRBRegBank}};

enum ValueMappingIdx {
  InvalidIdx = 0,
  GPR32Idx = 1,
  GPR64Idx = 4,
  SPRIdx = 7,
  DPRIdx = 10,
  MSAIdx = 13
};

const RegisterBankInfo::ValueMapping ValueMappings[] = {
    // invalid
    {nullptr, 0},
    // up to 3 operands in GPRs; 32 bit.
    {&PartMappings[PMI_GPR32 - PMI_Min], 1},
    {&PartMappings[PMI_GPR32 - PMI_Min], 1},
    {&PartMappings[PMI_GPR32 - PMI_Min], 1},
    // up to 3 operands in GPRs; 64 bit.
    {&PartMappings[PMI_GPR64 - PMI_Min], 1},
    {&PartMappings[PMI_GPR64 - PMI_Min], 1},
    {&PartMappings[PMI_GPR64 - PMI_Min], 1},
    // up to 3 operands in FPRs - single precission
    {&PartMappings[PMI_SPR - PMI_Min], 1},
    {&PartMappings[PMI_SPR - PMI_Min], 1},
    {&PartMappings[PMI_SPR - PMI_Min], 1},
    // up to 3 operands in FPRs - double precission
    {&PartMappings[PMI_DPR - PMI_Min], 1},
    {&PartMappings[PMI_DPR - PMI_Min], 1},
    {&PartMappings[PMI_DPR - PMI_Min], 1},
    // up to 3 operands in FPRs - MSA
    {&PartMappings[PMI_MSA - PMI_Min], 1},
    {&PartMappings[PMI_MSA - PMI_Min], 1},
    {&PartMappings[PMI_MSA - PMI_Min], 1}};

} // end namespace Mips
} // end namespace llvm

using namespace llvm;

MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) {}

// Instructions where use operands are floating point registers.
// Def operands are general purpose.
static bool isFloatingPointOpcodeUse(unsigned Opc) {
  switch (Opc) {
  case TargetOpcode::G_FPTOSI:
  case TargetOpcode::G_FPTOUI:
  case TargetOpcode::G_FCMP:
    return true;
  default:
    return isPreISelGenericFloatingPointOpcode(Opc);
  }
}

// Instructions where def operands are floating point registers.
// Use operands are general purpose.
static bool isFloatingPointOpcodeDef(unsigned Opc) {
  switch (Opc) {
  case TargetOpcode::G_SITOFP:
  case TargetOpcode::G_UITOFP:
    return true;
  default:
    return isPreISelGenericFloatingPointOpcode(Opc);
  }
}

static bool isGprbTwoInstrUnalignedLoadOrStore(const MachineInstr *MI) {
  if (MI->getOpcode() == TargetOpcode::G_LOAD ||
      MI->getOpcode() == TargetOpcode::G_STORE) {
    auto MMO = *MI->memoperands_begin();
    const MipsSubtarget &STI = MI->getMF()->getSubtarget<MipsSubtarget>();
    if (MMO->getSize() == 4 && (!STI.systemSupportsUnalignedAccess() &&
                                (!MMO->getSize().hasValue() ||
                                 MMO->getAlign() < MMO->getSize().getValue())))
      return true;
  }
  return false;
}

static bool isAmbiguous(unsigned Opc) {
  switch (Opc) {
  case TargetOpcode::G_LOAD:
  case TargetOpcode::G_STORE:
  case TargetOpcode::G_PHI:
  case TargetOpcode::G_SELECT:
  case TargetOpcode::G_IMPLICIT_DEF:
  case TargetOpcode::G_UNMERGE_VALUES:
  case TargetOpcode::G_MERGE_VALUES:
    return true;
  default:
    return false;
  }
}

void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses(
    Register Reg, const MachineRegisterInfo &MRI) {
  assert(!MRI.getType(Reg).isPointer() &&
         "Pointers are gprb, they should not be considered as ambiguous.\n");
  for (MachineInstr &UseMI : MRI.use_instructions(Reg)) {
    MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI);
    // Copy with many uses.
    if (NonCopyInstr->getOpcode() == TargetOpcode::COPY &&
        !NonCopyInstr->getOperand(0).getReg().isPhysical())
      addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI);
    else
      DefUses.push_back(skipCopiesOutgoing(&UseMI));
  }
}

void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef(
    Register Reg, const MachineRegisterInfo &MRI) {
  assert(!MRI.getType(Reg).isPointer() &&
         "Pointers are gprb, they should not be considered as ambiguous.\n");
  MachineInstr *DefMI = MRI.getVRegDef(Reg);
  UseDefs.push_back(skipCopiesIncoming(DefMI));
}

MachineInstr *
MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing(
    MachineInstr *MI) const {
  const MachineFunction &MF = *MI->getParent()->getParent();
  const MachineRegisterInfo &MRI = MF.getRegInfo();
  MachineInstr *Ret = MI;
  while (Ret->getOpcode() == TargetOpcode::COPY &&
         !Ret->getOperand(0).getReg().isPhysical() &&
         MRI.hasOneUse(Ret->getOperand(0).getReg())) {
    Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg()));
  }
  return Ret;
}

MachineInstr *
MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming(
    MachineInstr *MI) const {
  const MachineFunction &MF = *MI->getParent()->getParent();
  const MachineRegisterInfo &MRI = MF.getRegInfo();
  MachineInstr *Ret = MI;
  while (Ret->getOpcode() == TargetOpcode::COPY &&
         !Ret->getOperand(1).getReg().isPhysical())
    Ret = MRI.getVRegDef(Ret->getOperand(1).getReg());
  return Ret;
}

MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
    const MachineInstr *MI) {
  assert(isAmbiguous(MI->getOpcode()) &&
         "Not implemented for non Ambiguous opcode.\n");

  const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();

  if (MI->getOpcode() == TargetOpcode::G_LOAD)
    addDefUses(MI->getOperand(0).getReg(), MRI);

  if (MI->getOpcode() == TargetOpcode::G_STORE)
    addUseDef(MI->getOperand(0).getReg(), MRI);

  if (auto *PHI = dyn_cast<GPhi>(MI)) {
    addDefUses(PHI->getReg(0), MRI);

    for (unsigned I = 1; I < PHI->getNumIncomingValues(); ++I)
      addUseDef(PHI->getIncomingValue(I), MRI);
  }

  if (MI->getOpcode() == TargetOpcode::G_SELECT) {
    addDefUses(MI->getOperand(0).getReg(), MRI);

    addUseDef(MI->getOperand(2).getReg(), MRI);
    addUseDef(MI->getOperand(3).getReg(), MRI);
  }

  if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
    addDefUses(MI->getOperand(0).getReg(), MRI);

  if (MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)
    addUseDef(MI->getOperand(MI->getNumOperands() - 1).getReg(), MRI);

  if (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
      addDefUses(MI->getOperand(0).getReg(), MRI);
}

bool MipsRegisterBankInfo::TypeInfoForMF::visit(
    const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI,
    InstType &AmbiguousTy) {
  assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n");
  if (wasVisited(MI))
    return true; // InstType has already been determined for MI.

  startVisit(MI);
  AmbiguousRegDefUseContainer DefUseContainer(MI);

  if (isGprbTwoInstrUnalignedLoadOrStore(MI)) {
    setTypes(MI, Integer);
    return true;
  }

  if (AmbiguousTy == InstType::Ambiguous &&
      (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
       MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
    AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge;

  // Visit instructions where MI's DEF operands are USED.
  if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true, AmbiguousTy))
    return true;

  // Visit instructions that DEFINE MI's USE operands.
  if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false, AmbiguousTy))
    return true;

  // All MI's adjacent instructions, are ambiguous.
  if (!WaitingForTypeOfMI) {
    // This is chain of ambiguous instructions.
    setTypes(MI, AmbiguousTy);
    return true;
  }
  // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous
  // instructions or has no other adjacent instructions. Anyway InstType could
  // not be determined. There could be unexplored path from some of
  // WaitingForTypeOfMI's adjacent instructions to an instruction with only one
  // mapping available.
  // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue,
  // this way when WaitingForTypeOfMI figures out its InstType same InstType
  // will be assigned to all instructions in this branch.
  addToWaitingQueue(WaitingForTypeOfMI, MI);
  return false;
}

bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs(
    const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs,
    bool isDefUse, InstType &AmbiguousTy) {
  while (!AdjacentInstrs.empty()) {
    MachineInstr *AdjMI = AdjacentInstrs.pop_back_val();

    if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode())
                 : isFloatingPointOpcodeDef(AdjMI->getOpcode())) {
      setTypes(MI, InstType::FloatingPoint);
      return true;
    }

    // Determine InstType from register bank of phys register that is
    // 'isDefUse ? def : use' of this copy.
    if (AdjMI->getOpcode() == TargetOpcode::COPY) {
      setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1);
      return true;
    }

    // Defaults to integer instruction. Small registers in G_MERGE (uses) and
    // G_UNMERGE (defs) will always be gprb.
    if ((!isDefUse && AdjMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) ||
        (isDefUse && AdjMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) ||
        !isAmbiguous(AdjMI->getOpcode())) {
      setTypes(MI, InstType::Integer);
      return true;
    }

    // When AdjMI was visited first, MI has to continue to explore remaining
    // adjacent instructions and determine InstType without visiting AdjMI.
    if (!wasVisited(AdjMI) ||
        getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) {
      if (visit(AdjMI, MI, AmbiguousTy)) {
        // InstType is successfully determined and is same as for AdjMI.
        setTypes(MI, getRecordedTypeForInstr(AdjMI));
        return true;
      }
    }
  }
  return false;
}

void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI,
                                                   InstType InstTy) {
  changeRecordedTypeForInstr(MI, InstTy);
  for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) {
    setTypes(WaitingInstr, InstTy);
  }
}

void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister(
    const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) {
  assert((CopyInst->getOperand(Op).getReg().isPhysical()) &&
         "Copies of non physical registers should not be considered here.\n");

  const MachineFunction &MF = *CopyInst->getMF();
  const MachineRegisterInfo &MRI = MF.getRegInfo();
  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
  const RegisterBankInfo &RBI =
      *CopyInst->getMF()->getSubtarget().getRegBankInfo();
  const RegisterBank *Bank =
      RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI);

  if (Bank == &Mips::FPRBRegBank)
    setTypes(MI, InstType::FloatingPoint);
  else if (Bank == &Mips::GPRBRegBank)
    setTypes(MI, InstType::Integer);
  else
    llvm_unreachable("Unsupported register bank.\n");
}

MipsRegisterBankInfo::InstType
MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) {
  InstType DefaultAmbiguousType = InstType::Ambiguous;
  visit(MI, nullptr, DefaultAmbiguousType);
  return getRecordedTypeForInstr(MI);
}

void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction(
    llvm::StringRef FunctionName) {
  if (MFName != FunctionName) {
    MFName = std::string(FunctionName);
    WaitingQueues.clear();
    Types.clear();
  }
}

static const MipsRegisterBankInfo::ValueMapping *
getMSAMapping(const MachineFunction &MF) {
  assert(MF.getSubtarget<MipsSubtarget>().hasMSA() &&
         "MSA mapping not available on target without MSA.");
  return &Mips::ValueMappings[Mips::MSAIdx];
}

static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) {
  return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
                    : &Mips::ValueMappings[Mips::DPRIdx];
}

static const unsigned CustomMappingID = 1;

// Only 64 bit mapping is available in fprb and will be marked as custom, i.e.
// will be split into two 32 bit registers in gprb.
static const MipsRegisterBankInfo::ValueMapping *
getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) {
  if (Size == 32)
    return &Mips::ValueMappings[Mips::GPR32Idx];

  MappingID = CustomMappingID;
  return &Mips::ValueMappings[Mips::DPRIdx];
}

const RegisterBankInfo::InstructionMapping &
MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {

  static TypeInfoForMF TI;

  // Reset TI internal data when MF changes.
  TI.cleanupIfNewFunction(MI.getMF()->getName());

  unsigned Opc = MI.getOpcode();
  const MachineFunction &MF = *MI.getParent()->getParent();
  const MachineRegisterInfo &MRI = MF.getRegInfo();

  if (MI.getOpcode() != TargetOpcode::G_PHI) {
    const RegisterBankInfo::InstructionMapping &Mapping =
        getInstrMappingImpl(MI);
    if (Mapping.isValid())
      return Mapping;
  }

  using namespace TargetOpcode;

  unsigned NumOperands = MI.getNumOperands();
  const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPR32Idx];
  unsigned GPRSize = getMaximumSize(Mips::GPRBRegBankID);
  assert((GPRSize == 32 || GPRSize == 64) && "Unexpected GPR size");
  const ValueMapping *GPRValueMapping =
      GPRSize == 32 ? &Mips::ValueMappings[Mips::GPR32Idx]
                    : &Mips::ValueMappings[Mips::GPR64Idx];
  unsigned MappingID = DefaultMappingID;

  // Check if LLT sizes match sizes of available register banks.
  for (const MachineOperand &Op : MI.operands()) {
    if (Op.isReg()) {
      LLT RegTy = MRI.getType(Op.getReg());

      if (RegTy.isScalar() &&
          (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64))
        return getInvalidInstructionMapping();

      if (RegTy.isVector() && RegTy.getSizeInBits() != 128)
        return getInvalidInstructionMapping();
    }
  }

  const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg());
  unsigned Op0Size = Op0Ty.getSizeInBits();
  InstType InstTy = InstType::Integer;

  switch (Opc) {
  case G_TRUNC:
  case G_UMULH:
  case G_ZEXTLOAD:
  case G_SEXTLOAD:
  case G_PTR_ADD:
  case G_INTTOPTR:
  case G_PTRTOINT:
  case G_AND:
  case G_OR:
  case G_XOR:
  case G_SHL:
  case G_ASHR:
  case G_LSHR:
  case G_BRINDIRECT:
  case G_VASTART:
  case G_BSWAP:
  case G_CTLZ:
    OperandsMapping = GPRValueMapping;
    break;
  case G_ADD:
  case G_SUB:
  case G_MUL:
  case G_SDIV:
  case G_SREM:
  case G_UDIV:
  case G_UREM:
    OperandsMapping = GPRValueMapping;
    if (Op0Size == 128)
      OperandsMapping = getMSAMapping(MF);
    break;
  case G_STORE:
  case G_LOAD: {
    if (Op0Size == 128) {
      OperandsMapping =
          getOperandsMapping({getMSAMapping(MF), GPRValueMapping});
      break;
    }

    if (!Op0Ty.isPointer())
      InstTy = TI.determineInstType(&MI);

    if (isFloatingPoint_32or64(InstTy, Op0Size) ||
        isAmbiguous_64(InstTy, Op0Size)) {
      OperandsMapping =
          getOperandsMapping({getFprbMapping(Op0Size), GPRValueMapping});
    } else if (InstTy == InstType::Integer) {
      OperandsMapping = getOperandsMapping({GPRValueMapping, GPRValueMapping});
    } else {
      assert((isAmbiguous_32(InstTy, Op0Size) ||
              isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
             "Unexpected Inst type");
      OperandsMapping = getOperandsMapping(
          {getGprbOrCustomMapping(Op0Size, MappingID), GPRValueMapping});
    }

    break;
  }
  case G_PHI: {
    if (!Op0Ty.isPointer())
      InstTy = TI.determineInstType(&MI);

    // PHI is copylike and should have one regbank in mapping for def register.
    if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) {
      OperandsMapping =
          getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]});
      TI.clearTypeInfoData(&MI);
      return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping,
                                   /*NumOperands=*/1);
    }
    assert((isInteger_32(InstTy, Op0Size) || isInteger_64(InstTy, Op0Size) ||
            isFloatingPoint_32or64(InstTy, Op0Size) ||
            isAmbiguous_32or64(InstTy, Op0Size)) &&
           "Unexpected Inst type");
    // Use default handling for PHI, i.e. set reg bank of def operand to match
    // register banks of use operands.
    return getInstrMappingImpl(MI);
  }
  case G_SELECT: {
    if (!Op0Ty.isPointer())
      InstTy = TI.determineInstType(&MI);

    if (isFloatingPoint_32or64(InstTy, Op0Size) ||
        isAmbiguous_64(InstTy, Op0Size)) {
      const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size);
      OperandsMapping = getOperandsMapping({Bank, GPRValueMapping, Bank, Bank});
      break;
    } else if (InstTy == InstType::Integer) {
      OperandsMapping = getOperandsMapping(
          {GPRValueMapping, GPRValueMapping, GPRValueMapping, GPRValueMapping});
    } else {
      assert((isAmbiguous_32(InstTy, Op0Size) ||
              isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) &&
             "Unexpected Inst type");
      const RegisterBankInfo::ValueMapping *Bank =
          getGprbOrCustomMapping(Op0Size, MappingID);
      OperandsMapping = getOperandsMapping({Bank, GPRValueMapping, Bank, Bank});
    }
    break;
  }
  case G_IMPLICIT_DEF: {
    if (!Op0Ty.isPointer())
      InstTy = TI.determineInstType(&MI);

    if (isFloatingPoint_32or64(InstTy, Op0Size))
      OperandsMapping = getFprbMapping(Op0Size);
    else if (InstTy == InstType::Integer) {
      OperandsMapping = GPRValueMapping;
    } else {
      assert(isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) &&
             "Unexpected Inst type");
      OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID);
    }
  } break;
  case G_UNMERGE_VALUES: {
    assert(MI.getNumOperands() == 3 && "Unsupported G_UNMERGE_VALUES");
    unsigned Op3Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
    InstTy = TI.determineInstType(&MI);
    assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) ||
            isFloatingPoint_64(InstTy, Op3Size)) &&
           "Unexpected Inst type");
    OperandsMapping = getOperandsMapping(
        {GPRValueMapping, GPRValueMapping, &Mips::ValueMappings[Mips::DPRIdx]});
    if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size))
      MappingID = CustomMappingID;
    break;
  }
  case G_MERGE_VALUES: {
    InstTy = TI.determineInstType(&MI);
    assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) ||
            isFloatingPoint_64(InstTy, Op0Size)) &&
           "Unexpected Inst type");
    OperandsMapping = getOperandsMapping(
        {&Mips::ValueMappings[Mips::DPRIdx], GPRValueMapping, GPRValueMapping});
    if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size))
      MappingID = CustomMappingID;
    break;
  }
  case G_FADD:
  case G_FSUB:
  case G_FMUL:
  case G_FDIV:
  case G_FABS:
  case G_FSQRT:
    OperandsMapping = getFprbMapping(Op0Size);
    if (Op0Size == 128)
      OperandsMapping = getMSAMapping(MF);
    break;
  case G_FCONSTANT:
    OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr});
    break;
  case G_FCMP: {
    unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
    OperandsMapping =
        getOperandsMapping({GPRValueMapping, nullptr, getFprbMapping(Op2Size),
                            getFprbMapping(Op2Size)});
    break;
  }
  case G_FPEXT:
    OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx],
                                          &Mips::ValueMappings[Mips::SPRIdx]});
    break;
  case G_FPTRUNC:
    OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx],
                                          &Mips::ValueMappings[Mips::DPRIdx]});
    break;
  case G_FPTOSI: {
    unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
    OperandsMapping =
        getOperandsMapping({GPRValueMapping, getFprbMapping(SizeFP)});
    break;
  }
  case G_SITOFP:
    OperandsMapping =
        getOperandsMapping({getFprbMapping(Op0Size), GPRValueMapping});
    break;
  case G_CONSTANT:
  case G_FRAME_INDEX:
  case G_GLOBAL_VALUE:
  case G_JUMP_TABLE:
  case G_BRCOND:
    OperandsMapping = getOperandsMapping({GPRValueMapping, nullptr});
    break;
  case G_BRJT:
    OperandsMapping =
        getOperandsMapping({GPRValueMapping, nullptr, GPRValueMapping});
    break;
  case G_ICMP:
    OperandsMapping = getOperandsMapping(
        {GPRValueMapping, nullptr, GPRValueMapping, GPRValueMapping});
    break;
  default:
    return getInvalidInstructionMapping();
  }

  if (MappingID == CustomMappingID)
    TI.clearTypeInfoData(&MI);
  return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping,
                               NumOperands);
}

using InstListTy = GISelWorkList<4>;
namespace {
class InstManager : public GISelChangeObserver {
  InstListTy &InstList;
  MachineIRBuilder &B;

public:
  InstManager(MachineIRBuilder &B, InstListTy &Insts) : InstList(Insts), B(B) {
    assert(!B.isObservingChanges());
    B.setChangeObserver(*this);
  }

  ~InstManager() override { B.stopObservingChanges(); }

  void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); }
  void erasingInstr(MachineInstr &MI) override {}
  void changingInstr(MachineInstr &MI) override {}
  void changedInstr(MachineInstr &MI) override {}
};
} // end anonymous namespace

void MipsRegisterBankInfo::setRegBank(MachineInstr &MI,
                                      MachineRegisterInfo &MRI) const {
  Register Dest = MI.getOperand(0).getReg();
  switch (MI.getOpcode()) {
  case TargetOpcode::G_STORE:
    // No def operands, skip this instruction.
    break;
  case TargetOpcode::G_CONSTANT:
  case TargetOpcode::G_LOAD:
  case TargetOpcode::G_SELECT:
  case TargetOpcode::G_PHI:
  case TargetOpcode::G_IMPLICIT_DEF: {
    assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type.");
    MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
    break;
  }
  case TargetOpcode::G_PTR_ADD: {
    assert(MRI.getType(Dest).isPointer() && "Unexpected operand type.");
    MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID));
    break;
  }
  default:
    llvm_unreachable("Unexpected opcode.");
  }
}

static void
combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner,
                            GUnmerge &MI, GISelChangeObserver &Observer) {
  SmallVector<Register, 4> UpdatedDefs;
  SmallVector<MachineInstr *, 2> DeadInstrs;
  ArtCombiner.tryCombineUnmergeValues(MI, DeadInstrs,
                                      UpdatedDefs, Observer);
  for (MachineInstr *DeadMI : DeadInstrs)
    DeadMI->eraseFromParent();
}

void MipsRegisterBankInfo::applyMappingImpl(
    MachineIRBuilder &Builder, const OperandsMapper &OpdMapper) const {
  MachineInstr &MI = OpdMapper.getMI();
  Builder.setInstrAndDebugLoc(MI);

  InstListTy NewInstrs;
  MachineFunction *MF = MI.getMF();
  MachineRegisterInfo &MRI = OpdMapper.getMRI();
  const LegalizerInfo &LegInfo = *MF->getSubtarget().getLegalizerInfo();

  InstManager NewInstrObserver(Builder, NewInstrs);
  LegalizerHelper Helper(*MF, NewInstrObserver, Builder);
  LegalizationArtifactCombiner ArtCombiner(Builder, MF->getRegInfo(), LegInfo);

  switch (MI.getOpcode()) {
  case TargetOpcode::G_LOAD:
  case TargetOpcode::G_STORE:
  case TargetOpcode::G_PHI:
  case TargetOpcode::G_SELECT:
  case TargetOpcode::G_IMPLICIT_DEF: {
    Helper.narrowScalar(MI, 0, LLT::scalar(32));
    // Handle new instructions.
    while (!NewInstrs.empty()) {
      MachineInstr *NewMI = NewInstrs.pop_back_val();
      // This is new G_UNMERGE that was created during narrowScalar and will
      // not be considered for regbank selection. RegBankSelect for mips
      // visits/makes corresponding G_MERGE first. Combine them here.
      if (auto *Unmerge = dyn_cast<GUnmerge>(NewMI))
        combineAwayG_UNMERGE_VALUES(ArtCombiner, *Unmerge, NewInstrObserver);
      // This G_MERGE will be combined away when its corresponding G_UNMERGE
      // gets regBankSelected.
      else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES)
        continue;
      else
        // Manually set register banks for def operands to 32 bit gprb.
        setRegBank(*NewMI, MRI);
    }
    return;
  }
  case TargetOpcode::G_UNMERGE_VALUES:
    combineAwayG_UNMERGE_VALUES(ArtCombiner, cast<GUnmerge>(MI),
                                NewInstrObserver);
    return;
  default:
    break;
  }

  return applyDefaultMapping(OpdMapper);
}
