1*0b57cec5SDimitry Andric//===- AMDGPUGenRegisterBankInfo.def -----------------------------*- C++ -*-==// 2*0b57cec5SDimitry Andric// 3*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric// 7*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric/// \file 9*0b57cec5SDimitry Andric/// This file defines all the static objects used by AMDGPURegisterBankInfo. 10*0b57cec5SDimitry Andric/// \todo This should be generated by TableGen. 11*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andricnamespace llvm { 14*0b57cec5SDimitry Andricnamespace AMDGPU { 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andricenum PartialMappingIdx { 17*0b57cec5SDimitry Andric None = - 1, 18*0b57cec5SDimitry Andric PM_SGPR1 = 2, 19*0b57cec5SDimitry Andric PM_SGPR16 = 6, 20*0b57cec5SDimitry Andric PM_SGPR32 = 7, 21*0b57cec5SDimitry Andric PM_SGPR64 = 8, 22*0b57cec5SDimitry Andric PM_SGPR128 = 9, 23*0b57cec5SDimitry Andric PM_SGPR256 = 10, 24*0b57cec5SDimitry Andric PM_SGPR512 = 11, 25*0b57cec5SDimitry Andric PM_VGPR1 = 12, 26*0b57cec5SDimitry Andric PM_VGPR16 = 16, 27*0b57cec5SDimitry Andric PM_VGPR32 = 17, 28*0b57cec5SDimitry Andric PM_VGPR64 = 18, 29*0b57cec5SDimitry Andric PM_VGPR128 = 19, 30*0b57cec5SDimitry Andric PM_VGPR256 = 20, 31*0b57cec5SDimitry Andric PM_VGPR512 = 21, 32*0b57cec5SDimitry Andric PM_SGPR96 = 22, 33*0b57cec5SDimitry Andric PM_VGPR96 = 23 34*0b57cec5SDimitry Andric}; 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andricconst RegisterBankInfo::PartialMapping PartMappings[] { 37*0b57cec5SDimitry Andric // StartIdx, Length, RegBank 38*0b57cec5SDimitry Andric {0, 1, SCCRegBank}, 39*0b57cec5SDimitry Andric {0, 1, VCCRegBank}, 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric {0, 1, SGPRRegBank}, // SGPR begin 42*0b57cec5SDimitry Andric {0, 16, SGPRRegBank}, 43*0b57cec5SDimitry Andric {0, 32, SGPRRegBank}, 44*0b57cec5SDimitry Andric {0, 64, SGPRRegBank}, 45*0b57cec5SDimitry Andric {0, 128, SGPRRegBank}, 46*0b57cec5SDimitry Andric {0, 256, SGPRRegBank}, 47*0b57cec5SDimitry Andric {0, 512, SGPRRegBank}, 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric {0, 1, VGPRRegBank}, // VGPR begin 50*0b57cec5SDimitry Andric {0, 16, VGPRRegBank}, 51*0b57cec5SDimitry Andric {0, 32, VGPRRegBank}, 52*0b57cec5SDimitry Andric {0, 64, VGPRRegBank}, 53*0b57cec5SDimitry Andric {0, 128, VGPRRegBank}, 54*0b57cec5SDimitry Andric {0, 256, VGPRRegBank}, 55*0b57cec5SDimitry Andric {0, 512, VGPRRegBank}, 56*0b57cec5SDimitry Andric {0, 96, SGPRRegBank}, 57*0b57cec5SDimitry Andric {0, 96, VGPRRegBank}, 58*0b57cec5SDimitry Andric}; 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andricconst RegisterBankInfo::ValueMapping ValMappings[] { 61*0b57cec5SDimitry Andric // SCC 62*0b57cec5SDimitry Andric {&PartMappings[0], 1}, 63*0b57cec5SDimitry Andric 64*0b57cec5SDimitry Andric // VCC 65*0b57cec5SDimitry Andric {&PartMappings[1], 1}, 66*0b57cec5SDimitry Andric 67*0b57cec5SDimitry Andric // SGPRs 68*0b57cec5SDimitry Andric {&PartMappings[2], 1}, 69*0b57cec5SDimitry Andric {nullptr, 0}, // Illegal power of 2 sizes 70*0b57cec5SDimitry Andric {nullptr, 0}, 71*0b57cec5SDimitry Andric {nullptr, 0}, 72*0b57cec5SDimitry Andric {&PartMappings[3], 1}, 73*0b57cec5SDimitry Andric {&PartMappings[4], 1}, 74*0b57cec5SDimitry Andric {&PartMappings[5], 1}, 75*0b57cec5SDimitry Andric {&PartMappings[6], 1}, 76*0b57cec5SDimitry Andric {&PartMappings[7], 1}, 77*0b57cec5SDimitry Andric {&PartMappings[8], 1}, 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric // VGPRs 80*0b57cec5SDimitry Andric {&PartMappings[9], 1}, 81*0b57cec5SDimitry Andric {nullptr, 0}, 82*0b57cec5SDimitry Andric {nullptr, 0}, 83*0b57cec5SDimitry Andric {nullptr, 0}, 84*0b57cec5SDimitry Andric {&PartMappings[10], 1}, 85*0b57cec5SDimitry Andric {&PartMappings[11], 1}, 86*0b57cec5SDimitry Andric {&PartMappings[12], 1}, 87*0b57cec5SDimitry Andric {&PartMappings[13], 1}, 88*0b57cec5SDimitry Andric {&PartMappings[14], 1}, 89*0b57cec5SDimitry Andric {&PartMappings[15], 1}, 90*0b57cec5SDimitry Andric {&PartMappings[16], 1}, 91*0b57cec5SDimitry Andric {&PartMappings[17], 1} 92*0b57cec5SDimitry Andric}; 93*0b57cec5SDimitry Andric 94*0b57cec5SDimitry Andricconst RegisterBankInfo::PartialMapping SGPROnly64BreakDown[] { 95*0b57cec5SDimitry Andric /*32-bit op*/ {0, 32, SGPRRegBank}, 96*0b57cec5SDimitry Andric /*2x32-bit op*/ {0, 32, SGPRRegBank}, 97*0b57cec5SDimitry Andric {32, 32, SGPRRegBank}, 98*0b57cec5SDimitry Andric/*<2x32-bit> op*/ {0, 64, SGPRRegBank}, 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric /*32-bit op*/ {0, 32, VGPRRegBank}, 101*0b57cec5SDimitry Andric /*2x32-bit op*/ {0, 32, VGPRRegBank}, 102*0b57cec5SDimitry Andric {32, 32, VGPRRegBank}, 103*0b57cec5SDimitry Andric}; 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric 106*0b57cec5SDimitry Andric// For some instructions which can operate 64-bit only for the scalar version. 107*0b57cec5SDimitry Andricconst RegisterBankInfo::ValueMapping ValMappingsSGPR64OnlyVGPR32[] { 108*0b57cec5SDimitry Andric /*32-bit sgpr*/ {&SGPROnly64BreakDown[0], 1}, 109*0b57cec5SDimitry Andric /*2 x 32-bit sgpr*/ {&SGPROnly64BreakDown[1], 2}, 110*0b57cec5SDimitry Andric /*64-bit sgpr */ {&SGPROnly64BreakDown[3], 1}, 111*0b57cec5SDimitry Andric 112*0b57cec5SDimitry Andric /*32-bit vgpr*/ {&SGPROnly64BreakDown[4], 1}, 113*0b57cec5SDimitry Andric /*2 x 32-bit vgpr*/ {&SGPROnly64BreakDown[5], 2} 114*0b57cec5SDimitry Andric}; 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andricenum ValueMappingIdx { 117*0b57cec5SDimitry Andric SCCStartIdx = 0, 118*0b57cec5SDimitry Andric SGPRStartIdx = 2, 119*0b57cec5SDimitry Andric VGPRStartIdx = 12 120*0b57cec5SDimitry Andric}; 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andricconst RegisterBankInfo::ValueMapping *getValueMapping(unsigned BankID, 123*0b57cec5SDimitry Andric unsigned Size) { 124*0b57cec5SDimitry Andric unsigned Idx; 125*0b57cec5SDimitry Andric switch (Size) { 126*0b57cec5SDimitry Andric case 1: 127*0b57cec5SDimitry Andric if (BankID == AMDGPU::SCCRegBankID) 128*0b57cec5SDimitry Andric return &ValMappings[0]; 129*0b57cec5SDimitry Andric if (BankID == AMDGPU::VCCRegBankID) 130*0b57cec5SDimitry Andric return &ValMappings[1]; 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric // 1-bit values not from a compare etc. 133*0b57cec5SDimitry Andric Idx = BankID == AMDGPU::SGPRRegBankID ? PM_SGPR1 : PM_VGPR1; 134*0b57cec5SDimitry Andric break; 135*0b57cec5SDimitry Andric case 96: 136*0b57cec5SDimitry Andric assert(BankID != AMDGPU::VCCRegBankID); 137*0b57cec5SDimitry Andric Idx = BankID == AMDGPU::SGPRRegBankID ? PM_SGPR96 : PM_VGPR96; 138*0b57cec5SDimitry Andric break; 139*0b57cec5SDimitry Andric default: 140*0b57cec5SDimitry Andric assert(BankID != AMDGPU::VCCRegBankID); 141*0b57cec5SDimitry Andric Idx = BankID == AMDGPU::VGPRRegBankID ? VGPRStartIdx : SGPRStartIdx; 142*0b57cec5SDimitry Andric Idx += Log2_32_Ceil(Size); 143*0b57cec5SDimitry Andric break; 144*0b57cec5SDimitry Andric } 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric assert(Log2_32_Ceil(Size) == Log2_32_Ceil(ValMappings[Idx].BreakDown->Length)); 147*0b57cec5SDimitry Andric assert(BankID == ValMappings[Idx].BreakDown->RegBank->getID()); 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric return &ValMappings[Idx]; 150*0b57cec5SDimitry Andric} 151*0b57cec5SDimitry Andric 152*0b57cec5SDimitry Andricconst RegisterBankInfo::ValueMapping *getValueMappingSGPR64Only(unsigned BankID, 153*0b57cec5SDimitry Andric unsigned Size) { 154*0b57cec5SDimitry Andric if (Size != 64) 155*0b57cec5SDimitry Andric return getValueMapping(BankID, Size); 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric if (BankID == AMDGPU::VGPRRegBankID) 158*0b57cec5SDimitry Andric return &ValMappingsSGPR64OnlyVGPR32[4]; 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric assert(BankID == AMDGPU::SGPRRegBankID); 161*0b57cec5SDimitry Andric return &ValMappingsSGPR64OnlyVGPR32[2]; 162*0b57cec5SDimitry Andric} 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andricconst RegisterBankInfo::PartialMapping LoadSGPROnlyBreakDown[] { 165*0b57cec5SDimitry Andric /* 256-bit load */ {0, 256, SGPRRegBank}, 166*0b57cec5SDimitry Andric /* 512-bit load */ {0, 512, SGPRRegBank}, 167*0b57cec5SDimitry Andric /* 8 32-bit loads */ {0, 32, VGPRRegBank}, {32, 32, VGPRRegBank}, 168*0b57cec5SDimitry Andric {64, 32, VGPRRegBank}, {96, 32, VGPRRegBank}, 169*0b57cec5SDimitry Andric {128, 32, VGPRRegBank}, {160, 32, VGPRRegBank}, 170*0b57cec5SDimitry Andric {192, 32, VGPRRegBank}, {224, 32, VGPRRegBank}, 171*0b57cec5SDimitry Andric /* 16 32-bit loads */ {0, 32, VGPRRegBank}, {32, 32, VGPRRegBank}, 172*0b57cec5SDimitry Andric {64, 32, VGPRRegBank}, {96, 32, VGPRRegBank}, 173*0b57cec5SDimitry Andric {128, 32, VGPRRegBank}, {160, 32, VGPRRegBank}, 174*0b57cec5SDimitry Andric {192, 32, VGPRRegBank}, {224, 32, VGPRRegBank}, 175*0b57cec5SDimitry Andric {256, 32, VGPRRegBank}, {288, 32, VGPRRegBank}, 176*0b57cec5SDimitry Andric {320, 32, VGPRRegBank}, {352, 32, VGPRRegBank}, 177*0b57cec5SDimitry Andric {384, 32, VGPRRegBank}, {416, 32, VGPRRegBank}, 178*0b57cec5SDimitry Andric {448, 32, VGPRRegBank}, {480, 32, VGPRRegBank}, 179*0b57cec5SDimitry Andric /* 4 64-bit loads */ {0, 64, VGPRRegBank}, {64, 64, VGPRRegBank}, 180*0b57cec5SDimitry Andric {128, 64, VGPRRegBank}, {192, 64, VGPRRegBank}, 181*0b57cec5SDimitry Andric /* 8 64-bit loads */ {0, 64, VGPRRegBank}, {64, 64, VGPRRegBank}, 182*0b57cec5SDimitry Andric {128, 64, VGPRRegBank}, {192, 64, VGPRRegBank}, 183*0b57cec5SDimitry Andric {256, 64, VGPRRegBank}, {320, 64, VGPRRegBank}, 184*0b57cec5SDimitry Andric {384, 64, VGPRRegBank}, {448, 64, VGPRRegBank}, 185*0b57cec5SDimitry Andric 186*0b57cec5SDimitry Andric /* FIXME: The generic register bank select does not support complex 187*0b57cec5SDimitry Andric * break downs where the number of vector elements does not equal the 188*0b57cec5SDimitry Andric * number of breakdowns. 189*0b57cec5SDimitry Andric * FIXME: register bank select now tries to handle complex break downs, 190*0b57cec5SDimitry Andric * but it emits an illegal instruction: 191*0b57cec5SDimitry Andric * %1:vgpr(<8 x s32>) = G_CONCAT_VECTORS %2:vgpr(s128), %3:vgpr(s128) 192*0b57cec5SDimitry Andric */ 193*0b57cec5SDimitry Andric /* 2 128-bit loads */ {0, 128, VGPRRegBank}, {128, 128, VGPRRegBank}, 194*0b57cec5SDimitry Andric /* 4 128-bit loads */ {0, 128, VGPRRegBank}, {128, 128, VGPRRegBank}, 195*0b57cec5SDimitry Andric {256, 128, VGPRRegBank}, {384, 128, VGPRRegBank} 196*0b57cec5SDimitry Andric}; 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andricconst RegisterBankInfo::ValueMapping ValMappingsLoadSGPROnly[] { 199*0b57cec5SDimitry Andric /* 256-bit load */ {&LoadSGPROnlyBreakDown[0], 1}, 200*0b57cec5SDimitry Andric /* 512-bit load */ {&LoadSGPROnlyBreakDown[1], 1}, 201*0b57cec5SDimitry Andric /* <8 x i32> load */ {&LoadSGPROnlyBreakDown[2], 8}, 202*0b57cec5SDimitry Andric /* <16 x i32> load */ {&LoadSGPROnlyBreakDown[10], 16}, 203*0b57cec5SDimitry Andric /* <4 x i64> load */ {&LoadSGPROnlyBreakDown[26], 4}, 204*0b57cec5SDimitry Andric /* <8 x i64> load */ {&LoadSGPROnlyBreakDown[30], 8} 205*0b57cec5SDimitry Andric}; 206*0b57cec5SDimitry Andric 207*0b57cec5SDimitry Andricconst RegisterBankInfo::ValueMapping * 208*0b57cec5SDimitry AndricgetValueMappingLoadSGPROnly(unsigned BankID, LLT SizeTy) { 209*0b57cec5SDimitry Andric unsigned Size = SizeTy.getSizeInBits(); 210*0b57cec5SDimitry Andric if (Size < 256 || BankID == AMDGPU::SGPRRegBankID) 211*0b57cec5SDimitry Andric return getValueMapping(BankID, Size); 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric assert((Size == 256 || Size == 512) && BankID == AMDGPU::VGPRRegBankID); 214*0b57cec5SDimitry Andric 215*0b57cec5SDimitry Andric // Default to using the non-split ValueMappings, we will use these if 216*0b57cec5SDimitry Andric // the register bank is SGPR or if we don't know how to handle the vector 217*0b57cec5SDimitry Andric // type. 218*0b57cec5SDimitry Andric unsigned Idx = Size == 256 ? 0 : 1; 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric // We need to split this load if it has a vgpr pointer. 221*0b57cec5SDimitry Andric if (BankID == AMDGPU::VGPRRegBankID) { 222*0b57cec5SDimitry Andric if (SizeTy == LLT::vector(8, 32)) 223*0b57cec5SDimitry Andric Idx = 2; 224*0b57cec5SDimitry Andric else if (SizeTy == LLT::vector(16, 32)) 225*0b57cec5SDimitry Andric Idx = 3; 226*0b57cec5SDimitry Andric else if (SizeTy == LLT::vector(4, 64)) 227*0b57cec5SDimitry Andric Idx = 4; 228*0b57cec5SDimitry Andric else if (SizeTy == LLT::vector(8, 64)) 229*0b57cec5SDimitry Andric Idx = 5; 230*0b57cec5SDimitry Andric } 231*0b57cec5SDimitry Andric 232*0b57cec5SDimitry Andric return &ValMappingsLoadSGPROnly[Idx]; 233*0b57cec5SDimitry Andric} 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric} // End AMDGPU namespace. 237*0b57cec5SDimitry Andric} // End llvm namespace. 238