| //===- 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 = 1, |
| PM_SGPR16 = 5, |
| PM_SGPR32 = 6, |
| PM_SGPR64 = 7, |
| PM_SGPR128 = 8, |
| PM_SGPR256 = 9, |
| PM_SGPR512 = 10, |
| PM_SGPR1024 = 11, |
| PM_VGPR1 = 12, |
| PM_VGPR16 = 16, |
| PM_VGPR32 = 17, |
| PM_VGPR64 = 18, |
| PM_VGPR128 = 19, |
| PM_VGPR256 = 20, |
| PM_VGPR512 = 21, |
| PM_VGPR1024 = 22, |
| PM_SGPR96 = 23, |
| PM_VGPR96 = 24, |
| PM_AGPR96 = 25, |
| PM_AGPR32 = 31, |
| PM_AGPR64 = 32, |
| PM_AGPR128 = 33, |
| PM_AGPR512 = 34, |
| PM_AGPR1024 = 35 |
| }; |
| |
| const RegisterBankInfo::PartialMapping PartMappings[] { |
| // StartIdx, Length, RegBank |
| {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, 1024, 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, 1024, VGPRRegBank}, |
| {0, 96, SGPRRegBank}, |
| {0, 96, VGPRRegBank}, |
| {0, 96, AGPRRegBank}, |
| |
| {0, 32, AGPRRegBank}, // AGPR begin |
| {0, 64, AGPRRegBank}, |
| {0, 128, AGPRRegBank}, |
| {0, 512, AGPRRegBank}, |
| {0, 1024, AGPRRegBank} |
| }; |
| |
| const RegisterBankInfo::ValueMapping ValMappings[] { |
| // VCC |
| {&PartMappings[0], 1}, |
| |
| // SGPRs |
| {&PartMappings[1], 1}, // 1 |
| {nullptr, 0}, // Illegal power of 2 sizes |
| {nullptr, 0}, |
| {nullptr, 0}, |
| {&PartMappings[2], 1}, // 16 |
| {&PartMappings[3], 1}, // 32 |
| {&PartMappings[4], 1}, // 64 |
| {&PartMappings[5], 1}, // 128 |
| {&PartMappings[6], 1}, // 256 |
| {&PartMappings[7], 1}, // 512 |
| {&PartMappings[8], 1}, // 1024 |
| |
| // VGPRs |
| {&PartMappings[9], 1}, // 1 |
| {nullptr, 0}, |
| {nullptr, 0}, |
| {nullptr, 0}, |
| {&PartMappings[10], 1}, // 16 |
| {&PartMappings[11], 1}, // 32 |
| {&PartMappings[12], 1}, // 64 |
| {&PartMappings[13], 1}, // 128 |
| {&PartMappings[14], 1}, // 256 |
| {&PartMappings[15], 1}, // 512 |
| {&PartMappings[16], 1}, // 1024 |
| {&PartMappings[17], 1}, |
| {&PartMappings[18], 1}, |
| {&PartMappings[19], 1}, |
| |
| // AGPRs |
| {nullptr, 0}, |
| {nullptr, 0}, |
| {nullptr, 0}, |
| {nullptr, 0}, |
| {nullptr, 0}, |
| {&PartMappings[20], 1}, // 32 |
| {&PartMappings[21], 1}, // 64 |
| {&PartMappings[22], 1}, // 128 |
| {nullptr, 0}, |
| {&PartMappings[23], 1}, // 512 |
| {&PartMappings[24], 1} // 1024 |
| }; |
| |
| const RegisterBankInfo::PartialMapping SGPROnly64BreakDown[] { |
| {0, 32, SGPRRegBank}, // 32-bit op |
| {0, 32, SGPRRegBank}, // 2x32-bit op |
| {32, 32, SGPRRegBank}, |
| {0, 64, SGPRRegBank}, // <2x32-bit> op |
| |
| {0, 32, VGPRRegBank}, // 32-bit op |
| {0, 32, VGPRRegBank}, // 2x32-bit op |
| {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 { |
| SGPRStartIdx = 1, |
| VGPRStartIdx = 12, |
| AGPRStartIdx = 26 |
| }; |
| |
| const RegisterBankInfo::ValueMapping *getValueMapping(unsigned BankID, |
| unsigned Size) { |
| unsigned Idx; |
| switch (Size) { |
| case 1: |
| if (BankID == AMDGPU::VCCRegBankID) |
| return &ValMappings[0]; |
| |
| Idx = BankID == AMDGPU::SGPRRegBankID ? PM_SGPR1 : PM_VGPR1; |
| break; |
| case 96: |
| switch (BankID) { |
| case AMDGPU::VGPRRegBankID: |
| Idx = PM_VGPR96; |
| break; |
| case AMDGPU::SGPRRegBankID: |
| Idx = PM_SGPR96; |
| break; |
| case AMDGPU::AGPRRegBankID: |
| Idx = PM_AGPR96; |
| break; |
| default: llvm_unreachable("Invalid register bank"); |
| } |
| break; |
| default: |
| switch (BankID) { |
| case AMDGPU::VGPRRegBankID: |
| Idx = VGPRStartIdx; |
| break; |
| case AMDGPU::SGPRRegBankID: |
| Idx = SGPRStartIdx; |
| break; |
| case AMDGPU::AGPRRegBankID: |
| Idx = AGPRStartIdx; |
| break; |
| default: llvm_unreachable("Invalid register bank"); |
| } |
| 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. |