1 //===- ARMRegisterBankInfo.cpp -----------------------------------*- C++ -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// This file implements the targeting of the RegisterBankInfo class for ARM. 11 /// \todo This should be generated by TableGen. 12 //===----------------------------------------------------------------------===// 13 14 #include "ARMRegisterBankInfo.h" 15 #include "ARMInstrInfo.h" // For the register classes 16 #include "ARMSubtarget.h" 17 #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 18 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 #include "llvm/CodeGen/TargetRegisterInfo.h" 21 22 #define GET_TARGET_REGBANK_IMPL 23 #include "ARMGenRegisterBank.inc" 24 25 using namespace llvm; 26 27 // FIXME: TableGen this. 28 // If it grows too much and TableGen still isn't ready to do the job, extract it 29 // into an ARMGenRegisterBankInfo.def (similar to AArch64). 30 namespace llvm { 31 namespace ARM { 32 enum PartialMappingIdx { 33 PMI_GPR, 34 PMI_SPR, 35 PMI_DPR, 36 PMI_Min = PMI_GPR, 37 }; 38 39 RegisterBankInfo::PartialMapping PartMappings[]{ 40 // GPR Partial Mapping 41 {0, 32, GPRRegBank}, 42 // SPR Partial Mapping 43 {0, 32, FPRRegBank}, 44 // DPR Partial Mapping 45 {0, 64, FPRRegBank}, 46 }; 47 48 #ifndef NDEBUG 49 static bool checkPartMapping(const RegisterBankInfo::PartialMapping &PM, 50 unsigned Start, unsigned Length, 51 unsigned RegBankID) { 52 return PM.StartIdx == Start && PM.Length == Length && 53 PM.RegBank->getID() == RegBankID; 54 } 55 56 static void checkPartialMappings() { 57 assert( 58 checkPartMapping(PartMappings[PMI_GPR - PMI_Min], 0, 32, GPRRegBankID) && 59 "Wrong mapping for GPR"); 60 assert( 61 checkPartMapping(PartMappings[PMI_SPR - PMI_Min], 0, 32, FPRRegBankID) && 62 "Wrong mapping for SPR"); 63 assert( 64 checkPartMapping(PartMappings[PMI_DPR - PMI_Min], 0, 64, FPRRegBankID) && 65 "Wrong mapping for DPR"); 66 } 67 #endif 68 69 enum ValueMappingIdx { 70 InvalidIdx = 0, 71 GPR3OpsIdx = 1, 72 SPR3OpsIdx = 4, 73 DPR3OpsIdx = 7, 74 }; 75 76 RegisterBankInfo::ValueMapping ValueMappings[] = { 77 // invalid 78 {nullptr, 0}, 79 // 3 ops in GPRs 80 {&PartMappings[PMI_GPR - PMI_Min], 1}, 81 {&PartMappings[PMI_GPR - PMI_Min], 1}, 82 {&PartMappings[PMI_GPR - PMI_Min], 1}, 83 // 3 ops in SPRs 84 {&PartMappings[PMI_SPR - PMI_Min], 1}, 85 {&PartMappings[PMI_SPR - PMI_Min], 1}, 86 {&PartMappings[PMI_SPR - PMI_Min], 1}, 87 // 3 ops in DPRs 88 {&PartMappings[PMI_DPR - PMI_Min], 1}, 89 {&PartMappings[PMI_DPR - PMI_Min], 1}, 90 {&PartMappings[PMI_DPR - PMI_Min], 1}}; 91 92 #ifndef NDEBUG 93 static bool checkValueMapping(const RegisterBankInfo::ValueMapping &VM, 94 RegisterBankInfo::PartialMapping *BreakDown) { 95 return VM.NumBreakDowns == 1 && VM.BreakDown == BreakDown; 96 } 97 98 static void checkValueMappings() { 99 assert(checkValueMapping(ValueMappings[GPR3OpsIdx], 100 &PartMappings[PMI_GPR - PMI_Min]) && 101 "Wrong value mapping for 3 GPR ops instruction"); 102 assert(checkValueMapping(ValueMappings[GPR3OpsIdx + 1], 103 &PartMappings[PMI_GPR - PMI_Min]) && 104 "Wrong value mapping for 3 GPR ops instruction"); 105 assert(checkValueMapping(ValueMappings[GPR3OpsIdx + 2], 106 &PartMappings[PMI_GPR - PMI_Min]) && 107 "Wrong value mapping for 3 GPR ops instruction"); 108 109 assert(checkValueMapping(ValueMappings[SPR3OpsIdx], 110 &PartMappings[PMI_SPR - PMI_Min]) && 111 "Wrong value mapping for 3 SPR ops instruction"); 112 assert(checkValueMapping(ValueMappings[SPR3OpsIdx + 1], 113 &PartMappings[PMI_SPR - PMI_Min]) && 114 "Wrong value mapping for 3 SPR ops instruction"); 115 assert(checkValueMapping(ValueMappings[SPR3OpsIdx + 2], 116 &PartMappings[PMI_SPR - PMI_Min]) && 117 "Wrong value mapping for 3 SPR ops instruction"); 118 119 assert(checkValueMapping(ValueMappings[DPR3OpsIdx], 120 &PartMappings[PMI_DPR - PMI_Min]) && 121 "Wrong value mapping for 3 DPR ops instruction"); 122 assert(checkValueMapping(ValueMappings[DPR3OpsIdx + 1], 123 &PartMappings[PMI_DPR - PMI_Min]) && 124 "Wrong value mapping for 3 DPR ops instruction"); 125 assert(checkValueMapping(ValueMappings[DPR3OpsIdx + 2], 126 &PartMappings[PMI_DPR - PMI_Min]) && 127 "Wrong value mapping for 3 DPR ops instruction"); 128 } 129 #endif 130 } // end namespace arm 131 } // end namespace llvm 132 133 ARMRegisterBankInfo::ARMRegisterBankInfo(const TargetRegisterInfo &TRI) 134 : ARMGenRegisterBankInfo() { 135 static bool AlreadyInit = false; 136 // We have only one set of register banks, whatever the subtarget 137 // is. Therefore, the initialization of the RegBanks table should be 138 // done only once. Indeed the table of all register banks 139 // (ARM::RegBanks) is unique in the compiler. At some point, it 140 // will get tablegen'ed and the whole constructor becomes empty. 141 if (AlreadyInit) 142 return; 143 AlreadyInit = true; 144 145 const RegisterBank &RBGPR = getRegBank(ARM::GPRRegBankID); 146 (void)RBGPR; 147 assert(&ARM::GPRRegBank == &RBGPR && "The order in RegBanks is messed up"); 148 149 // Initialize the GPR bank. 150 assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRRegClassID)) && 151 "Subclass not added?"); 152 assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRwithAPSRRegClassID)) && 153 "Subclass not added?"); 154 assert(RBGPR.covers(*TRI.getRegClass(ARM::GPRnopcRegClassID)) && 155 "Subclass not added?"); 156 assert(RBGPR.covers(*TRI.getRegClass(ARM::rGPRRegClassID)) && 157 "Subclass not added?"); 158 assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPRRegClassID)) && 159 "Subclass not added?"); 160 assert(RBGPR.covers(*TRI.getRegClass(ARM::tcGPRRegClassID)) && 161 "Subclass not added?"); 162 assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPR_and_tcGPRRegClassID)) && 163 "Subclass not added?"); 164 assert(RBGPR.getSize() == 32 && "GPRs should hold up to 32-bit"); 165 166 #ifndef NDEBUG 167 ARM::checkPartialMappings(); 168 ARM::checkValueMappings(); 169 #endif 170 } 171 172 const RegisterBank &ARMRegisterBankInfo::getRegBankFromRegClass( 173 const TargetRegisterClass &RC) const { 174 using namespace ARM; 175 176 switch (RC.getID()) { 177 case GPRRegClassID: 178 case GPRwithAPSRRegClassID: 179 case GPRnopcRegClassID: 180 case rGPRRegClassID: 181 case GPRspRegClassID: 182 case tGPR_and_tcGPRRegClassID: 183 case tcGPRRegClassID: 184 case tGPRRegClassID: 185 return getRegBank(ARM::GPRRegBankID); 186 case HPRRegClassID: 187 case SPR_8RegClassID: 188 case SPRRegClassID: 189 case DPR_8RegClassID: 190 case DPRRegClassID: 191 case QPRRegClassID: 192 return getRegBank(ARM::FPRRegBankID); 193 default: 194 llvm_unreachable("Unsupported register kind"); 195 } 196 197 llvm_unreachable("Switch should handle all register classes"); 198 } 199 200 const RegisterBankInfo::InstructionMapping & 201 ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 202 auto Opc = MI.getOpcode(); 203 204 // Try the default logic for non-generic instructions that are either copies 205 // or already have some operands assigned to banks. 206 if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) { 207 const InstructionMapping &Mapping = getInstrMappingImpl(MI); 208 if (Mapping.isValid()) 209 return Mapping; 210 } 211 212 using namespace TargetOpcode; 213 214 const MachineFunction &MF = *MI.getParent()->getParent(); 215 const MachineRegisterInfo &MRI = MF.getRegInfo(); 216 unsigned NumOperands = MI.getNumOperands(); 217 const ValueMapping *OperandsMapping = &ARM::ValueMappings[ARM::GPR3OpsIdx]; 218 219 switch (Opc) { 220 case G_ADD: 221 case G_SUB: 222 case G_MUL: 223 case G_AND: 224 case G_OR: 225 case G_XOR: 226 case G_LSHR: 227 case G_ASHR: 228 case G_SHL: 229 case G_SDIV: 230 case G_UDIV: 231 case G_SEXT: 232 case G_ZEXT: 233 case G_ANYEXT: 234 case G_GEP: 235 case G_INTTOPTR: 236 case G_PTRTOINT: 237 case G_CTLZ: 238 // FIXME: We're abusing the fact that everything lives in a GPR for now; in 239 // the real world we would use different mappings. 240 OperandsMapping = &ARM::ValueMappings[ARM::GPR3OpsIdx]; 241 break; 242 case G_TRUNC: { 243 // In some cases we may end up with a G_TRUNC from a 64-bit value to a 244 // 32-bit value. This isn't a real floating point trunc (that would be a 245 // G_FPTRUNC). Instead it is an integer trunc in disguise, which can appear 246 // because the legalizer doesn't distinguish between integer and floating 247 // point values so it may leave some 64-bit integers un-narrowed. Until we 248 // have a more principled solution that doesn't let such things sneak all 249 // the way to this point, just map the source to a DPR and the destination 250 // to a GPR. 251 LLT LargeTy = MRI.getType(MI.getOperand(1).getReg()); 252 OperandsMapping = 253 LargeTy.getSizeInBits() <= 32 254 ? &ARM::ValueMappings[ARM::GPR3OpsIdx] 255 : getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], 256 &ARM::ValueMappings[ARM::DPR3OpsIdx]}); 257 break; 258 } 259 case G_LOAD: 260 case G_STORE: { 261 LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 262 OperandsMapping = 263 Ty.getSizeInBits() == 64 264 ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], 265 &ARM::ValueMappings[ARM::GPR3OpsIdx]}) 266 : &ARM::ValueMappings[ARM::GPR3OpsIdx]; 267 break; 268 } 269 case G_FADD: 270 case G_FSUB: 271 case G_FMUL: 272 case G_FDIV: 273 case G_FNEG: { 274 LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 275 OperandsMapping =Ty.getSizeInBits() == 64 276 ? &ARM::ValueMappings[ARM::DPR3OpsIdx] 277 : &ARM::ValueMappings[ARM::SPR3OpsIdx]; 278 break; 279 } 280 case G_FMA: { 281 LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 282 OperandsMapping = 283 Ty.getSizeInBits() == 64 284 ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], 285 &ARM::ValueMappings[ARM::DPR3OpsIdx], 286 &ARM::ValueMappings[ARM::DPR3OpsIdx], 287 &ARM::ValueMappings[ARM::DPR3OpsIdx]}) 288 : getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx], 289 &ARM::ValueMappings[ARM::SPR3OpsIdx], 290 &ARM::ValueMappings[ARM::SPR3OpsIdx], 291 &ARM::ValueMappings[ARM::SPR3OpsIdx]}); 292 break; 293 } 294 case G_FPEXT: { 295 LLT ToTy = MRI.getType(MI.getOperand(0).getReg()); 296 LLT FromTy = MRI.getType(MI.getOperand(1).getReg()); 297 if (ToTy.getSizeInBits() == 64 && FromTy.getSizeInBits() == 32) 298 OperandsMapping = 299 getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], 300 &ARM::ValueMappings[ARM::SPR3OpsIdx]}); 301 break; 302 } 303 case G_FPTRUNC: { 304 LLT ToTy = MRI.getType(MI.getOperand(0).getReg()); 305 LLT FromTy = MRI.getType(MI.getOperand(1).getReg()); 306 if (ToTy.getSizeInBits() == 32 && FromTy.getSizeInBits() == 64) 307 OperandsMapping = 308 getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx], 309 &ARM::ValueMappings[ARM::DPR3OpsIdx]}); 310 break; 311 } 312 case G_FPTOSI: 313 case G_FPTOUI: { 314 LLT ToTy = MRI.getType(MI.getOperand(0).getReg()); 315 LLT FromTy = MRI.getType(MI.getOperand(1).getReg()); 316 if ((FromTy.getSizeInBits() == 32 || FromTy.getSizeInBits() == 64) && 317 ToTy.getSizeInBits() == 32) 318 OperandsMapping = 319 FromTy.getSizeInBits() == 64 320 ? getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], 321 &ARM::ValueMappings[ARM::DPR3OpsIdx]}) 322 : getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], 323 &ARM::ValueMappings[ARM::SPR3OpsIdx]}); 324 break; 325 } 326 case G_SITOFP: 327 case G_UITOFP: { 328 LLT ToTy = MRI.getType(MI.getOperand(0).getReg()); 329 LLT FromTy = MRI.getType(MI.getOperand(1).getReg()); 330 if (FromTy.getSizeInBits() == 32 && 331 (ToTy.getSizeInBits() == 32 || ToTy.getSizeInBits() == 64)) 332 OperandsMapping = 333 ToTy.getSizeInBits() == 64 334 ? getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], 335 &ARM::ValueMappings[ARM::GPR3OpsIdx]}) 336 : getOperandsMapping({&ARM::ValueMappings[ARM::SPR3OpsIdx], 337 &ARM::ValueMappings[ARM::GPR3OpsIdx]}); 338 break; 339 } 340 case G_CONSTANT: 341 case G_FRAME_INDEX: 342 case G_GLOBAL_VALUE: 343 OperandsMapping = 344 getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr}); 345 break; 346 case G_SELECT: { 347 LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 348 (void)Ty; 349 LLT Ty2 = MRI.getType(MI.getOperand(1).getReg()); 350 (void)Ty2; 351 assert(Ty.getSizeInBits() == 32 && "Unsupported size for G_SELECT"); 352 assert(Ty2.getSizeInBits() == 1 && "Unsupported size for G_SELECT"); 353 OperandsMapping = 354 getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], 355 &ARM::ValueMappings[ARM::GPR3OpsIdx], 356 &ARM::ValueMappings[ARM::GPR3OpsIdx], 357 &ARM::ValueMappings[ARM::GPR3OpsIdx]}); 358 break; 359 } 360 case G_ICMP: { 361 LLT Ty2 = MRI.getType(MI.getOperand(2).getReg()); 362 (void)Ty2; 363 assert(Ty2.getSizeInBits() == 32 && "Unsupported size for G_ICMP"); 364 OperandsMapping = 365 getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr, 366 &ARM::ValueMappings[ARM::GPR3OpsIdx], 367 &ARM::ValueMappings[ARM::GPR3OpsIdx]}); 368 break; 369 } 370 case G_FCMP: { 371 LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 372 (void)Ty; 373 LLT Ty1 = MRI.getType(MI.getOperand(2).getReg()); 374 LLT Ty2 = MRI.getType(MI.getOperand(3).getReg()); 375 (void)Ty2; 376 assert(Ty.getSizeInBits() == 1 && "Unsupported size for G_FCMP"); 377 assert(Ty1.getSizeInBits() == Ty2.getSizeInBits() && 378 "Mismatched operand sizes for G_FCMP"); 379 380 unsigned Size = Ty1.getSizeInBits(); 381 assert((Size == 32 || Size == 64) && "Unsupported size for G_FCMP"); 382 383 auto FPRValueMapping = Size == 32 ? &ARM::ValueMappings[ARM::SPR3OpsIdx] 384 : &ARM::ValueMappings[ARM::DPR3OpsIdx]; 385 OperandsMapping = 386 getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr, 387 FPRValueMapping, FPRValueMapping}); 388 break; 389 } 390 case G_MERGE_VALUES: { 391 // We only support G_MERGE_VALUES for creating a double precision floating 392 // point value out of two GPRs. 393 LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 394 LLT Ty1 = MRI.getType(MI.getOperand(1).getReg()); 395 LLT Ty2 = MRI.getType(MI.getOperand(2).getReg()); 396 if (Ty.getSizeInBits() != 64 || Ty1.getSizeInBits() != 32 || 397 Ty2.getSizeInBits() != 32) 398 return getInvalidInstructionMapping(); 399 OperandsMapping = 400 getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], 401 &ARM::ValueMappings[ARM::GPR3OpsIdx], 402 &ARM::ValueMappings[ARM::GPR3OpsIdx]}); 403 break; 404 } 405 case G_UNMERGE_VALUES: { 406 // We only support G_UNMERGE_VALUES for splitting a double precision 407 // floating point value into two GPRs. 408 LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 409 LLT Ty1 = MRI.getType(MI.getOperand(1).getReg()); 410 LLT Ty2 = MRI.getType(MI.getOperand(2).getReg()); 411 if (Ty.getSizeInBits() != 32 || Ty1.getSizeInBits() != 32 || 412 Ty2.getSizeInBits() != 64) 413 return getInvalidInstructionMapping(); 414 OperandsMapping = 415 getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], 416 &ARM::ValueMappings[ARM::GPR3OpsIdx], 417 &ARM::ValueMappings[ARM::DPR3OpsIdx]}); 418 break; 419 } 420 case G_BR: 421 OperandsMapping = getOperandsMapping({nullptr}); 422 break; 423 case G_BRCOND: 424 OperandsMapping = 425 getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr}); 426 break; 427 default: 428 return getInvalidInstructionMapping(); 429 } 430 431 #ifndef NDEBUG 432 for (unsigned i = 0; i < NumOperands; i++) { 433 for (const auto &Mapping : OperandsMapping[i]) { 434 assert( 435 (Mapping.RegBank->getID() != ARM::FPRRegBankID || 436 MF.getSubtarget<ARMSubtarget>().hasVFP2()) && 437 "Trying to use floating point register bank on target without vfp"); 438 } 439 } 440 #endif 441 442 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping, 443 NumOperands); 444 } 445