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