blob: 2e92ae51660b772c611565a539d2a966ff822374 [file] [log] [blame]
//===- 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.