//===- AMDGPUGenRegisterBankInfo.def -----------------------------*- C++ -*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// This file defines all the static objects used by AMDGPURegisterBankInfo. /// \todo This should be generated by TableGen. //===----------------------------------------------------------------------===// namespace llvm { namespace AMDGPU { enum PartialMappingIdx { None = - 1, PM_SGPR1 = 2, PM_SGPR16 = 6, PM_SGPR32 = 7, PM_SGPR64 = 8, PM_SGPR128 = 9, PM_SGPR256 = 10, PM_SGPR512 = 11, PM_VGPR1 = 12, PM_VGPR16 = 16, PM_VGPR32 = 17, PM_VGPR64 = 18, PM_VGPR128 = 19, PM_VGPR256 = 20, PM_VGPR512 = 21, PM_SGPR96 = 22, PM_VGPR96 = 23 }; const RegisterBankInfo::PartialMapping PartMappings[] { // StartIdx, Length, RegBank {0, 1, SCCRegBank}, {0, 1, VCCRegBank}, {0, 1, SGPRRegBank}, // SGPR begin {0, 16, SGPRRegBank}, {0, 32, SGPRRegBank}, {0, 64, SGPRRegBank}, {0, 128, SGPRRegBank}, {0, 256, SGPRRegBank}, {0, 512, SGPRRegBank}, {0, 1, VGPRRegBank}, // VGPR begin {0, 16, VGPRRegBank}, {0, 32, VGPRRegBank}, {0, 64, VGPRRegBank}, {0, 128, VGPRRegBank}, {0, 256, VGPRRegBank}, {0, 512, VGPRRegBank}, {0, 96, SGPRRegBank}, {0, 96, VGPRRegBank}, }; const RegisterBankInfo::ValueMapping ValMappings[] { // SCC {&PartMappings[0], 1}, // VCC {&PartMappings[1], 1}, // SGPRs {&PartMappings[2], 1}, {nullptr, 0}, // Illegal power of 2 sizes {nullptr, 0}, {nullptr, 0}, {&PartMappings[3], 1}, {&PartMappings[4], 1}, {&PartMappings[5], 1}, {&PartMappings[6], 1}, {&PartMappings[7], 1}, {&PartMappings[8], 1}, // VGPRs {&PartMappings[9], 1}, {nullptr, 0}, {nullptr, 0}, {nullptr, 0}, {&PartMappings[10], 1}, {&PartMappings[11], 1}, {&PartMappings[12], 1}, {&PartMappings[13], 1}, {&PartMappings[14], 1}, {&PartMappings[15], 1}, {&PartMappings[16], 1}, {&PartMappings[17], 1} }; const RegisterBankInfo::PartialMapping SGPROnly64BreakDown[] { /*32-bit op*/ {0, 32, SGPRRegBank}, /*2x32-bit op*/ {0, 32, SGPRRegBank}, {32, 32, SGPRRegBank}, /*<2x32-bit> op*/ {0, 64, SGPRRegBank}, /*32-bit op*/ {0, 32, VGPRRegBank}, /*2x32-bit op*/ {0, 32, VGPRRegBank}, {32, 32, VGPRRegBank}, }; // For some instructions which can operate 64-bit only for the scalar version. const RegisterBankInfo::ValueMapping ValMappingsSGPR64OnlyVGPR32[] { /*32-bit sgpr*/ {&SGPROnly64BreakDown[0], 1}, /*2 x 32-bit sgpr*/ {&SGPROnly64BreakDown[1], 2}, /*64-bit sgpr */ {&SGPROnly64BreakDown[3], 1}, /*32-bit vgpr*/ {&SGPROnly64BreakDown[4], 1}, /*2 x 32-bit vgpr*/ {&SGPROnly64BreakDown[5], 2} }; enum ValueMappingIdx { SCCStartIdx = 0, SGPRStartIdx = 2, VGPRStartIdx = 12 }; const RegisterBankInfo::ValueMapping *getValueMapping(unsigned BankID, unsigned Size) { unsigned Idx; switch (Size) { case 1: if (BankID == AMDGPU::SCCRegBankID) return &ValMappings[0]; if (BankID == AMDGPU::VCCRegBankID) return &ValMappings[1]; // 1-bit values not from a compare etc. Idx = BankID == AMDGPU::SGPRRegBankID ? PM_SGPR1 : PM_VGPR1; break; case 96: assert(BankID != AMDGPU::VCCRegBankID); Idx = BankID == AMDGPU::SGPRRegBankID ? PM_SGPR96 : PM_VGPR96; break; default: assert(BankID != AMDGPU::VCCRegBankID); Idx = BankID == AMDGPU::VGPRRegBankID ? VGPRStartIdx : SGPRStartIdx; Idx += Log2_32_Ceil(Size); break; } assert(Log2_32_Ceil(Size) == Log2_32_Ceil(ValMappings[Idx].BreakDown->Length)); assert(BankID == ValMappings[Idx].BreakDown->RegBank->getID()); return &ValMappings[Idx]; } const RegisterBankInfo::ValueMapping *getValueMappingSGPR64Only(unsigned BankID, unsigned Size) { if (Size != 64) return getValueMapping(BankID, Size); if (BankID == AMDGPU::VGPRRegBankID) return &ValMappingsSGPR64OnlyVGPR32[4]; assert(BankID == AMDGPU::SGPRRegBankID); return &ValMappingsSGPR64OnlyVGPR32[2]; } const RegisterBankInfo::PartialMapping LoadSGPROnlyBreakDown[] { /* 256-bit load */ {0, 256, SGPRRegBank}, /* 512-bit load */ {0, 512, SGPRRegBank}, /* 8 32-bit loads */ {0, 32, VGPRRegBank}, {32, 32, VGPRRegBank}, {64, 32, VGPRRegBank}, {96, 32, VGPRRegBank}, {128, 32, VGPRRegBank}, {160, 32, VGPRRegBank}, {192, 32, VGPRRegBank}, {224, 32, VGPRRegBank}, /* 16 32-bit loads */ {0, 32, VGPRRegBank}, {32, 32, VGPRRegBank}, {64, 32, VGPRRegBank}, {96, 32, VGPRRegBank}, {128, 32, VGPRRegBank}, {160, 32, VGPRRegBank}, {192, 32, VGPRRegBank}, {224, 32, VGPRRegBank}, {256, 32, VGPRRegBank}, {288, 32, VGPRRegBank}, {320, 32, VGPRRegBank}, {352, 32, VGPRRegBank}, {384, 32, VGPRRegBank}, {416, 32, VGPRRegBank}, {448, 32, VGPRRegBank}, {480, 32, VGPRRegBank}, /* 4 64-bit loads */ {0, 64, VGPRRegBank}, {64, 64, VGPRRegBank}, {128, 64, VGPRRegBank}, {192, 64, VGPRRegBank}, /* 8 64-bit loads */ {0, 64, VGPRRegBank}, {64, 64, VGPRRegBank}, {128, 64, VGPRRegBank}, {192, 64, VGPRRegBank}, {256, 64, VGPRRegBank}, {320, 64, VGPRRegBank}, {384, 64, VGPRRegBank}, {448, 64, VGPRRegBank}, /* FIXME: The generic register bank select does not support complex * break downs where the number of vector elements does not equal the * number of breakdowns. * FIXME: register bank select now tries to handle complex break downs, * but it emits an illegal instruction: * %1:vgpr(<8 x s32>) = G_CONCAT_VECTORS %2:vgpr(s128), %3:vgpr(s128) */ /* 2 128-bit loads */ {0, 128, VGPRRegBank}, {128, 128, VGPRRegBank}, /* 4 128-bit loads */ {0, 128, VGPRRegBank}, {128, 128, VGPRRegBank}, {256, 128, VGPRRegBank}, {384, 128, VGPRRegBank} }; const RegisterBankInfo::ValueMapping ValMappingsLoadSGPROnly[] { /* 256-bit load */ {&LoadSGPROnlyBreakDown[0], 1}, /* 512-bit load */ {&LoadSGPROnlyBreakDown[1], 1}, /* <8 x i32> load */ {&LoadSGPROnlyBreakDown[2], 8}, /* <16 x i32> load */ {&LoadSGPROnlyBreakDown[10], 16}, /* <4 x i64> load */ {&LoadSGPROnlyBreakDown[26], 4}, /* <8 x i64> load */ {&LoadSGPROnlyBreakDown[30], 8} }; const RegisterBankInfo::ValueMapping * getValueMappingLoadSGPROnly(unsigned BankID, LLT SizeTy) { unsigned Size = SizeTy.getSizeInBits(); if (Size < 256 || BankID == AMDGPU::SGPRRegBankID) return getValueMapping(BankID, Size); assert((Size == 256 || Size == 512) && BankID == AMDGPU::VGPRRegBankID); // Default to using the non-split ValueMappings, we will use these if // the register bank is SGPR or if we don't know how to handle the vector // type. unsigned Idx = Size == 256 ? 0 : 1; // We need to split this load if it has a vgpr pointer. if (BankID == AMDGPU::VGPRRegBankID) { if (SizeTy == LLT::vector(8, 32)) Idx = 2; else if (SizeTy == LLT::vector(16, 32)) Idx = 3; else if (SizeTy == LLT::vector(4, 64)) Idx = 4; else if (SizeTy == LLT::vector(8, 64)) Idx = 5; } return &ValMappingsLoadSGPROnly[Idx]; } } // End AMDGPU namespace. } // End llvm namespace.