1fac93e28SPetar Jovanovic //===- MipsRegisterBankInfo.cpp ---------------------------------*- C++ -*-===// 2fac93e28SPetar Jovanovic // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fac93e28SPetar Jovanovic // 7fac93e28SPetar Jovanovic //===----------------------------------------------------------------------===// 8fac93e28SPetar Jovanovic /// \file 9fac93e28SPetar Jovanovic /// This file implements the targeting of the RegisterBankInfo class for Mips. 10fac93e28SPetar Jovanovic /// \todo This should be generated by TableGen. 11fac93e28SPetar Jovanovic //===----------------------------------------------------------------------===// 12fac93e28SPetar Jovanovic 13fac93e28SPetar Jovanovic #include "MipsRegisterBankInfo.h" 14ec575f6eSPetar Avramovic #include "MipsInstrInfo.h" 15599591f3SPetar Avramovic #include "MipsTargetMachine.h" 16ec575f6eSPetar Avramovic #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 17ec575f6eSPetar Avramovic #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" 18ec575f6eSPetar Avramovic #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 19fac93e28SPetar Jovanovic #include "llvm/CodeGen/MachineRegisterInfo.h" 20fac93e28SPetar Jovanovic 21366857a2SPetar Jovanovic #define GET_TARGET_REGBANK_IMPL 22fac93e28SPetar Jovanovic 23366857a2SPetar Jovanovic #include "MipsGenRegisterBank.inc" 24366857a2SPetar Jovanovic 25366857a2SPetar Jovanovic namespace llvm { 26366857a2SPetar Jovanovic namespace Mips { 27366857a2SPetar Jovanovic enum PartialMappingIdx { 28366857a2SPetar Jovanovic PMI_GPR, 291af05df3SPetar Avramovic PMI_SPR, 301af05df3SPetar Avramovic PMI_DPR, 31599591f3SPetar Avramovic PMI_MSA, 32366857a2SPetar Jovanovic PMI_Min = PMI_GPR, 33366857a2SPetar Jovanovic }; 34366857a2SPetar Jovanovic 35366857a2SPetar Jovanovic RegisterBankInfo::PartialMapping PartMappings[]{ 361af05df3SPetar Avramovic {0, 32, GPRBRegBank}, 371af05df3SPetar Avramovic {0, 32, FPRBRegBank}, 38599591f3SPetar Avramovic {0, 64, FPRBRegBank}, 39599591f3SPetar Avramovic {0, 128, FPRBRegBank} 40366857a2SPetar Jovanovic }; 41366857a2SPetar Jovanovic 421af05df3SPetar Avramovic enum ValueMappingIdx { 431af05df3SPetar Avramovic InvalidIdx = 0, 441af05df3SPetar Avramovic GPRIdx = 1, 451af05df3SPetar Avramovic SPRIdx = 4, 46599591f3SPetar Avramovic DPRIdx = 7, 47599591f3SPetar Avramovic MSAIdx = 10 481af05df3SPetar Avramovic }; 49366857a2SPetar Jovanovic 50366857a2SPetar Jovanovic RegisterBankInfo::ValueMapping ValueMappings[] = { 51366857a2SPetar Jovanovic // invalid 52366857a2SPetar Jovanovic {nullptr, 0}, 531af05df3SPetar Avramovic // up to 3 operands in GPRs 54366857a2SPetar Jovanovic {&PartMappings[PMI_GPR - PMI_Min], 1}, 55366857a2SPetar Jovanovic {&PartMappings[PMI_GPR - PMI_Min], 1}, 561af05df3SPetar Avramovic {&PartMappings[PMI_GPR - PMI_Min], 1}, 57f7c213c9SPetar Avramovic // up to 3 operands in FPRs - single precission 581af05df3SPetar Avramovic {&PartMappings[PMI_SPR - PMI_Min], 1}, 591af05df3SPetar Avramovic {&PartMappings[PMI_SPR - PMI_Min], 1}, 601af05df3SPetar Avramovic {&PartMappings[PMI_SPR - PMI_Min], 1}, 61f7c213c9SPetar Avramovic // up to 3 operands in FPRs - double precission 621af05df3SPetar Avramovic {&PartMappings[PMI_DPR - PMI_Min], 1}, 631af05df3SPetar Avramovic {&PartMappings[PMI_DPR - PMI_Min], 1}, 64599591f3SPetar Avramovic {&PartMappings[PMI_DPR - PMI_Min], 1}, 65599591f3SPetar Avramovic // up to 3 operands in FPRs - MSA 66599591f3SPetar Avramovic {&PartMappings[PMI_MSA - PMI_Min], 1}, 67599591f3SPetar Avramovic {&PartMappings[PMI_MSA - PMI_Min], 1}, 68599591f3SPetar Avramovic {&PartMappings[PMI_MSA - PMI_Min], 1} 691af05df3SPetar Avramovic }; 70366857a2SPetar Jovanovic 71366857a2SPetar Jovanovic } // end namespace Mips 72366857a2SPetar Jovanovic } // end namespace llvm 73366857a2SPetar Jovanovic 74366857a2SPetar Jovanovic using namespace llvm; 75fac93e28SPetar Jovanovic 76*62128719SKazu Hirata MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) {} 77366857a2SPetar Jovanovic 7821309eafSMatt Arsenault const RegisterBank & 7921309eafSMatt Arsenault MipsRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, 8021309eafSMatt Arsenault LLT) const { 81366857a2SPetar Jovanovic using namespace Mips; 82366857a2SPetar Jovanovic 83366857a2SPetar Jovanovic switch (RC.getID()) { 84366857a2SPetar Jovanovic case Mips::GPR32RegClassID: 85366857a2SPetar Jovanovic case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID: 86852dd83bSSimon Atanasyan case Mips::GPRMM16MovePPairFirstRegClassID: 87852dd83bSSimon Atanasyan case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID: 88366857a2SPetar Jovanovic case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: 89852dd83bSSimon Atanasyan case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: 90021e4c82SPetar Jovanovic case Mips::SP32RegClassID: 91efcd3c00SPetar Avramovic case Mips::GP32RegClassID: 92366857a2SPetar Jovanovic return getRegBank(Mips::GPRBRegBankID); 933dfa368dSPetar Avramovic case Mips::FGRCCRegClassID: 94afa3afa3SPetar Avramovic case Mips::FGR32RegClassID: 953dfa368dSPetar Avramovic case Mips::FGR64RegClassID: 963dfa368dSPetar Avramovic case Mips::AFGR64RegClassID: 97599591f3SPetar Avramovic case Mips::MSA128BRegClassID: 98599591f3SPetar Avramovic case Mips::MSA128HRegClassID: 99599591f3SPetar Avramovic case Mips::MSA128WRegClassID: 100599591f3SPetar Avramovic case Mips::MSA128DRegClassID: 1013dfa368dSPetar Avramovic return getRegBank(Mips::FPRBRegBankID); 102366857a2SPetar Jovanovic default: 103366857a2SPetar Jovanovic llvm_unreachable("Register class not supported"); 104366857a2SPetar Jovanovic } 105366857a2SPetar Jovanovic } 106366857a2SPetar Jovanovic 107ec575f6eSPetar Avramovic // Instructions where all register operands are floating point. 108ec575f6eSPetar Avramovic static bool isFloatingPointOpcode(unsigned Opc) { 109ec575f6eSPetar Avramovic switch (Opc) { 110ec575f6eSPetar Avramovic case TargetOpcode::G_FCONSTANT: 111ec575f6eSPetar Avramovic case TargetOpcode::G_FADD: 112ec575f6eSPetar Avramovic case TargetOpcode::G_FSUB: 113ec575f6eSPetar Avramovic case TargetOpcode::G_FMUL: 114ec575f6eSPetar Avramovic case TargetOpcode::G_FDIV: 115ec575f6eSPetar Avramovic case TargetOpcode::G_FABS: 116ec575f6eSPetar Avramovic case TargetOpcode::G_FSQRT: 117ec575f6eSPetar Avramovic case TargetOpcode::G_FCEIL: 118ec575f6eSPetar Avramovic case TargetOpcode::G_FFLOOR: 119ec575f6eSPetar Avramovic case TargetOpcode::G_FPEXT: 120ec575f6eSPetar Avramovic case TargetOpcode::G_FPTRUNC: 121ec575f6eSPetar Avramovic return true; 122ec575f6eSPetar Avramovic default: 123ec575f6eSPetar Avramovic return false; 124ec575f6eSPetar Avramovic } 125ec575f6eSPetar Avramovic } 126ec575f6eSPetar Avramovic 127aa699b20SPetar Avramovic // Instructions where use operands are floating point registers. 128aa699b20SPetar Avramovic // Def operands are general purpose. 129aa699b20SPetar Avramovic static bool isFloatingPointOpcodeUse(unsigned Opc) { 130aa699b20SPetar Avramovic switch (Opc) { 131aa699b20SPetar Avramovic case TargetOpcode::G_FPTOSI: 132aa699b20SPetar Avramovic case TargetOpcode::G_FPTOUI: 133aa699b20SPetar Avramovic case TargetOpcode::G_FCMP: 134aa699b20SPetar Avramovic return true; 135aa699b20SPetar Avramovic default: 136aa699b20SPetar Avramovic return isFloatingPointOpcode(Opc); 137aa699b20SPetar Avramovic } 138aa699b20SPetar Avramovic } 139aa699b20SPetar Avramovic 140ec575f6eSPetar Avramovic // Instructions where def operands are floating point registers. 141ec575f6eSPetar Avramovic // Use operands are general purpose. 142ec575f6eSPetar Avramovic static bool isFloatingPointOpcodeDef(unsigned Opc) { 143ec575f6eSPetar Avramovic switch (Opc) { 144ec575f6eSPetar Avramovic case TargetOpcode::G_SITOFP: 145ec575f6eSPetar Avramovic case TargetOpcode::G_UITOFP: 146ec575f6eSPetar Avramovic return true; 147ec575f6eSPetar Avramovic default: 148ec575f6eSPetar Avramovic return isFloatingPointOpcode(Opc); 149ec575f6eSPetar Avramovic } 150ec575f6eSPetar Avramovic } 151ec575f6eSPetar Avramovic 1525171d152SPetar Avramovic static bool isGprbTwoInstrUnalignedLoadOrStore(const MachineInstr *MI) { 1535171d152SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_LOAD || 1545171d152SPetar Avramovic MI->getOpcode() == TargetOpcode::G_STORE) { 1555171d152SPetar Avramovic auto MMO = *MI->memoperands_begin(); 1565171d152SPetar Avramovic const MipsSubtarget &STI = 1575171d152SPetar Avramovic static_cast<const MipsSubtarget &>(MI->getMF()->getSubtarget()); 1585171d152SPetar Avramovic if (MMO->getSize() == 4 && (!STI.systemSupportsUnalignedAccess() && 15974eac903SGuillaume Chatelet MMO->getAlign() < MMO->getSize())) 1605171d152SPetar Avramovic return true; 1615171d152SPetar Avramovic } 1625171d152SPetar Avramovic return false; 1635171d152SPetar Avramovic } 1645171d152SPetar Avramovic 165ec575f6eSPetar Avramovic static bool isAmbiguous(unsigned Opc) { 166ec575f6eSPetar Avramovic switch (Opc) { 167ec575f6eSPetar Avramovic case TargetOpcode::G_LOAD: 168ec575f6eSPetar Avramovic case TargetOpcode::G_STORE: 169ec575f6eSPetar Avramovic case TargetOpcode::G_PHI: 170ec575f6eSPetar Avramovic case TargetOpcode::G_SELECT: 17175e43a60SPetar Avramovic case TargetOpcode::G_IMPLICIT_DEF: 17292c80529SPetar Avramovic case TargetOpcode::G_UNMERGE_VALUES: 17392c80529SPetar Avramovic case TargetOpcode::G_MERGE_VALUES: 174ec575f6eSPetar Avramovic return true; 175ec575f6eSPetar Avramovic default: 176ec575f6eSPetar Avramovic return false; 177ec575f6eSPetar Avramovic } 178ec575f6eSPetar Avramovic } 179ec575f6eSPetar Avramovic 180aa699b20SPetar Avramovic void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addDefUses( 181aa699b20SPetar Avramovic Register Reg, const MachineRegisterInfo &MRI) { 182aa699b20SPetar Avramovic assert(!MRI.getType(Reg).isPointer() && 183aa699b20SPetar Avramovic "Pointers are gprb, they should not be considered as ambiguous.\n"); 184aa699b20SPetar Avramovic for (MachineInstr &UseMI : MRI.use_instructions(Reg)) { 18596252407SPetar Avramovic MachineInstr *NonCopyInstr = skipCopiesOutgoing(&UseMI); 18696252407SPetar Avramovic // Copy with many uses. 18796252407SPetar Avramovic if (NonCopyInstr->getOpcode() == TargetOpcode::COPY && 1882bea69bfSDaniel Sanders !Register::isPhysicalRegister(NonCopyInstr->getOperand(0).getReg())) 18996252407SPetar Avramovic addDefUses(NonCopyInstr->getOperand(0).getReg(), MRI); 19096252407SPetar Avramovic else 19196252407SPetar Avramovic DefUses.push_back(skipCopiesOutgoing(&UseMI)); 192aa699b20SPetar Avramovic } 193aa699b20SPetar Avramovic } 194aa699b20SPetar Avramovic 195ec575f6eSPetar Avramovic void MipsRegisterBankInfo::AmbiguousRegDefUseContainer::addUseDef( 196ec575f6eSPetar Avramovic Register Reg, const MachineRegisterInfo &MRI) { 197ec575f6eSPetar Avramovic assert(!MRI.getType(Reg).isPointer() && 198ec575f6eSPetar Avramovic "Pointers are gprb, they should not be considered as ambiguous.\n"); 199ec575f6eSPetar Avramovic MachineInstr *DefMI = MRI.getVRegDef(Reg); 20096252407SPetar Avramovic UseDefs.push_back(skipCopiesIncoming(DefMI)); 20196252407SPetar Avramovic } 202ec575f6eSPetar Avramovic 20396252407SPetar Avramovic MachineInstr * 20496252407SPetar Avramovic MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesOutgoing( 20596252407SPetar Avramovic MachineInstr *MI) const { 20696252407SPetar Avramovic const MachineFunction &MF = *MI->getParent()->getParent(); 20796252407SPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 20896252407SPetar Avramovic MachineInstr *Ret = MI; 20996252407SPetar Avramovic while (Ret->getOpcode() == TargetOpcode::COPY && 2102bea69bfSDaniel Sanders !Register::isPhysicalRegister(Ret->getOperand(0).getReg()) && 21196252407SPetar Avramovic MRI.hasOneUse(Ret->getOperand(0).getReg())) { 21296252407SPetar Avramovic Ret = &(*MRI.use_instr_begin(Ret->getOperand(0).getReg())); 21396252407SPetar Avramovic } 21496252407SPetar Avramovic return Ret; 21596252407SPetar Avramovic } 21696252407SPetar Avramovic 21796252407SPetar Avramovic MachineInstr * 21896252407SPetar Avramovic MipsRegisterBankInfo::AmbiguousRegDefUseContainer::skipCopiesIncoming( 21996252407SPetar Avramovic MachineInstr *MI) const { 22096252407SPetar Avramovic const MachineFunction &MF = *MI->getParent()->getParent(); 22196252407SPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 22296252407SPetar Avramovic MachineInstr *Ret = MI; 22396252407SPetar Avramovic while (Ret->getOpcode() == TargetOpcode::COPY && 2242bea69bfSDaniel Sanders !Register::isPhysicalRegister(Ret->getOperand(1).getReg())) 22596252407SPetar Avramovic Ret = MRI.getVRegDef(Ret->getOperand(1).getReg()); 22696252407SPetar Avramovic return Ret; 227ec575f6eSPetar Avramovic } 228ec575f6eSPetar Avramovic 229ec575f6eSPetar Avramovic MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer( 230ec575f6eSPetar Avramovic const MachineInstr *MI) { 231ec575f6eSPetar Avramovic assert(isAmbiguous(MI->getOpcode()) && 232ec575f6eSPetar Avramovic "Not implemented for non Ambiguous opcode.\n"); 233ec575f6eSPetar Avramovic 234ec575f6eSPetar Avramovic const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo(); 235ec575f6eSPetar Avramovic 236aa699b20SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_LOAD) 237aa699b20SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 238aa699b20SPetar Avramovic 239ec575f6eSPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_STORE) 240ec575f6eSPetar Avramovic addUseDef(MI->getOperand(0).getReg(), MRI); 241dbb6d01dSPetar Avramovic 242be20e361SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_PHI) { 243be20e361SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 244be20e361SPetar Avramovic 245be20e361SPetar Avramovic for (unsigned i = 1; i < MI->getNumOperands(); i += 2) 246be20e361SPetar Avramovic addUseDef(MI->getOperand(i).getReg(), MRI); 247be20e361SPetar Avramovic } 248be20e361SPetar Avramovic 249dbb6d01dSPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_SELECT) { 250dbb6d01dSPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 251dbb6d01dSPetar Avramovic 252dbb6d01dSPetar Avramovic addUseDef(MI->getOperand(2).getReg(), MRI); 253dbb6d01dSPetar Avramovic addUseDef(MI->getOperand(3).getReg(), MRI); 254dbb6d01dSPetar Avramovic } 25575e43a60SPetar Avramovic 25675e43a60SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) 25775e43a60SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 25892c80529SPetar Avramovic 25992c80529SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) 26092c80529SPetar Avramovic addUseDef(MI->getOperand(MI->getNumOperands() - 1).getReg(), MRI); 26192c80529SPetar Avramovic 26292c80529SPetar Avramovic if (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES) 26392c80529SPetar Avramovic addDefUses(MI->getOperand(0).getReg(), MRI); 264ec575f6eSPetar Avramovic } 265ec575f6eSPetar Avramovic 266e3bb0a72SPetar Avramovic bool MipsRegisterBankInfo::TypeInfoForMF::visit( 26792c80529SPetar Avramovic const MachineInstr *MI, const MachineInstr *WaitingForTypeOfMI, 26892c80529SPetar Avramovic InstType &AmbiguousTy) { 269ec575f6eSPetar Avramovic assert(isAmbiguous(MI->getOpcode()) && "Visiting non-Ambiguous opcode.\n"); 270e3bb0a72SPetar Avramovic if (wasVisited(MI)) 271e3bb0a72SPetar Avramovic return true; // InstType has already been determined for MI. 272ec575f6eSPetar Avramovic 273ec575f6eSPetar Avramovic startVisit(MI); 274ec575f6eSPetar Avramovic AmbiguousRegDefUseContainer DefUseContainer(MI); 275ec575f6eSPetar Avramovic 2765171d152SPetar Avramovic if (isGprbTwoInstrUnalignedLoadOrStore(MI)) { 2775171d152SPetar Avramovic setTypes(MI, Integer); 2785171d152SPetar Avramovic return true; 2795171d152SPetar Avramovic } 2805171d152SPetar Avramovic 28192c80529SPetar Avramovic if (AmbiguousTy == InstType::Ambiguous && 28292c80529SPetar Avramovic (MI->getOpcode() == TargetOpcode::G_MERGE_VALUES || 28392c80529SPetar Avramovic MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES)) 28492c80529SPetar Avramovic AmbiguousTy = InstType::AmbiguousWithMergeOrUnmerge; 28592c80529SPetar Avramovic 286aa699b20SPetar Avramovic // Visit instructions where MI's DEF operands are USED. 28792c80529SPetar Avramovic if (visitAdjacentInstrs(MI, DefUseContainer.getDefUses(), true, AmbiguousTy)) 288aa699b20SPetar Avramovic return true; 289aa699b20SPetar Avramovic 290ec575f6eSPetar Avramovic // Visit instructions that DEFINE MI's USE operands. 29192c80529SPetar Avramovic if (visitAdjacentInstrs(MI, DefUseContainer.getUseDefs(), false, AmbiguousTy)) 292ec575f6eSPetar Avramovic return true; 293ec575f6eSPetar Avramovic 294e3bb0a72SPetar Avramovic // All MI's adjacent instructions, are ambiguous. 295e3bb0a72SPetar Avramovic if (!WaitingForTypeOfMI) { 296e3bb0a72SPetar Avramovic // This is chain of ambiguous instructions. 29792c80529SPetar Avramovic setTypes(MI, AmbiguousTy); 298e3bb0a72SPetar Avramovic return true; 299e3bb0a72SPetar Avramovic } 300e3bb0a72SPetar Avramovic // Excluding WaitingForTypeOfMI, MI is either connected to chains of ambiguous 301e3bb0a72SPetar Avramovic // instructions or has no other adjacent instructions. Anyway InstType could 302e3bb0a72SPetar Avramovic // not be determined. There could be unexplored path from some of 303e3bb0a72SPetar Avramovic // WaitingForTypeOfMI's adjacent instructions to an instruction with only one 304e3bb0a72SPetar Avramovic // mapping available. 305e3bb0a72SPetar Avramovic // We are done with this branch, add MI to WaitingForTypeOfMI's WaitingQueue, 306e3bb0a72SPetar Avramovic // this way when WaitingForTypeOfMI figures out its InstType same InstType 307e3bb0a72SPetar Avramovic // will be assigned to all instructions in this branch. 308e3bb0a72SPetar Avramovic addToWaitingQueue(WaitingForTypeOfMI, MI); 309ec575f6eSPetar Avramovic return false; 310ec575f6eSPetar Avramovic } 311ec575f6eSPetar Avramovic 312ec575f6eSPetar Avramovic bool MipsRegisterBankInfo::TypeInfoForMF::visitAdjacentInstrs( 313aa699b20SPetar Avramovic const MachineInstr *MI, SmallVectorImpl<MachineInstr *> &AdjacentInstrs, 31492c80529SPetar Avramovic bool isDefUse, InstType &AmbiguousTy) { 315ec575f6eSPetar Avramovic while (!AdjacentInstrs.empty()) { 316ec575f6eSPetar Avramovic MachineInstr *AdjMI = AdjacentInstrs.pop_back_val(); 317ec575f6eSPetar Avramovic 318aa699b20SPetar Avramovic if (isDefUse ? isFloatingPointOpcodeUse(AdjMI->getOpcode()) 319aa699b20SPetar Avramovic : isFloatingPointOpcodeDef(AdjMI->getOpcode())) { 320ec575f6eSPetar Avramovic setTypes(MI, InstType::FloatingPoint); 321ec575f6eSPetar Avramovic return true; 322ec575f6eSPetar Avramovic } 323ec575f6eSPetar Avramovic 324ec575f6eSPetar Avramovic // Determine InstType from register bank of phys register that is 325aa699b20SPetar Avramovic // 'isDefUse ? def : use' of this copy. 326ec575f6eSPetar Avramovic if (AdjMI->getOpcode() == TargetOpcode::COPY) { 327aa699b20SPetar Avramovic setTypesAccordingToPhysicalRegister(MI, AdjMI, isDefUse ? 0 : 1); 328ec575f6eSPetar Avramovic return true; 329ec575f6eSPetar Avramovic } 330ec575f6eSPetar Avramovic 33192c80529SPetar Avramovic // Defaults to integer instruction. Small registers in G_MERGE (uses) and 33292c80529SPetar Avramovic // G_UNMERGE (defs) will always be gprb. 33392c80529SPetar Avramovic if ((!isDefUse && AdjMI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) || 33492c80529SPetar Avramovic (isDefUse && AdjMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) || 33592c80529SPetar Avramovic !isAmbiguous(AdjMI->getOpcode())) { 336ec575f6eSPetar Avramovic setTypes(MI, InstType::Integer); 337ec575f6eSPetar Avramovic return true; 338ec575f6eSPetar Avramovic } 339e3bb0a72SPetar Avramovic 340e3bb0a72SPetar Avramovic // When AdjMI was visited first, MI has to continue to explore remaining 341e3bb0a72SPetar Avramovic // adjacent instructions and determine InstType without visiting AdjMI. 342e3bb0a72SPetar Avramovic if (!wasVisited(AdjMI) || 343e3bb0a72SPetar Avramovic getRecordedTypeForInstr(AdjMI) != InstType::NotDetermined) { 34492c80529SPetar Avramovic if (visit(AdjMI, MI, AmbiguousTy)) { 345e3bb0a72SPetar Avramovic // InstType is successfully determined and is same as for AdjMI. 346e3bb0a72SPetar Avramovic setTypes(MI, getRecordedTypeForInstr(AdjMI)); 347e3bb0a72SPetar Avramovic return true; 348e3bb0a72SPetar Avramovic } 349e3bb0a72SPetar Avramovic } 350e3bb0a72SPetar Avramovic } 351ec575f6eSPetar Avramovic return false; 352ec575f6eSPetar Avramovic } 353ec575f6eSPetar Avramovic 354ec575f6eSPetar Avramovic void MipsRegisterBankInfo::TypeInfoForMF::setTypes(const MachineInstr *MI, 355ec575f6eSPetar Avramovic InstType InstTy) { 356ec575f6eSPetar Avramovic changeRecordedTypeForInstr(MI, InstTy); 357e3bb0a72SPetar Avramovic for (const MachineInstr *WaitingInstr : getWaitingQueueFor(MI)) { 358e3bb0a72SPetar Avramovic setTypes(WaitingInstr, InstTy); 359e3bb0a72SPetar Avramovic } 360ec575f6eSPetar Avramovic } 361ec575f6eSPetar Avramovic 362ec575f6eSPetar Avramovic void MipsRegisterBankInfo::TypeInfoForMF::setTypesAccordingToPhysicalRegister( 363ec575f6eSPetar Avramovic const MachineInstr *MI, const MachineInstr *CopyInst, unsigned Op) { 3642bea69bfSDaniel Sanders assert((Register::isPhysicalRegister(CopyInst->getOperand(Op).getReg())) && 365ec575f6eSPetar Avramovic "Copies of non physical registers should not be considered here.\n"); 366ec575f6eSPetar Avramovic 367ec575f6eSPetar Avramovic const MachineFunction &MF = *CopyInst->getMF(); 368ec575f6eSPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 369ec575f6eSPetar Avramovic const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 370ec575f6eSPetar Avramovic const RegisterBankInfo &RBI = 371ec575f6eSPetar Avramovic *CopyInst->getMF()->getSubtarget().getRegBankInfo(); 372ec575f6eSPetar Avramovic const RegisterBank *Bank = 373ec575f6eSPetar Avramovic RBI.getRegBank(CopyInst->getOperand(Op).getReg(), MRI, TRI); 374ec575f6eSPetar Avramovic 375ec575f6eSPetar Avramovic if (Bank == &Mips::FPRBRegBank) 376ec575f6eSPetar Avramovic setTypes(MI, InstType::FloatingPoint); 377ec575f6eSPetar Avramovic else if (Bank == &Mips::GPRBRegBank) 378ec575f6eSPetar Avramovic setTypes(MI, InstType::Integer); 379ec575f6eSPetar Avramovic else 380ec575f6eSPetar Avramovic llvm_unreachable("Unsupported register bank.\n"); 381ec575f6eSPetar Avramovic } 382ec575f6eSPetar Avramovic 383ec575f6eSPetar Avramovic MipsRegisterBankInfo::InstType 384ec575f6eSPetar Avramovic MipsRegisterBankInfo::TypeInfoForMF::determineInstType(const MachineInstr *MI) { 38592c80529SPetar Avramovic InstType DefaultAmbiguousType = InstType::Ambiguous; 38692c80529SPetar Avramovic visit(MI, nullptr, DefaultAmbiguousType); 387ec575f6eSPetar Avramovic return getRecordedTypeForInstr(MI); 388ec575f6eSPetar Avramovic } 389ec575f6eSPetar Avramovic 390ec575f6eSPetar Avramovic void MipsRegisterBankInfo::TypeInfoForMF::cleanupIfNewFunction( 391ec575f6eSPetar Avramovic llvm::StringRef FunctionName) { 392ec575f6eSPetar Avramovic if (MFName != FunctionName) { 393adcd0268SBenjamin Kramer MFName = std::string(FunctionName); 394e3bb0a72SPetar Avramovic WaitingQueues.clear(); 395ec575f6eSPetar Avramovic Types.clear(); 396ec575f6eSPetar Avramovic } 397ec575f6eSPetar Avramovic } 398ec575f6eSPetar Avramovic 399599591f3SPetar Avramovic static const MipsRegisterBankInfo::ValueMapping * 400599591f3SPetar Avramovic getMSAMapping(const MachineFunction &MF) { 401599591f3SPetar Avramovic assert(static_cast<const MipsSubtarget &>(MF.getSubtarget()).hasMSA() && 402599591f3SPetar Avramovic "MSA mapping not available on target without MSA."); 403599591f3SPetar Avramovic return &Mips::ValueMappings[Mips::MSAIdx]; 404599591f3SPetar Avramovic } 405599591f3SPetar Avramovic 406f7c213c9SPetar Avramovic static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) { 407f7c213c9SPetar Avramovic return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 408f7c213c9SPetar Avramovic : &Mips::ValueMappings[Mips::DPRIdx]; 409f7c213c9SPetar Avramovic } 410f7c213c9SPetar Avramovic 411f7c213c9SPetar Avramovic static const unsigned CustomMappingID = 1; 412f7c213c9SPetar Avramovic 413f7c213c9SPetar Avramovic // Only 64 bit mapping is available in fprb and will be marked as custom, i.e. 414f7c213c9SPetar Avramovic // will be split into two 32 bit registers in gprb. 415f7c213c9SPetar Avramovic static const MipsRegisterBankInfo::ValueMapping * 416f7c213c9SPetar Avramovic getGprbOrCustomMapping(unsigned Size, unsigned &MappingID) { 417f7c213c9SPetar Avramovic if (Size == 32) 418f7c213c9SPetar Avramovic return &Mips::ValueMappings[Mips::GPRIdx]; 419f7c213c9SPetar Avramovic 420f7c213c9SPetar Avramovic MappingID = CustomMappingID; 421f7c213c9SPetar Avramovic return &Mips::ValueMappings[Mips::DPRIdx]; 422f7c213c9SPetar Avramovic } 423f7c213c9SPetar Avramovic 424366857a2SPetar Jovanovic const RegisterBankInfo::InstructionMapping & 425366857a2SPetar Jovanovic MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 426366857a2SPetar Jovanovic 427ec575f6eSPetar Avramovic static TypeInfoForMF TI; 428ec575f6eSPetar Avramovic 429ec575f6eSPetar Avramovic // Reset TI internal data when MF changes. 430ec575f6eSPetar Avramovic TI.cleanupIfNewFunction(MI.getMF()->getName()); 431ec575f6eSPetar Avramovic 432366857a2SPetar Jovanovic unsigned Opc = MI.getOpcode(); 4331af05df3SPetar Avramovic const MachineFunction &MF = *MI.getParent()->getParent(); 4341af05df3SPetar Avramovic const MachineRegisterInfo &MRI = MF.getRegInfo(); 435366857a2SPetar Jovanovic 436be20e361SPetar Avramovic if (MI.getOpcode() != TargetOpcode::G_PHI) { 437be20e361SPetar Avramovic const RegisterBankInfo::InstructionMapping &Mapping = 438be20e361SPetar Avramovic getInstrMappingImpl(MI); 439366857a2SPetar Jovanovic if (Mapping.isValid()) 440366857a2SPetar Jovanovic return Mapping; 441be20e361SPetar Avramovic } 442366857a2SPetar Jovanovic 443366857a2SPetar Jovanovic using namespace TargetOpcode; 444366857a2SPetar Jovanovic 445366857a2SPetar Jovanovic unsigned NumOperands = MI.getNumOperands(); 446366857a2SPetar Jovanovic const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 447ec575f6eSPetar Avramovic unsigned MappingID = DefaultMappingID; 448f7c213c9SPetar Avramovic 449f7c213c9SPetar Avramovic // Check if LLT sizes match sizes of available register banks. 450f7c213c9SPetar Avramovic for (const MachineOperand &Op : MI.operands()) { 451f7c213c9SPetar Avramovic if (Op.isReg()) { 452f7c213c9SPetar Avramovic LLT RegTy = MRI.getType(Op.getReg()); 453f7c213c9SPetar Avramovic 454f7c213c9SPetar Avramovic if (RegTy.isScalar() && 455f7c213c9SPetar Avramovic (RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64)) 456f7c213c9SPetar Avramovic return getInvalidInstructionMapping(); 457599591f3SPetar Avramovic 458599591f3SPetar Avramovic if (RegTy.isVector() && RegTy.getSizeInBits() != 128) 459599591f3SPetar Avramovic return getInvalidInstructionMapping(); 460f7c213c9SPetar Avramovic } 461f7c213c9SPetar Avramovic } 462f7c213c9SPetar Avramovic 463f7c213c9SPetar Avramovic const LLT Op0Ty = MRI.getType(MI.getOperand(0).getReg()); 464f7c213c9SPetar Avramovic unsigned Op0Size = Op0Ty.getSizeInBits(); 465f7c213c9SPetar Avramovic InstType InstTy = InstType::Integer; 466366857a2SPetar Jovanovic 467366857a2SPetar Jovanovic switch (Opc) { 4687cecadb9SPetar Avramovic case G_TRUNC: 469a48285a1SPetar Avramovic case G_UMULH: 47079df8596SPetar Avramovic case G_ZEXTLOAD: 47179df8596SPetar Avramovic case G_SEXTLOAD: 472e74c5b96SDaniel Sanders case G_PTR_ADD: 473b1fc6f61SPetar Avramovic case G_INTTOPTR: 474b1fc6f61SPetar Avramovic case G_PTRTOINT: 4753b953c37SPetar Jovanovic case G_AND: 4763b953c37SPetar Jovanovic case G_OR: 4773b953c37SPetar Jovanovic case G_XOR: 4783b953c37SPetar Jovanovic case G_SHL: 4793b953c37SPetar Jovanovic case G_ASHR: 4803b953c37SPetar Jovanovic case G_LSHR: 481ff6ac1ebSPetar Avramovic case G_BRINDIRECT: 482c063b0b0SPetar Avramovic case G_VASTART: 48394a24e7aSPetar Avramovic case G_BSWAP: 4842b66d32fSPetar Avramovic case G_CTLZ: 485366857a2SPetar Jovanovic OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 486366857a2SPetar Jovanovic break; 487e4af9de3SPetar Avramovic case G_ADD: 488c46d24f5SPetar Avramovic case G_SUB: 489d1815dacSPetar Avramovic case G_MUL: 4901d7f79c0SPetar Avramovic case G_SDIV: 4911d7f79c0SPetar Avramovic case G_SREM: 4921d7f79c0SPetar Avramovic case G_UDIV: 4931d7f79c0SPetar Avramovic case G_UREM: 494e4af9de3SPetar Avramovic OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 495e4af9de3SPetar Avramovic if (Op0Size == 128) 496e4af9de3SPetar Avramovic OperandsMapping = getMSAMapping(MF); 497e4af9de3SPetar Avramovic break; 498f7c213c9SPetar Avramovic case G_STORE: 49992c80529SPetar Avramovic case G_LOAD: { 500599591f3SPetar Avramovic if (Op0Size == 128) { 501599591f3SPetar Avramovic OperandsMapping = getOperandsMapping( 502599591f3SPetar Avramovic {getMSAMapping(MF), &Mips::ValueMappings[Mips::GPRIdx]}); 503599591f3SPetar Avramovic break; 504599591f3SPetar Avramovic } 505599591f3SPetar Avramovic 506f7c213c9SPetar Avramovic if (!Op0Ty.isPointer()) 507aa699b20SPetar Avramovic InstTy = TI.determineInstType(&MI); 508aa699b20SPetar Avramovic 50992c80529SPetar Avramovic if (isFloatingPoint_32or64(InstTy, Op0Size) || 51092c80529SPetar Avramovic isAmbiguous_64(InstTy, Op0Size)) { 511f7c213c9SPetar Avramovic OperandsMapping = getOperandsMapping( 512f7c213c9SPetar Avramovic {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 51392c80529SPetar Avramovic } else { 51492c80529SPetar Avramovic assert((isInteger_32(InstTy, Op0Size) || 51592c80529SPetar Avramovic isAmbiguous_32(InstTy, Op0Size) || 51692c80529SPetar Avramovic isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) && 51792c80529SPetar Avramovic "Unexpected Inst type"); 518aa699b20SPetar Avramovic OperandsMapping = 519f7c213c9SPetar Avramovic getOperandsMapping({getGprbOrCustomMapping(Op0Size, MappingID), 520aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 52192c80529SPetar Avramovic } 522aa699b20SPetar Avramovic 523aa699b20SPetar Avramovic break; 52492c80529SPetar Avramovic } 52592c80529SPetar Avramovic case G_PHI: { 526f7c213c9SPetar Avramovic if (!Op0Ty.isPointer()) 527ec575f6eSPetar Avramovic InstTy = TI.determineInstType(&MI); 528be20e361SPetar Avramovic 529be20e361SPetar Avramovic // PHI is copylike and should have one regbank in mapping for def register. 53092c80529SPetar Avramovic if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) { 531be20e361SPetar Avramovic OperandsMapping = 532be20e361SPetar Avramovic getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]}); 53392c80529SPetar Avramovic TI.clearTypeInfoData(&MI); 534be20e361SPetar Avramovic return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping, 535be20e361SPetar Avramovic /*NumOperands=*/1); 536be20e361SPetar Avramovic } 53792c80529SPetar Avramovic assert((isInteger_32(InstTy, Op0Size) || 53892c80529SPetar Avramovic isFloatingPoint_32or64(InstTy, Op0Size) || 53992c80529SPetar Avramovic isAmbiguous_32or64(InstTy, Op0Size)) && 54092c80529SPetar Avramovic "Unexpected Inst type"); 541be20e361SPetar Avramovic // Use default handling for PHI, i.e. set reg bank of def operand to match 542be20e361SPetar Avramovic // register banks of use operands. 543f7c213c9SPetar Avramovic return getInstrMappingImpl(MI); 54492c80529SPetar Avramovic } 545dbb6d01dSPetar Avramovic case G_SELECT: { 546f7c213c9SPetar Avramovic if (!Op0Ty.isPointer()) 547dbb6d01dSPetar Avramovic InstTy = TI.determineInstType(&MI); 54892c80529SPetar Avramovic if (isFloatingPoint_32or64(InstTy, Op0Size) || 54992c80529SPetar Avramovic isAmbiguous_64(InstTy, Op0Size)) { 550f7c213c9SPetar Avramovic const RegisterBankInfo::ValueMapping *Bank = getFprbMapping(Op0Size); 551dbb6d01dSPetar Avramovic OperandsMapping = getOperandsMapping( 552dbb6d01dSPetar Avramovic {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 553dbb6d01dSPetar Avramovic break; 554f7c213c9SPetar Avramovic } else { 55592c80529SPetar Avramovic assert((isInteger_32(InstTy, Op0Size) || 55692c80529SPetar Avramovic isAmbiguous_32(InstTy, Op0Size) || 55792c80529SPetar Avramovic isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) && 55892c80529SPetar Avramovic "Unexpected Inst type"); 559dbb6d01dSPetar Avramovic const RegisterBankInfo::ValueMapping *Bank = 560f7c213c9SPetar Avramovic getGprbOrCustomMapping(Op0Size, MappingID); 561dbb6d01dSPetar Avramovic OperandsMapping = getOperandsMapping( 562dbb6d01dSPetar Avramovic {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank}); 563dbb6d01dSPetar Avramovic } 564dbb6d01dSPetar Avramovic break; 565dbb6d01dSPetar Avramovic } 56692c80529SPetar Avramovic case G_IMPLICIT_DEF: { 567f7c213c9SPetar Avramovic if (!Op0Ty.isPointer()) 56875e43a60SPetar Avramovic InstTy = TI.determineInstType(&MI); 56975e43a60SPetar Avramovic 57092c80529SPetar Avramovic if (isFloatingPoint_32or64(InstTy, Op0Size)) 571f7c213c9SPetar Avramovic OperandsMapping = getFprbMapping(Op0Size); 57292c80529SPetar Avramovic else { 57392c80529SPetar Avramovic assert((isInteger_32(InstTy, Op0Size) || 57492c80529SPetar Avramovic isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) && 57592c80529SPetar Avramovic "Unexpected Inst type"); 576f7c213c9SPetar Avramovic OperandsMapping = getGprbOrCustomMapping(Op0Size, MappingID); 57792c80529SPetar Avramovic } 57892c80529SPetar Avramovic } break; 57992c80529SPetar Avramovic case G_UNMERGE_VALUES: { 58092c80529SPetar Avramovic assert(MI.getNumOperands() == 3 && "Unsupported G_UNMERGE_VALUES"); 58192c80529SPetar Avramovic unsigned Op3Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 58292c80529SPetar Avramovic InstTy = TI.determineInstType(&MI); 58392c80529SPetar Avramovic assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size) || 58492c80529SPetar Avramovic isFloatingPoint_64(InstTy, Op3Size)) && 58592c80529SPetar Avramovic "Unexpected Inst type"); 586aa699b20SPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 587aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx], 588aa699b20SPetar Avramovic &Mips::ValueMappings[Mips::DPRIdx]}); 58992c80529SPetar Avramovic if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op3Size)) 590aa699b20SPetar Avramovic MappingID = CustomMappingID; 591aa699b20SPetar Avramovic break; 59292c80529SPetar Avramovic } 59392c80529SPetar Avramovic case G_MERGE_VALUES: { 59492c80529SPetar Avramovic InstTy = TI.determineInstType(&MI); 59592c80529SPetar Avramovic assert((isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size) || 59692c80529SPetar Avramovic isFloatingPoint_64(InstTy, Op0Size)) && 59792c80529SPetar Avramovic "Unexpected Inst type"); 598ec575f6eSPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 599ec575f6eSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx], 600ec575f6eSPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 60192c80529SPetar Avramovic if (isAmbiguousWithMergeOrUnmerge_64(InstTy, Op0Size)) 602ec575f6eSPetar Avramovic MappingID = CustomMappingID; 603ec575f6eSPetar Avramovic break; 60492c80529SPetar Avramovic } 605afa3afa3SPetar Avramovic case G_FADD: 606afa3afa3SPetar Avramovic case G_FSUB: 607afa3afa3SPetar Avramovic case G_FMUL: 6080a1fd355SPetar Avramovic case G_FDIV: 609e3b49df5SPetar Avramovic case G_FABS: 610417dd678SPetar Avramovic case G_FSQRT: 611f7c213c9SPetar Avramovic OperandsMapping = getFprbMapping(Op0Size); 612914ce664SPetar Avramovic if (Op0Size == 128) 613914ce664SPetar Avramovic OperandsMapping = getMSAMapping(MF); 614afa3afa3SPetar Avramovic break; 615f7c213c9SPetar Avramovic case G_FCONSTANT: 616f7c213c9SPetar Avramovic OperandsMapping = getOperandsMapping({getFprbMapping(Op0Size), nullptr}); 6171af05df3SPetar Avramovic break; 61822e99c43SPetar Avramovic case G_FCMP: { 619f7c213c9SPetar Avramovic unsigned Op2Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 62022e99c43SPetar Avramovic OperandsMapping = 62122e99c43SPetar Avramovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 622f7c213c9SPetar Avramovic getFprbMapping(Op2Size), getFprbMapping(Op2Size)}); 62322e99c43SPetar Avramovic break; 62422e99c43SPetar Avramovic } 625a7d00064SPetar Avramovic case G_FPEXT: 626a7d00064SPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 627a7d00064SPetar Avramovic &Mips::ValueMappings[Mips::SPRIdx]}); 628a7d00064SPetar Avramovic break; 629a7d00064SPetar Avramovic case G_FPTRUNC: 630a7d00064SPetar Avramovic OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx], 631a7d00064SPetar Avramovic &Mips::ValueMappings[Mips::DPRIdx]}); 632a7d00064SPetar Avramovic break; 6334b4dae1cSPetar Avramovic case G_FPTOSI: { 634f7c213c9SPetar Avramovic assert((Op0Size == 32) && "Unsupported integer size"); 6354b4dae1cSPetar Avramovic unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 636f7c213c9SPetar Avramovic OperandsMapping = getOperandsMapping( 637f7c213c9SPetar Avramovic {&Mips::ValueMappings[Mips::GPRIdx], getFprbMapping(SizeFP)}); 638f7c213c9SPetar Avramovic break; 639f7c213c9SPetar Avramovic } 640f7c213c9SPetar Avramovic case G_SITOFP: 641f7c213c9SPetar Avramovic assert((MRI.getType(MI.getOperand(1).getReg()).getSizeInBits() == 32) && 642ddd056c9SFangrui Song "Unsupported integer size"); 643f7c213c9SPetar Avramovic OperandsMapping = getOperandsMapping( 644f7c213c9SPetar Avramovic {getFprbMapping(Op0Size), &Mips::ValueMappings[Mips::GPRIdx]}); 6454b4dae1cSPetar Avramovic break; 646021e4c82SPetar Jovanovic case G_CONSTANT: 647021e4c82SPetar Jovanovic case G_FRAME_INDEX: 64864c10ba8SPetar Jovanovic case G_GLOBAL_VALUE: 649caef9306SPetar Avramovic case G_JUMP_TABLE: 6505d9b8eedSPetar Avramovic case G_BRCOND: 651021e4c82SPetar Jovanovic OperandsMapping = 652021e4c82SPetar Jovanovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 653021e4c82SPetar Jovanovic break; 654caef9306SPetar Avramovic case G_BRJT: 655caef9306SPetar Avramovic OperandsMapping = 656caef9306SPetar Avramovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 657caef9306SPetar Avramovic &Mips::ValueMappings[Mips::GPRIdx]}); 658caef9306SPetar Avramovic break; 659ce4dd0aeSPetar Jovanovic case G_ICMP: 660ce4dd0aeSPetar Jovanovic OperandsMapping = 661ce4dd0aeSPetar Jovanovic getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 662ce4dd0aeSPetar Jovanovic &Mips::ValueMappings[Mips::GPRIdx], 663ce4dd0aeSPetar Jovanovic &Mips::ValueMappings[Mips::GPRIdx]}); 664ce4dd0aeSPetar Jovanovic break; 665366857a2SPetar Jovanovic default: 666366857a2SPetar Jovanovic return getInvalidInstructionMapping(); 667366857a2SPetar Jovanovic } 668366857a2SPetar Jovanovic 66992c80529SPetar Avramovic if (MappingID == CustomMappingID) 67092c80529SPetar Avramovic TI.clearTypeInfoData(&MI); 671ec575f6eSPetar Avramovic return getInstructionMapping(MappingID, /*Cost=*/1, OperandsMapping, 672366857a2SPetar Jovanovic NumOperands); 673366857a2SPetar Jovanovic } 674ec575f6eSPetar Avramovic 675ec575f6eSPetar Avramovic using InstListTy = GISelWorkList<4>; 676ec575f6eSPetar Avramovic namespace { 677ec575f6eSPetar Avramovic class InstManager : public GISelChangeObserver { 678ec575f6eSPetar Avramovic InstListTy &InstList; 679ec575f6eSPetar Avramovic 680ec575f6eSPetar Avramovic public: 681ec575f6eSPetar Avramovic InstManager(InstListTy &Insts) : InstList(Insts) {} 682ec575f6eSPetar Avramovic 683ec575f6eSPetar Avramovic void createdInstr(MachineInstr &MI) override { InstList.insert(&MI); } 684ec575f6eSPetar Avramovic void erasingInstr(MachineInstr &MI) override {} 685ec575f6eSPetar Avramovic void changingInstr(MachineInstr &MI) override {} 686ec575f6eSPetar Avramovic void changedInstr(MachineInstr &MI) override {} 687ec575f6eSPetar Avramovic }; 688ec575f6eSPetar Avramovic } // end anonymous namespace 689ec575f6eSPetar Avramovic 690f7c213c9SPetar Avramovic void MipsRegisterBankInfo::setRegBank(MachineInstr &MI, 691f7c213c9SPetar Avramovic MachineRegisterInfo &MRI) const { 692f7c213c9SPetar Avramovic Register Dest = MI.getOperand(0).getReg(); 693f7c213c9SPetar Avramovic switch (MI.getOpcode()) { 694f7c213c9SPetar Avramovic case TargetOpcode::G_STORE: 695f7c213c9SPetar Avramovic // No def operands, skip this instruction. 696f7c213c9SPetar Avramovic break; 697f7c213c9SPetar Avramovic case TargetOpcode::G_CONSTANT: 698f7c213c9SPetar Avramovic case TargetOpcode::G_LOAD: 699f7c213c9SPetar Avramovic case TargetOpcode::G_SELECT: 700f7c213c9SPetar Avramovic case TargetOpcode::G_PHI: 701f7c213c9SPetar Avramovic case TargetOpcode::G_IMPLICIT_DEF: { 702f7c213c9SPetar Avramovic assert(MRI.getType(Dest) == LLT::scalar(32) && "Unexpected operand type."); 703f7c213c9SPetar Avramovic MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 704f7c213c9SPetar Avramovic break; 705f7c213c9SPetar Avramovic } 706e74c5b96SDaniel Sanders case TargetOpcode::G_PTR_ADD: { 707f7c213c9SPetar Avramovic assert(MRI.getType(Dest).isPointer() && "Unexpected operand type."); 708f7c213c9SPetar Avramovic MRI.setRegBank(Dest, getRegBank(Mips::GPRBRegBankID)); 709f7c213c9SPetar Avramovic break; 710f7c213c9SPetar Avramovic } 711f7c213c9SPetar Avramovic default: 712f7c213c9SPetar Avramovic llvm_unreachable("Unexpected opcode."); 713f7c213c9SPetar Avramovic } 714f7c213c9SPetar Avramovic } 715f7c213c9SPetar Avramovic 716f7c213c9SPetar Avramovic static void 717f7c213c9SPetar Avramovic combineAwayG_UNMERGE_VALUES(LegalizationArtifactCombiner &ArtCombiner, 7185ec0f051SAmara Emerson GUnmerge &MI, GISelChangeObserver &Observer) { 7198731799fSRoman Tereshin SmallVector<Register, 4> UpdatedDefs; 720f7c213c9SPetar Avramovic SmallVector<MachineInstr *, 2> DeadInstrs; 7215ec0f051SAmara Emerson ArtCombiner.tryCombineUnmergeValues(MI, DeadInstrs, 7225ec0f051SAmara Emerson UpdatedDefs, Observer); 723f7c213c9SPetar Avramovic for (MachineInstr *DeadMI : DeadInstrs) 724f7c213c9SPetar Avramovic DeadMI->eraseFromParent(); 725f7c213c9SPetar Avramovic } 726f7c213c9SPetar Avramovic 727ec575f6eSPetar Avramovic void MipsRegisterBankInfo::applyMappingImpl( 728ec575f6eSPetar Avramovic const OperandsMapper &OpdMapper) const { 729ec575f6eSPetar Avramovic MachineInstr &MI = OpdMapper.getMI(); 730ec575f6eSPetar Avramovic InstListTy NewInstrs; 731ec575f6eSPetar Avramovic MachineFunction *MF = MI.getMF(); 732ec575f6eSPetar Avramovic MachineRegisterInfo &MRI = OpdMapper.getMRI(); 733f7c213c9SPetar Avramovic const LegalizerInfo &LegInfo = *MF->getSubtarget().getLegalizerInfo(); 734ec575f6eSPetar Avramovic 735ec575f6eSPetar Avramovic InstManager NewInstrObserver(NewInstrs); 736d55d592aSMatt Arsenault MachineIRBuilder B(MI, NewInstrObserver); 737d55d592aSMatt Arsenault LegalizerHelper Helper(*MF, NewInstrObserver, B); 738f7c213c9SPetar Avramovic LegalizationArtifactCombiner ArtCombiner(B, MF->getRegInfo(), LegInfo); 739ec575f6eSPetar Avramovic 740ec575f6eSPetar Avramovic switch (MI.getOpcode()) { 741aa699b20SPetar Avramovic case TargetOpcode::G_LOAD: 742dbb6d01dSPetar Avramovic case TargetOpcode::G_STORE: 743be20e361SPetar Avramovic case TargetOpcode::G_PHI: 74475e43a60SPetar Avramovic case TargetOpcode::G_SELECT: 74575e43a60SPetar Avramovic case TargetOpcode::G_IMPLICIT_DEF: { 746ec575f6eSPetar Avramovic Helper.narrowScalar(MI, 0, LLT::scalar(32)); 747ec575f6eSPetar Avramovic // Handle new instructions. 748ec575f6eSPetar Avramovic while (!NewInstrs.empty()) { 749ec575f6eSPetar Avramovic MachineInstr *NewMI = NewInstrs.pop_back_val(); 750ec575f6eSPetar Avramovic // This is new G_UNMERGE that was created during narrowScalar and will 751ec575f6eSPetar Avramovic // not be considered for regbank selection. RegBankSelect for mips 752ec575f6eSPetar Avramovic // visits/makes corresponding G_MERGE first. Combine them here. 7535ec0f051SAmara Emerson if (auto *Unmerge = dyn_cast<GUnmerge>(NewMI)) 7545ec0f051SAmara Emerson combineAwayG_UNMERGE_VALUES(ArtCombiner, *Unmerge, NewInstrObserver); 755aa699b20SPetar Avramovic // This G_MERGE will be combined away when its corresponding G_UNMERGE 756aa699b20SPetar Avramovic // gets regBankSelected. 757aa699b20SPetar Avramovic else if (NewMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) 758aa699b20SPetar Avramovic continue; 759aa699b20SPetar Avramovic else 760f7c213c9SPetar Avramovic // Manually set register banks for def operands to 32 bit gprb. 761f7c213c9SPetar Avramovic setRegBank(*NewMI, MRI); 762ec575f6eSPetar Avramovic } 763ec575f6eSPetar Avramovic return; 764ec575f6eSPetar Avramovic } 765f7c213c9SPetar Avramovic case TargetOpcode::G_UNMERGE_VALUES: 7665ec0f051SAmara Emerson combineAwayG_UNMERGE_VALUES(ArtCombiner, cast<GUnmerge>(MI), 7675ec0f051SAmara Emerson NewInstrObserver); 768aa699b20SPetar Avramovic return; 769ec575f6eSPetar Avramovic default: 770ec575f6eSPetar Avramovic break; 771ec575f6eSPetar Avramovic } 772ec575f6eSPetar Avramovic 773ec575f6eSPetar Avramovic return applyDefaultMapping(OpdMapper); 774ec575f6eSPetar Avramovic } 775