14be39288SPhilip Reames //===-- RISCVRegisterBankInfo.cpp -------------------------------*- C++ -*-===// 24be39288SPhilip Reames // 34be39288SPhilip Reames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 44be39288SPhilip Reames // See https://llvm.org/LICENSE.txt for license information. 54be39288SPhilip Reames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 64be39288SPhilip Reames // 74be39288SPhilip Reames //===----------------------------------------------------------------------===// 84be39288SPhilip Reames /// \file 929463612SCraig Topper /// This file implements the targeting of the RegisterBankInfo class for RISC-V. 104be39288SPhilip Reames /// \todo This should be generated by TableGen. 114be39288SPhilip Reames //===----------------------------------------------------------------------===// 124be39288SPhilip Reames 134be39288SPhilip Reames #include "RISCVRegisterBankInfo.h" 144be39288SPhilip Reames #include "MCTargetDesc/RISCVMCTargetDesc.h" 15d9320e22SCraig Topper #include "RISCVSubtarget.h" 16973e9dbdSMichael Maitland #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" 174be39288SPhilip Reames #include "llvm/CodeGen/MachineRegisterInfo.h" 184be39288SPhilip Reames #include "llvm/CodeGen/RegisterBank.h" 194be39288SPhilip Reames #include "llvm/CodeGen/RegisterBankInfo.h" 204be39288SPhilip Reames #include "llvm/CodeGen/TargetRegisterInfo.h" 214be39288SPhilip Reames 224be39288SPhilip Reames #define GET_TARGET_REGBANK_IMPL 234be39288SPhilip Reames #include "RISCVGenRegisterBank.inc" 244be39288SPhilip Reames 25d9320e22SCraig Topper namespace llvm { 26d9320e22SCraig Topper namespace RISCV { 27d9320e22SCraig Topper 28c4821073SCraig Topper const RegisterBankInfo::PartialMapping PartMappings[] = { 2910c2d5ffSJiahan Xie // clang-format off 308c53cfd3SCraig Topper {0, 32, GPRBRegBank}, 318c53cfd3SCraig Topper {0, 64, GPRBRegBank}, 32dddef9d1SCraig Topper {0, 16, FPRBRegBank}, 338c53cfd3SCraig Topper {0, 32, FPRBRegBank}, 348c53cfd3SCraig Topper {0, 64, FPRBRegBank}, 3510c2d5ffSJiahan Xie {0, 64, VRBRegBank}, 3610c2d5ffSJiahan Xie {0, 128, VRBRegBank}, 3710c2d5ffSJiahan Xie {0, 256, VRBRegBank}, 3810c2d5ffSJiahan Xie {0, 512, VRBRegBank}, 3910c2d5ffSJiahan Xie // clang-format on 40d9320e22SCraig Topper }; 41d9320e22SCraig Topper 42d9320e22SCraig Topper enum PartialMappingIdx { 433e606934SCraig Topper PMI_GPRB32 = 0, 443e606934SCraig Topper PMI_GPRB64 = 1, 45dddef9d1SCraig Topper PMI_FPRB16 = 2, 46dddef9d1SCraig Topper PMI_FPRB32 = 3, 47dddef9d1SCraig Topper PMI_FPRB64 = 4, 48dddef9d1SCraig Topper PMI_VRB64 = 5, 49dddef9d1SCraig Topper PMI_VRB128 = 6, 50dddef9d1SCraig Topper PMI_VRB256 = 7, 51dddef9d1SCraig Topper PMI_VRB512 = 8, 52d9320e22SCraig Topper }; 53d9320e22SCraig Topper 54c4821073SCraig Topper const RegisterBankInfo::ValueMapping ValueMappings[] = { 55d9320e22SCraig Topper // Invalid value mapping. 56d9320e22SCraig Topper {nullptr, 0}, 57d9320e22SCraig Topper // Maximum 3 GPR operands; 32 bit. 583e606934SCraig Topper {&PartMappings[PMI_GPRB32], 1}, 593e606934SCraig Topper {&PartMappings[PMI_GPRB32], 1}, 603e606934SCraig Topper {&PartMappings[PMI_GPRB32], 1}, 61d9320e22SCraig Topper // Maximum 3 GPR operands; 64 bit. 623e606934SCraig Topper {&PartMappings[PMI_GPRB64], 1}, 633e606934SCraig Topper {&PartMappings[PMI_GPRB64], 1}, 643e606934SCraig Topper {&PartMappings[PMI_GPRB64], 1}, 65dddef9d1SCraig Topper // Maximum 3 FPR operands; 16 bit. 66dddef9d1SCraig Topper {&PartMappings[PMI_FPRB16], 1}, 67dddef9d1SCraig Topper {&PartMappings[PMI_FPRB16], 1}, 68dddef9d1SCraig Topper {&PartMappings[PMI_FPRB16], 1}, 69c2b64dfaSCraig Topper // Maximum 3 FPR operands; 32 bit. 703e606934SCraig Topper {&PartMappings[PMI_FPRB32], 1}, 713e606934SCraig Topper {&PartMappings[PMI_FPRB32], 1}, 723e606934SCraig Topper {&PartMappings[PMI_FPRB32], 1}, 73c2b64dfaSCraig Topper // Maximum 3 FPR operands; 64 bit. 743e606934SCraig Topper {&PartMappings[PMI_FPRB64], 1}, 753e606934SCraig Topper {&PartMappings[PMI_FPRB64], 1}, 763e606934SCraig Topper {&PartMappings[PMI_FPRB64], 1}, 7710c2d5ffSJiahan Xie // Maximum 3 VR LMUL={1, MF2, MF4, MF8} operands. 7810c2d5ffSJiahan Xie {&PartMappings[PMI_VRB64], 1}, 7910c2d5ffSJiahan Xie {&PartMappings[PMI_VRB64], 1}, 8010c2d5ffSJiahan Xie {&PartMappings[PMI_VRB64], 1}, 8110c2d5ffSJiahan Xie // Maximum 3 VR LMUL=2 operands. 8210c2d5ffSJiahan Xie {&PartMappings[PMI_VRB128], 1}, 8310c2d5ffSJiahan Xie {&PartMappings[PMI_VRB128], 1}, 8410c2d5ffSJiahan Xie {&PartMappings[PMI_VRB128], 1}, 8510c2d5ffSJiahan Xie // Maximum 3 VR LMUL=4 operands. 8610c2d5ffSJiahan Xie {&PartMappings[PMI_VRB256], 1}, 8710c2d5ffSJiahan Xie {&PartMappings[PMI_VRB256], 1}, 8810c2d5ffSJiahan Xie {&PartMappings[PMI_VRB256], 1}, 8910c2d5ffSJiahan Xie // Maximum 3 VR LMUL=8 operands. 9010c2d5ffSJiahan Xie {&PartMappings[PMI_VRB512], 1}, 9110c2d5ffSJiahan Xie {&PartMappings[PMI_VRB512], 1}, 9210c2d5ffSJiahan Xie {&PartMappings[PMI_VRB512], 1}, 93d9320e22SCraig Topper }; 94d9320e22SCraig Topper 951ffcac1bSCraig Topper enum ValueMappingIdx { 96d9320e22SCraig Topper InvalidIdx = 0, 973e606934SCraig Topper GPRB32Idx = 1, 983e606934SCraig Topper GPRB64Idx = 4, 99dddef9d1SCraig Topper FPRB16Idx = 7, 100dddef9d1SCraig Topper FPRB32Idx = 10, 101dddef9d1SCraig Topper FPRB64Idx = 13, 102dddef9d1SCraig Topper VRB64Idx = 16, 103dddef9d1SCraig Topper VRB128Idx = 19, 104dddef9d1SCraig Topper VRB256Idx = 22, 105dddef9d1SCraig Topper VRB512Idx = 25, 106d9320e22SCraig Topper }; 107d9320e22SCraig Topper } // namespace RISCV 108d9320e22SCraig Topper } // namespace llvm 109d9320e22SCraig Topper 1104be39288SPhilip Reames using namespace llvm; 1114be39288SPhilip Reames 112aa7eace8SNitin John Raj RISCVRegisterBankInfo::RISCVRegisterBankInfo(unsigned HwMode) 113aa7eace8SNitin John Raj : RISCVGenRegisterBankInfo(HwMode) {} 114d9320e22SCraig Topper 1157ccdad14SCraig Topper static const RegisterBankInfo::ValueMapping *getFPValueMapping(unsigned Size) { 116dddef9d1SCraig Topper unsigned Idx; 117dddef9d1SCraig Topper switch (Size) { 118dddef9d1SCraig Topper default: 119dddef9d1SCraig Topper llvm_unreachable("Unexpected size"); 120dddef9d1SCraig Topper case 16: 121dddef9d1SCraig Topper Idx = RISCV::FPRB16Idx; 122dddef9d1SCraig Topper break; 123dddef9d1SCraig Topper case 32: 124dddef9d1SCraig Topper Idx = RISCV::FPRB32Idx; 125dddef9d1SCraig Topper break; 126dddef9d1SCraig Topper case 64: 127dddef9d1SCraig Topper Idx = RISCV::FPRB64Idx; 128dddef9d1SCraig Topper break; 129dddef9d1SCraig Topper } 1307ccdad14SCraig Topper return &RISCV::ValueMappings[Idx]; 1317ccdad14SCraig Topper } 1327ccdad14SCraig Topper 13305300222SCraig Topper // TODO: Make this more like AArch64? 1349e88a207SCraig Topper bool RISCVRegisterBankInfo::hasFPConstraints( 1359e88a207SCraig Topper const MachineInstr &MI, const MachineRegisterInfo &MRI, 1369e88a207SCraig Topper const TargetRegisterInfo &TRI) const { 1379e88a207SCraig Topper if (isPreISelGenericFloatingPointOpcode(MI.getOpcode())) 1389e88a207SCraig Topper return true; 1399e88a207SCraig Topper 1409e88a207SCraig Topper // If we have a copy instruction, we could be feeding floating point 1419e88a207SCraig Topper // instructions. 1429e88a207SCraig Topper if (MI.getOpcode() != TargetOpcode::COPY) 1439e88a207SCraig Topper return false; 1449e88a207SCraig Topper 1459e88a207SCraig Topper return getRegBank(MI.getOperand(0).getReg(), MRI, TRI) == &RISCV::FPRBRegBank; 1469e88a207SCraig Topper } 1479e88a207SCraig Topper 148c44ac52eSCraig Topper bool RISCVRegisterBankInfo::onlyUsesFP(const MachineInstr &MI, 149c44ac52eSCraig Topper const MachineRegisterInfo &MRI, 150c44ac52eSCraig Topper const TargetRegisterInfo &TRI) const { 15105300222SCraig Topper switch (MI.getOpcode()) { 152d3177d8bSCraig Topper case RISCV::G_FCVT_W_RV64: 153d3177d8bSCraig Topper case RISCV::G_FCVT_WU_RV64: 154*de6d0d2dSLuke Quinn case RISCV::G_FCLASS: 15505300222SCraig Topper case TargetOpcode::G_FPTOSI: 15605300222SCraig Topper case TargetOpcode::G_FPTOUI: 1579e88a207SCraig Topper case TargetOpcode::G_FCMP: 15805300222SCraig Topper return true; 15905300222SCraig Topper default: 16005300222SCraig Topper break; 16105300222SCraig Topper } 16205300222SCraig Topper 1639e88a207SCraig Topper return hasFPConstraints(MI, MRI, TRI); 16405300222SCraig Topper } 16505300222SCraig Topper 166c44ac52eSCraig Topper bool RISCVRegisterBankInfo::onlyDefinesFP(const MachineInstr &MI, 167c44ac52eSCraig Topper const MachineRegisterInfo &MRI, 168c44ac52eSCraig Topper const TargetRegisterInfo &TRI) const { 16905300222SCraig Topper switch (MI.getOpcode()) { 17005300222SCraig Topper case TargetOpcode::G_SITOFP: 17105300222SCraig Topper case TargetOpcode::G_UITOFP: 17205300222SCraig Topper return true; 17305300222SCraig Topper default: 17405300222SCraig Topper break; 17505300222SCraig Topper } 17605300222SCraig Topper 1779e88a207SCraig Topper return hasFPConstraints(MI, MRI, TRI); 17805300222SCraig Topper } 17905300222SCraig Topper 1806976dac0SMichael Maitland bool RISCVRegisterBankInfo::anyUseOnlyUseFP( 1816976dac0SMichael Maitland Register Def, const MachineRegisterInfo &MRI, 1826976dac0SMichael Maitland const TargetRegisterInfo &TRI) const { 1836976dac0SMichael Maitland return any_of( 1846976dac0SMichael Maitland MRI.use_nodbg_instructions(Def), 1856976dac0SMichael Maitland [&](const MachineInstr &UseMI) { return onlyUsesFP(UseMI, MRI, TRI); }); 1866976dac0SMichael Maitland } 1876976dac0SMichael Maitland 18810c2d5ffSJiahan Xie static const RegisterBankInfo::ValueMapping *getVRBValueMapping(unsigned Size) { 18910c2d5ffSJiahan Xie unsigned Idx; 19010c2d5ffSJiahan Xie 19110c2d5ffSJiahan Xie if (Size <= 64) 19210c2d5ffSJiahan Xie Idx = RISCV::VRB64Idx; 19310c2d5ffSJiahan Xie else if (Size == 128) 19410c2d5ffSJiahan Xie Idx = RISCV::VRB128Idx; 19510c2d5ffSJiahan Xie else if (Size == 256) 19610c2d5ffSJiahan Xie Idx = RISCV::VRB256Idx; 19710c2d5ffSJiahan Xie else if (Size == 512) 19810c2d5ffSJiahan Xie Idx = RISCV::VRB512Idx; 19910c2d5ffSJiahan Xie else 20010c2d5ffSJiahan Xie llvm::report_fatal_error("Invalid Size"); 20110c2d5ffSJiahan Xie 20210c2d5ffSJiahan Xie return &RISCV::ValueMappings[Idx]; 20310c2d5ffSJiahan Xie } 20410c2d5ffSJiahan Xie 205d9320e22SCraig Topper const RegisterBankInfo::InstructionMapping & 206d9320e22SCraig Topper RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 207d9320e22SCraig Topper const unsigned Opc = MI.getOpcode(); 208d9320e22SCraig Topper 209d9320e22SCraig Topper // Try the default logic for non-generic instructions that are either copies 210d9320e22SCraig Topper // or already have some operands assigned to banks. 211d9320e22SCraig Topper if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) { 212d9320e22SCraig Topper const InstructionMapping &Mapping = getInstrMappingImpl(MI); 213d9320e22SCraig Topper if (Mapping.isValid()) 214d9320e22SCraig Topper return Mapping; 215d9320e22SCraig Topper } 216d9320e22SCraig Topper 217c2b64dfaSCraig Topper const MachineFunction &MF = *MI.getParent()->getParent(); 218c2b64dfaSCraig Topper const MachineRegisterInfo &MRI = MF.getRegInfo(); 219c44ac52eSCraig Topper const TargetSubtargetInfo &STI = MF.getSubtarget(); 220c44ac52eSCraig Topper const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); 221c2b64dfaSCraig Topper 2228c53cfd3SCraig Topper unsigned GPRSize = getMaximumSize(RISCV::GPRBRegBankID); 223d9320e22SCraig Topper assert((GPRSize == 32 || GPRSize == 64) && "Unexpected GPR size"); 224d9320e22SCraig Topper 225d9320e22SCraig Topper unsigned NumOperands = MI.getNumOperands(); 226d9320e22SCraig Topper const ValueMapping *GPRValueMapping = 2273e606934SCraig Topper &RISCV::ValueMappings[GPRSize == 64 ? RISCV::GPRB64Idx 2283e606934SCraig Topper : RISCV::GPRB32Idx]; 229d9320e22SCraig Topper 230d9320e22SCraig Topper switch (Opc) { 231d9320e22SCraig Topper case TargetOpcode::G_ADD: 232852eb20bSCraig Topper case TargetOpcode::G_SUB: 233d9320e22SCraig Topper case TargetOpcode::G_SHL: 234d9320e22SCraig Topper case TargetOpcode::G_ASHR: 235d9320e22SCraig Topper case TargetOpcode::G_LSHR: 236d9320e22SCraig Topper case TargetOpcode::G_AND: 237d9320e22SCraig Topper case TargetOpcode::G_OR: 238d9320e22SCraig Topper case TargetOpcode::G_XOR: 239d9320e22SCraig Topper case TargetOpcode::G_MUL: 240d9320e22SCraig Topper case TargetOpcode::G_SDIV: 241d9320e22SCraig Topper case TargetOpcode::G_SREM: 242de17384cSMin-Yih Hsu case TargetOpcode::G_SMULH: 243028ed612SCraig Topper case TargetOpcode::G_SMAX: 244028ed612SCraig Topper case TargetOpcode::G_SMIN: 245d9320e22SCraig Topper case TargetOpcode::G_UDIV: 246d9320e22SCraig Topper case TargetOpcode::G_UREM: 247d9320e22SCraig Topper case TargetOpcode::G_UMULH: 248028ed612SCraig Topper case TargetOpcode::G_UMAX: 249028ed612SCraig Topper case TargetOpcode::G_UMIN: 250d9320e22SCraig Topper case TargetOpcode::G_PTR_ADD: 251cfdafc1eSCraig Topper case TargetOpcode::G_PTRTOINT: 252cfdafc1eSCraig Topper case TargetOpcode::G_INTTOPTR: 2530b8379bfSCraig Topper case TargetOpcode::G_FADD: 2540b8379bfSCraig Topper case TargetOpcode::G_FSUB: 2550b8379bfSCraig Topper case TargetOpcode::G_FMUL: 2560b8379bfSCraig Topper case TargetOpcode::G_FDIV: 2570b8379bfSCraig Topper case TargetOpcode::G_FABS: 2580b8379bfSCraig Topper case TargetOpcode::G_FNEG: 2590b8379bfSCraig Topper case TargetOpcode::G_FSQRT: 2600b8379bfSCraig Topper case TargetOpcode::G_FMAXNUM: 261f2f18459SNikita Popov case TargetOpcode::G_FMINNUM: { 2620b8379bfSCraig Topper LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 263852eb20bSCraig Topper TypeSize Size = Ty.getSizeInBits(); 264852eb20bSCraig Topper 265852eb20bSCraig Topper const ValueMapping *Mapping; 266852eb20bSCraig Topper if (Ty.isVector()) 267852eb20bSCraig Topper Mapping = getVRBValueMapping(Size.getKnownMinValue()); 268852eb20bSCraig Topper else if (isPreISelGenericFloatingPointOpcode(Opc)) 269852eb20bSCraig Topper Mapping = getFPValueMapping(Size.getFixedValue()); 270852eb20bSCraig Topper else 271852eb20bSCraig Topper Mapping = GPRValueMapping; 272852eb20bSCraig Topper 273852eb20bSCraig Topper #ifndef NDEBUG 274852eb20bSCraig Topper // Make sure all the operands are using similar size and type. 275852eb20bSCraig Topper for (unsigned Idx = 1; Idx != NumOperands; ++Idx) { 276852eb20bSCraig Topper LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg()); 277852eb20bSCraig Topper assert(Ty.isVector() == OpTy.isVector() && 278852eb20bSCraig Topper "Operand has incompatible type"); 279852eb20bSCraig Topper // Don't check size for GPR. 280852eb20bSCraig Topper if (OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc)) 281852eb20bSCraig Topper assert(Size == OpTy.getSizeInBits() && "Operand has incompatible size"); 2820b8379bfSCraig Topper } 283852eb20bSCraig Topper #endif // End NDEBUG 284852eb20bSCraig Topper 285852eb20bSCraig Topper return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands); 286852eb20bSCraig Topper } 287852eb20bSCraig Topper case TargetOpcode::G_SEXTLOAD: 288852eb20bSCraig Topper case TargetOpcode::G_ZEXTLOAD: 289852eb20bSCraig Topper return getInstructionMapping(DefaultMappingID, /*Cost=*/1, GPRValueMapping, 290852eb20bSCraig Topper NumOperands); 2916976dac0SMichael Maitland case TargetOpcode::G_IMPLICIT_DEF: { 2926976dac0SMichael Maitland Register Dst = MI.getOperand(0).getReg(); 293ea798a79SMichael Maitland LLT DstTy = MRI.getType(Dst); 294a853d799SCraig Topper unsigned DstMinSize = DstTy.getSizeInBits().getKnownMinValue(); 2956976dac0SMichael Maitland auto Mapping = GPRValueMapping; 2966976dac0SMichael Maitland // FIXME: May need to do a better job determining when to use FPRB. 2976976dac0SMichael Maitland // For example, the look through COPY case: 2986976dac0SMichael Maitland // %0:_(s32) = G_IMPLICIT_DEF 2996976dac0SMichael Maitland // %1:_(s32) = COPY %0 3006976dac0SMichael Maitland // $f10_d = COPY %1(s32) 301ea798a79SMichael Maitland if (DstTy.isVector()) 302ea798a79SMichael Maitland Mapping = getVRBValueMapping(DstMinSize); 303a853d799SCraig Topper else if (anyUseOnlyUseFP(Dst, MRI, TRI)) 304a853d799SCraig Topper Mapping = getFPValueMapping(DstMinSize); 305ea798a79SMichael Maitland 3066976dac0SMichael Maitland return getInstructionMapping(DefaultMappingID, /*Cost=*/1, Mapping, 3076976dac0SMichael Maitland NumOperands); 3086976dac0SMichael Maitland } 3090b8379bfSCraig Topper } 3100b8379bfSCraig Topper 3110b8379bfSCraig Topper SmallVector<const ValueMapping *, 4> OpdsMapping(NumOperands); 3120b8379bfSCraig Topper 3130b8379bfSCraig Topper switch (Opc) { 31405300222SCraig Topper case TargetOpcode::G_LOAD: { 31505300222SCraig Topper LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 3161c66ef91SJiahan Xie TypeSize Size = Ty.getSizeInBits(); 3171c66ef91SJiahan Xie 3180b8379bfSCraig Topper OpdsMapping[1] = GPRValueMapping; 3191c66ef91SJiahan Xie 320a1ba4fb4SCraig Topper if (Ty.isVector()) { 321a1ba4fb4SCraig Topper OpdsMapping[0] = getVRBValueMapping(Size.getKnownMinValue()); 3221c66ef91SJiahan Xie break; 323a1ba4fb4SCraig Topper } 324a1ba4fb4SCraig Topper 325a1ba4fb4SCraig Topper OpdsMapping[0] = GPRValueMapping; 326a1ba4fb4SCraig Topper 32705300222SCraig Topper // Use FPR64 for s64 loads on rv32. 3281c66ef91SJiahan Xie if (GPRSize == 32 && Size.getFixedValue() == 64) { 32905300222SCraig Topper assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD()); 330*de6d0d2dSLuke Quinn OpdsMapping[0] = getFPValueMapping(Size); 33105300222SCraig Topper break; 33205300222SCraig Topper } 33305300222SCraig Topper 33405300222SCraig Topper // Check if that load feeds fp instructions. 33505300222SCraig Topper // In that case, we want the default mapping to be on FPR 33605300222SCraig Topper // instead of blind map every scalar to GPR. 337*de6d0d2dSLuke Quinn if (anyUseOnlyUseFP(MI.getOperand(0).getReg(), MRI, TRI)) { 33805300222SCraig Topper // If we have at least one direct use in a FP instruction, 33905300222SCraig Topper // assume this was a floating point load in the IR. If it was 34005300222SCraig Topper // not, we would have had a bitcast before reaching that 34105300222SCraig Topper // instruction. 342*de6d0d2dSLuke Quinn OpdsMapping[0] = getFPValueMapping(Size); 343*de6d0d2dSLuke Quinn break; 344*de6d0d2dSLuke Quinn } 34505300222SCraig Topper 34605300222SCraig Topper break; 34705300222SCraig Topper } 34805300222SCraig Topper case TargetOpcode::G_STORE: { 34905300222SCraig Topper LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 3501c66ef91SJiahan Xie TypeSize Size = Ty.getSizeInBits(); 3511c66ef91SJiahan Xie 3520b8379bfSCraig Topper OpdsMapping[1] = GPRValueMapping; 3531c66ef91SJiahan Xie 354a1ba4fb4SCraig Topper if (Ty.isVector()) { 355a1ba4fb4SCraig Topper OpdsMapping[0] = getVRBValueMapping(Size.getKnownMinValue()); 3561c66ef91SJiahan Xie break; 357a1ba4fb4SCraig Topper } 358a1ba4fb4SCraig Topper 359a1ba4fb4SCraig Topper OpdsMapping[0] = GPRValueMapping; 3601c66ef91SJiahan Xie 36105300222SCraig Topper // Use FPR64 for s64 stores on rv32. 3621c66ef91SJiahan Xie if (GPRSize == 32 && Size.getFixedValue() == 64) { 36305300222SCraig Topper assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD()); 3640b8379bfSCraig Topper OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); 36505300222SCraig Topper break; 36605300222SCraig Topper } 36705300222SCraig Topper 36805300222SCraig Topper MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(0).getReg()); 3690b8379bfSCraig Topper if (onlyDefinesFP(*DefMI, MRI, TRI)) 3700b8379bfSCraig Topper OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); 37105300222SCraig Topper break; 37205300222SCraig Topper } 3735f31dbd1SCraig Topper case TargetOpcode::G_SELECT: { 3745f31dbd1SCraig Topper LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 3755f31dbd1SCraig Topper 376973e9dbdSMichael Maitland if (Ty.isVector()) { 377973e9dbdSMichael Maitland auto &Sel = cast<GSelect>(MI); 378973e9dbdSMichael Maitland LLT TestTy = MRI.getType(Sel.getCondReg()); 379973e9dbdSMichael Maitland assert(TestTy.isVector() && "Unexpected condition argument type"); 380973e9dbdSMichael Maitland OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = 381973e9dbdSMichael Maitland getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue()); 382973e9dbdSMichael Maitland OpdsMapping[1] = 383973e9dbdSMichael Maitland getVRBValueMapping(TestTy.getSizeInBits().getKnownMinValue()); 384973e9dbdSMichael Maitland break; 385973e9dbdSMichael Maitland } 386973e9dbdSMichael Maitland 3875f31dbd1SCraig Topper // Try to minimize the number of copies. If we have more floating point 3885f31dbd1SCraig Topper // constrained values than not, then we'll put everything on FPR. Otherwise, 3895f31dbd1SCraig Topper // everything has to be on GPR. 3905f31dbd1SCraig Topper unsigned NumFP = 0; 3915f31dbd1SCraig Topper 392d345cfb5SCraig Topper // Use FPR64 for s64 select on rv32. 393d345cfb5SCraig Topper if (GPRSize == 32 && Ty.getSizeInBits() == 64) { 394d345cfb5SCraig Topper NumFP = 3; 395d345cfb5SCraig Topper } else { 3965f31dbd1SCraig Topper // Check if the uses of the result always produce floating point values. 3975f31dbd1SCraig Topper // 3985f31dbd1SCraig Topper // For example: 3995f31dbd1SCraig Topper // 4005f31dbd1SCraig Topper // %z = G_SELECT %cond %x %y 4015f31dbd1SCraig Topper // fpr = G_FOO %z ... 4025f31dbd1SCraig Topper if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()), 4035f31dbd1SCraig Topper [&](const MachineInstr &UseMI) { 4045f31dbd1SCraig Topper return onlyUsesFP(UseMI, MRI, TRI); 4055f31dbd1SCraig Topper })) 4065f31dbd1SCraig Topper ++NumFP; 4075f31dbd1SCraig Topper 4085f31dbd1SCraig Topper // Check if the defs of the source values always produce floating point 4095f31dbd1SCraig Topper // values. 4105f31dbd1SCraig Topper // 4115f31dbd1SCraig Topper // For example: 4125f31dbd1SCraig Topper // 4135f31dbd1SCraig Topper // %x = G_SOMETHING_ALWAYS_FLOAT %a ... 4145f31dbd1SCraig Topper // %z = G_SELECT %cond %x %y 4155f31dbd1SCraig Topper // 4165f31dbd1SCraig Topper // Also check whether or not the sources have already been decided to be 4175f31dbd1SCraig Topper // FPR. Keep track of this. 4185f31dbd1SCraig Topper // 4195f31dbd1SCraig Topper // This doesn't check the condition, since the condition is always an 4205f31dbd1SCraig Topper // integer. 4215f31dbd1SCraig Topper for (unsigned Idx = 2; Idx < 4; ++Idx) { 4225f31dbd1SCraig Topper Register VReg = MI.getOperand(Idx).getReg(); 4235f31dbd1SCraig Topper MachineInstr *DefMI = MRI.getVRegDef(VReg); 4245f31dbd1SCraig Topper if (getRegBank(VReg, MRI, TRI) == &RISCV::FPRBRegBank || 4255f31dbd1SCraig Topper onlyDefinesFP(*DefMI, MRI, TRI)) 4265f31dbd1SCraig Topper ++NumFP; 4275f31dbd1SCraig Topper } 428d345cfb5SCraig Topper } 4295f31dbd1SCraig Topper 4305f31dbd1SCraig Topper // Condition operand is always GPR. 4310b8379bfSCraig Topper OpdsMapping[1] = GPRValueMapping; 4325f31dbd1SCraig Topper 4335f31dbd1SCraig Topper const ValueMapping *Mapping = GPRValueMapping; 4345f31dbd1SCraig Topper if (NumFP >= 2) 4355f31dbd1SCraig Topper Mapping = getFPValueMapping(Ty.getSizeInBits()); 4365f31dbd1SCraig Topper 4375f31dbd1SCraig Topper OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping; 438d9320e22SCraig Topper break; 4395f31dbd1SCraig Topper } 440d3177d8bSCraig Topper case RISCV::G_FCVT_W_RV64: 441d3177d8bSCraig Topper case RISCV::G_FCVT_WU_RV64: 442374fb412SCraig Topper case TargetOpcode::G_FPTOSI: 4437c3c8a12SMin-Yih Hsu case TargetOpcode::G_FPTOUI: 4447c3c8a12SMin-Yih Hsu case RISCV::G_FCLASS: { 445374fb412SCraig Topper LLT Ty = MRI.getType(MI.getOperand(1).getReg()); 4460b8379bfSCraig Topper OpdsMapping[0] = GPRValueMapping; 4470b8379bfSCraig Topper OpdsMapping[1] = getFPValueMapping(Ty.getSizeInBits()); 448374fb412SCraig Topper break; 449374fb412SCraig Topper } 450a6c80c4fSCraig Topper case TargetOpcode::G_SITOFP: 451a6c80c4fSCraig Topper case TargetOpcode::G_UITOFP: { 452a6c80c4fSCraig Topper LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 4530b8379bfSCraig Topper OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); 4540b8379bfSCraig Topper OpdsMapping[1] = GPRValueMapping; 455a6c80c4fSCraig Topper break; 456a6c80c4fSCraig Topper } 457fdbff881SCraig Topper case TargetOpcode::G_FCMP: { 458fdbff881SCraig Topper LLT Ty = MRI.getType(MI.getOperand(2).getReg()); 459fdbff881SCraig Topper 460fdbff881SCraig Topper unsigned Size = Ty.getSizeInBits(); 461fdbff881SCraig Topper 4620b8379bfSCraig Topper OpdsMapping[0] = GPRValueMapping; 4630b8379bfSCraig Topper OpdsMapping[2] = OpdsMapping[3] = getFPValueMapping(Size); 464fdbff881SCraig Topper break; 465fdbff881SCraig Topper } 466dbb9043dSMichael Maitland case TargetOpcode::G_MERGE_VALUES: { 467dbb9043dSMichael Maitland // Use FPR64 for s64 merge on rv32. 468dbb9043dSMichael Maitland LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 469dbb9043dSMichael Maitland if (GPRSize == 32 && Ty.getSizeInBits() == 64) { 470dbb9043dSMichael Maitland assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD()); 471dbb9043dSMichael Maitland OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits()); 472dbb9043dSMichael Maitland OpdsMapping[1] = GPRValueMapping; 473dbb9043dSMichael Maitland OpdsMapping[2] = GPRValueMapping; 474dbb9043dSMichael Maitland } 475dbb9043dSMichael Maitland break; 476dbb9043dSMichael Maitland } 477dbb9043dSMichael Maitland case TargetOpcode::G_UNMERGE_VALUES: { 478dbb9043dSMichael Maitland // Use FPR64 for s64 unmerge on rv32. 479dbb9043dSMichael Maitland LLT Ty = MRI.getType(MI.getOperand(2).getReg()); 480dbb9043dSMichael Maitland if (GPRSize == 32 && Ty.getSizeInBits() == 64) { 481dbb9043dSMichael Maitland assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD()); 482dbb9043dSMichael Maitland OpdsMapping[0] = GPRValueMapping; 483dbb9043dSMichael Maitland OpdsMapping[1] = GPRValueMapping; 484dbb9043dSMichael Maitland OpdsMapping[2] = getFPValueMapping(Ty.getSizeInBits()); 485dbb9043dSMichael Maitland } 486dbb9043dSMichael Maitland break; 487dbb9043dSMichael Maitland } 488ca5b81bdSMichael Maitland case TargetOpcode::G_SPLAT_VECTOR: { 489ca5b81bdSMichael Maitland OpdsMapping[0] = getVRBValueMapping(MRI.getType(MI.getOperand(0).getReg()) 490ca5b81bdSMichael Maitland .getSizeInBits() 491ca5b81bdSMichael Maitland .getKnownMinValue()); 492ca5b81bdSMichael Maitland 493ca5b81bdSMichael Maitland LLT ScalarTy = MRI.getType(MI.getOperand(1).getReg()); 494ca5b81bdSMichael Maitland MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(1).getReg()); 495ca5b81bdSMichael Maitland if ((GPRSize == 32 && ScalarTy.getSizeInBits() == 64) || 496ca5b81bdSMichael Maitland onlyDefinesFP(*DefMI, MRI, TRI)) { 497ca5b81bdSMichael Maitland assert(MF.getSubtarget<RISCVSubtarget>().hasStdExtD()); 498ca5b81bdSMichael Maitland OpdsMapping[1] = getFPValueMapping(ScalarTy.getSizeInBits()); 499ca5b81bdSMichael Maitland } else 500ca5b81bdSMichael Maitland OpdsMapping[1] = GPRValueMapping; 501ca5b81bdSMichael Maitland break; 502ca5b81bdSMichael Maitland } 503d9320e22SCraig Topper default: 5048630cf21SCraig Topper // By default map all scalars to GPR. 5058630cf21SCraig Topper for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { 5068630cf21SCraig Topper auto &MO = MI.getOperand(Idx); 507181e8065SCraig Topper if (!MO.isReg() || !MO.getReg()) 5088630cf21SCraig Topper continue; 509181e8065SCraig Topper LLT Ty = MRI.getType(MO.getReg()); 510181e8065SCraig Topper if (!Ty.isValid()) 511181e8065SCraig Topper continue; 512181e8065SCraig Topper 51305f673bcSMichael Maitland if (Ty.isVector()) 51405f673bcSMichael Maitland OpdsMapping[Idx] = 51505f673bcSMichael Maitland getVRBValueMapping(Ty.getSizeInBits().getKnownMinValue()); 51605f673bcSMichael Maitland else if (isPreISelGenericFloatingPointOpcode(Opc)) 517181e8065SCraig Topper OpdsMapping[Idx] = getFPValueMapping(Ty.getSizeInBits()); 518181e8065SCraig Topper else 5198630cf21SCraig Topper OpdsMapping[Idx] = GPRValueMapping; 5208630cf21SCraig Topper } 5218630cf21SCraig Topper break; 522d9320e22SCraig Topper } 523d9320e22SCraig Topper 5240b8379bfSCraig Topper return getInstructionMapping(DefaultMappingID, /*Cost=*/1, 5250b8379bfSCraig Topper getOperandsMapping(OpdsMapping), NumOperands); 526d9320e22SCraig Topper } 527