1 //===- MipsRegisterBankInfo.cpp ---------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements the targeting of the RegisterBankInfo class for Mips. 10 /// \todo This should be generated by TableGen. 11 //===----------------------------------------------------------------------===// 12 13 #include "MipsInstrInfo.h" 14 #include "MipsRegisterBankInfo.h" 15 #include "llvm/CodeGen/MachineRegisterInfo.h" 16 17 #define GET_TARGET_REGBANK_IMPL 18 19 #define DEBUG_TYPE "registerbankinfo" 20 21 #include "MipsGenRegisterBank.inc" 22 23 namespace llvm { 24 namespace Mips { 25 enum PartialMappingIdx { 26 PMI_GPR, 27 PMI_SPR, 28 PMI_DPR, 29 PMI_Min = PMI_GPR, 30 }; 31 32 RegisterBankInfo::PartialMapping PartMappings[]{ 33 {0, 32, GPRBRegBank}, 34 {0, 32, FPRBRegBank}, 35 {0, 64, FPRBRegBank} 36 }; 37 38 enum ValueMappingIdx { 39 InvalidIdx = 0, 40 GPRIdx = 1, 41 SPRIdx = 4, 42 DPRIdx = 7 43 }; 44 45 RegisterBankInfo::ValueMapping ValueMappings[] = { 46 // invalid 47 {nullptr, 0}, 48 // up to 3 operands in GPRs 49 {&PartMappings[PMI_GPR - PMI_Min], 1}, 50 {&PartMappings[PMI_GPR - PMI_Min], 1}, 51 {&PartMappings[PMI_GPR - PMI_Min], 1}, 52 // up to 3 ops operands FPRs - single precission 53 {&PartMappings[PMI_SPR - PMI_Min], 1}, 54 {&PartMappings[PMI_SPR - PMI_Min], 1}, 55 {&PartMappings[PMI_SPR - PMI_Min], 1}, 56 // up to 3 ops operands FPRs - double precission 57 {&PartMappings[PMI_DPR - PMI_Min], 1}, 58 {&PartMappings[PMI_DPR - PMI_Min], 1}, 59 {&PartMappings[PMI_DPR - PMI_Min], 1} 60 }; 61 62 } // end namespace Mips 63 } // end namespace llvm 64 65 using namespace llvm; 66 67 MipsRegisterBankInfo::MipsRegisterBankInfo(const TargetRegisterInfo &TRI) 68 : MipsGenRegisterBankInfo() {} 69 70 const RegisterBank &MipsRegisterBankInfo::getRegBankFromRegClass( 71 const TargetRegisterClass &RC) const { 72 using namespace Mips; 73 74 switch (RC.getID()) { 75 case Mips::GPR32RegClassID: 76 case Mips::CPU16Regs_and_GPRMM16ZeroRegClassID: 77 case Mips::GPRMM16MovePPairFirstRegClassID: 78 case Mips::CPU16Regs_and_GPRMM16MovePPairSecondRegClassID: 79 case Mips::GPRMM16MoveP_and_CPU16Regs_and_GPRMM16ZeroRegClassID: 80 case Mips::GPRMM16MovePPairFirst_and_GPRMM16MovePPairSecondRegClassID: 81 case Mips::SP32RegClassID: 82 case Mips::GP32RegClassID: 83 return getRegBank(Mips::GPRBRegBankID); 84 case Mips::FGRCCRegClassID: 85 case Mips::FGR32RegClassID: 86 case Mips::FGR64RegClassID: 87 case Mips::AFGR64RegClassID: 88 return getRegBank(Mips::FPRBRegBankID); 89 default: 90 llvm_unreachable("Register class not supported"); 91 } 92 } 93 94 const RegisterBankInfo::InstructionMapping & 95 MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 96 97 unsigned Opc = MI.getOpcode(); 98 const MachineFunction &MF = *MI.getParent()->getParent(); 99 const MachineRegisterInfo &MRI = MF.getRegInfo(); 100 101 const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); 102 if (Mapping.isValid()) 103 return Mapping; 104 105 using namespace TargetOpcode; 106 107 unsigned NumOperands = MI.getNumOperands(); 108 const ValueMapping *OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 109 110 switch (Opc) { 111 case G_TRUNC: 112 case G_ADD: 113 case G_SUB: 114 case G_MUL: 115 case G_UMULH: 116 case G_LOAD: 117 case G_STORE: 118 case G_ZEXTLOAD: 119 case G_SEXTLOAD: 120 case G_GEP: 121 case G_AND: 122 case G_OR: 123 case G_XOR: 124 case G_SHL: 125 case G_ASHR: 126 case G_LSHR: 127 case G_SDIV: 128 case G_UDIV: 129 case G_SREM: 130 case G_UREM: 131 OperandsMapping = &Mips::ValueMappings[Mips::GPRIdx]; 132 break; 133 case G_FADD: 134 case G_FSUB: 135 case G_FMUL: 136 case G_FDIV: 137 case G_FABS: 138 case G_FSQRT:{ 139 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 140 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 141 OperandsMapping = Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 142 : &Mips::ValueMappings[Mips::DPRIdx]; 143 break; 144 } 145 case G_FCONSTANT: { 146 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 147 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 148 const RegisterBankInfo::ValueMapping *FPRValueMapping = 149 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 150 : &Mips::ValueMappings[Mips::DPRIdx]; 151 OperandsMapping = getOperandsMapping({FPRValueMapping, nullptr}); 152 break; 153 } 154 case G_FCMP: { 155 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 156 assert((Size == 32 || Size == 64) && "Unsupported floating point size"); 157 const RegisterBankInfo::ValueMapping *FPRValueMapping = 158 Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 159 : &Mips::ValueMappings[Mips::DPRIdx]; 160 OperandsMapping = 161 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 162 FPRValueMapping, FPRValueMapping}); 163 break; 164 } 165 case G_FPEXT: 166 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx], 167 &Mips::ValueMappings[Mips::SPRIdx]}); 168 break; 169 case G_FPTRUNC: 170 OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::SPRIdx], 171 &Mips::ValueMappings[Mips::DPRIdx]}); 172 break; 173 case G_FPTOSI: { 174 unsigned SizeInt = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 175 unsigned SizeFP = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 176 assert((SizeInt == 32) && "Unsupported integer size"); 177 assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size"); 178 OperandsMapping = getOperandsMapping({ 179 &Mips::ValueMappings[Mips::GPRIdx], 180 SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 181 : &Mips::ValueMappings[Mips::DPRIdx], 182 }); 183 break; 184 } 185 case G_SITOFP: { 186 unsigned SizeInt = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 187 unsigned SizeFP = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 188 assert((SizeInt == 32) && "Unsupported integer size"); 189 assert((SizeFP == 32 || SizeFP == 64) && "Unsupported floating point size"); 190 OperandsMapping = 191 getOperandsMapping({SizeFP == 32 ? &Mips::ValueMappings[Mips::SPRIdx] 192 : &Mips::ValueMappings[Mips::DPRIdx], 193 &Mips::ValueMappings[Mips::GPRIdx]}); 194 break; 195 } 196 case G_CONSTANT: 197 case G_FRAME_INDEX: 198 case G_GLOBAL_VALUE: 199 case G_BRCOND: 200 OperandsMapping = 201 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr}); 202 break; 203 case G_ICMP: 204 OperandsMapping = 205 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], nullptr, 206 &Mips::ValueMappings[Mips::GPRIdx], 207 &Mips::ValueMappings[Mips::GPRIdx]}); 208 break; 209 case G_SELECT: 210 OperandsMapping = 211 getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx], 212 &Mips::ValueMappings[Mips::GPRIdx], 213 &Mips::ValueMappings[Mips::GPRIdx], 214 &Mips::ValueMappings[Mips::GPRIdx]}); 215 break; 216 default: 217 return getInvalidInstructionMapping(); 218 } 219 220 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping, 221 NumOperands); 222 } 223