intel/compiler: Add a INVALID_{,HW_}REG_TYPE macros
[mesa.git] / src / intel / compiler / brw_reg_type.c
1 /*
2 * Copyright © 2017 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "brw_reg.h"
25 #include "brw_eu_defines.h"
26 #include "dev/gen_device_info.h"
27
28 #define INVALID (-1)
29
30 enum hw_reg_type {
31 BRW_HW_REG_TYPE_UD = 0,
32 BRW_HW_REG_TYPE_D = 1,
33 BRW_HW_REG_TYPE_UW = 2,
34 BRW_HW_REG_TYPE_W = 3,
35 BRW_HW_REG_TYPE_F = 7,
36 GEN8_HW_REG_TYPE_UQ = 8,
37 GEN8_HW_REG_TYPE_Q = 9,
38
39 BRW_HW_REG_TYPE_UB = 4,
40 BRW_HW_REG_TYPE_B = 5,
41 GEN7_HW_REG_TYPE_DF = 6,
42 GEN8_HW_REG_TYPE_HF = 10,
43
44 GEN11_HW_REG_TYPE_UD = 0,
45 GEN11_HW_REG_TYPE_D = 1,
46 GEN11_HW_REG_TYPE_UW = 2,
47 GEN11_HW_REG_TYPE_W = 3,
48 GEN11_HW_REG_TYPE_UB = 4,
49 GEN11_HW_REG_TYPE_B = 5,
50 GEN11_HW_REG_TYPE_UQ = 6,
51 GEN11_HW_REG_TYPE_Q = 7,
52 GEN11_HW_REG_TYPE_HF = 8,
53 GEN11_HW_REG_TYPE_F = 9,
54 GEN11_HW_REG_TYPE_DF = 10,
55 GEN11_HW_REG_TYPE_NF = 11,
56 };
57
58 enum hw_imm_type {
59 BRW_HW_IMM_TYPE_UD = 0,
60 BRW_HW_IMM_TYPE_D = 1,
61 BRW_HW_IMM_TYPE_UW = 2,
62 BRW_HW_IMM_TYPE_W = 3,
63 BRW_HW_IMM_TYPE_F = 7,
64 GEN8_HW_IMM_TYPE_UQ = 8,
65 GEN8_HW_IMM_TYPE_Q = 9,
66
67 BRW_HW_IMM_TYPE_UV = 4,
68 BRW_HW_IMM_TYPE_VF = 5,
69 BRW_HW_IMM_TYPE_V = 6,
70 GEN8_HW_IMM_TYPE_DF = 10,
71 GEN8_HW_IMM_TYPE_HF = 11,
72
73 GEN11_HW_IMM_TYPE_UD = 0,
74 GEN11_HW_IMM_TYPE_D = 1,
75 GEN11_HW_IMM_TYPE_UW = 2,
76 GEN11_HW_IMM_TYPE_W = 3,
77 GEN11_HW_IMM_TYPE_UV = 4,
78 GEN11_HW_IMM_TYPE_V = 5,
79 GEN11_HW_IMM_TYPE_UQ = 6,
80 GEN11_HW_IMM_TYPE_Q = 7,
81 GEN11_HW_IMM_TYPE_HF = 8,
82 GEN11_HW_IMM_TYPE_F = 9,
83 GEN11_HW_IMM_TYPE_DF = 10,
84 GEN11_HW_IMM_TYPE_VF = 11,
85 };
86
87 #define GEN12_HW_REG_TYPE_UINT(n) (n)
88 #define GEN12_HW_REG_TYPE_SINT(n) (0x4 | (n))
89 #define GEN12_HW_REG_TYPE_FLOAT(n) (0x8 | (n))
90
91 static const struct hw_type {
92 enum hw_reg_type reg_type;
93 enum hw_imm_type imm_type;
94 } gen4_hw_type[] = {
95 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
96
97 [BRW_REGISTER_TYPE_DF] = { GEN7_HW_REG_TYPE_DF, GEN8_HW_IMM_TYPE_DF },
98 [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
99 [BRW_REGISTER_TYPE_HF] = { GEN8_HW_REG_TYPE_HF, GEN8_HW_IMM_TYPE_HF },
100 [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
101
102 [BRW_REGISTER_TYPE_Q] = { GEN8_HW_REG_TYPE_Q, GEN8_HW_IMM_TYPE_Q },
103 [BRW_REGISTER_TYPE_UQ] = { GEN8_HW_REG_TYPE_UQ, GEN8_HW_IMM_TYPE_UQ },
104 [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
105 [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
106 [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
107 [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
108 [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
109 [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
110 [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
111 [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV },
112 }, gen11_hw_type[] = {
113 [BRW_REGISTER_TYPE_NF] = { GEN11_HW_REG_TYPE_NF, INVALID },
114 [BRW_REGISTER_TYPE_DF] = { GEN11_HW_REG_TYPE_DF, GEN11_HW_IMM_TYPE_DF },
115 [BRW_REGISTER_TYPE_F] = { GEN11_HW_REG_TYPE_F, GEN11_HW_IMM_TYPE_F },
116 [BRW_REGISTER_TYPE_HF] = { GEN11_HW_REG_TYPE_HF, GEN11_HW_IMM_TYPE_HF },
117 [BRW_REGISTER_TYPE_VF] = { INVALID, GEN11_HW_IMM_TYPE_VF },
118
119 [BRW_REGISTER_TYPE_Q] = { GEN11_HW_REG_TYPE_Q, GEN11_HW_IMM_TYPE_Q },
120 [BRW_REGISTER_TYPE_UQ] = { GEN11_HW_REG_TYPE_UQ, GEN11_HW_IMM_TYPE_UQ },
121 [BRW_REGISTER_TYPE_D] = { GEN11_HW_REG_TYPE_D, GEN11_HW_IMM_TYPE_D },
122 [BRW_REGISTER_TYPE_UD] = { GEN11_HW_REG_TYPE_UD, GEN11_HW_IMM_TYPE_UD },
123 [BRW_REGISTER_TYPE_W] = { GEN11_HW_REG_TYPE_W, GEN11_HW_IMM_TYPE_W },
124 [BRW_REGISTER_TYPE_UW] = { GEN11_HW_REG_TYPE_UW, GEN11_HW_IMM_TYPE_UW },
125 [BRW_REGISTER_TYPE_B] = { GEN11_HW_REG_TYPE_B, INVALID },
126 [BRW_REGISTER_TYPE_UB] = { GEN11_HW_REG_TYPE_UB, INVALID },
127 [BRW_REGISTER_TYPE_V] = { INVALID, GEN11_HW_IMM_TYPE_V },
128 [BRW_REGISTER_TYPE_UV] = { INVALID, GEN11_HW_IMM_TYPE_UV },
129 }, gen12_hw_type[] = {
130 [BRW_REGISTER_TYPE_NF] = { INVALID, INVALID },
131 [BRW_REGISTER_TYPE_DF] = { GEN12_HW_REG_TYPE_FLOAT(3), GEN12_HW_REG_TYPE_FLOAT(3) },
132 [BRW_REGISTER_TYPE_F] = { GEN12_HW_REG_TYPE_FLOAT(2), GEN12_HW_REG_TYPE_FLOAT(2) },
133 [BRW_REGISTER_TYPE_HF] = { GEN12_HW_REG_TYPE_FLOAT(1), GEN12_HW_REG_TYPE_FLOAT(1) },
134 [BRW_REGISTER_TYPE_VF] = { INVALID, GEN12_HW_REG_TYPE_FLOAT(0) },
135
136 [BRW_REGISTER_TYPE_Q] = { GEN12_HW_REG_TYPE_SINT(3), GEN12_HW_REG_TYPE_SINT(3) },
137 [BRW_REGISTER_TYPE_UQ] = { GEN12_HW_REG_TYPE_UINT(3), GEN12_HW_REG_TYPE_UINT(3) },
138 [BRW_REGISTER_TYPE_D] = { GEN12_HW_REG_TYPE_SINT(2), GEN12_HW_REG_TYPE_SINT(2) },
139 [BRW_REGISTER_TYPE_UD] = { GEN12_HW_REG_TYPE_UINT(2), GEN12_HW_REG_TYPE_UINT(2) },
140 [BRW_REGISTER_TYPE_W] = { GEN12_HW_REG_TYPE_SINT(1), GEN12_HW_REG_TYPE_SINT(1) },
141 [BRW_REGISTER_TYPE_UW] = { GEN12_HW_REG_TYPE_UINT(1), GEN12_HW_REG_TYPE_UINT(1) },
142 [BRW_REGISTER_TYPE_B] = { GEN12_HW_REG_TYPE_SINT(0), INVALID },
143 [BRW_REGISTER_TYPE_UB] = { GEN12_HW_REG_TYPE_UINT(0), INVALID },
144 [BRW_REGISTER_TYPE_V] = { INVALID, GEN12_HW_REG_TYPE_SINT(0) },
145 [BRW_REGISTER_TYPE_UV] = { INVALID, GEN12_HW_REG_TYPE_UINT(0) },
146 };
147
148 /* SNB adds 3-src instructions (MAD and LRP) that only operate on floats, so
149 * the types were implied. IVB adds BFE and BFI2 that operate on doublewords
150 * and unsigned doublewords, so a new field is also available in the da3src
151 * struct (part of struct brw_instruction.bits1 in brw_structs.h) to select
152 * dst and shared-src types.
153 *
154 * CNL adds support for 3-src instructions in align1 mode, and with it support
155 * for most register types.
156 */
157 enum hw_3src_reg_type {
158 GEN7_3SRC_TYPE_F = 0,
159 GEN7_3SRC_TYPE_D = 1,
160 GEN7_3SRC_TYPE_UD = 2,
161 GEN7_3SRC_TYPE_DF = 3,
162 GEN8_3SRC_TYPE_HF = 4,
163
164 /** When ExecutionDatatype is 1: @{ */
165 GEN10_ALIGN1_3SRC_REG_TYPE_HF = 0b000,
166 GEN10_ALIGN1_3SRC_REG_TYPE_F = 0b001,
167 GEN10_ALIGN1_3SRC_REG_TYPE_DF = 0b010,
168 GEN11_ALIGN1_3SRC_REG_TYPE_NF = 0b011,
169 /** @} */
170
171 /** When ExecutionDatatype is 0: @{ */
172 GEN10_ALIGN1_3SRC_REG_TYPE_UD = 0b000,
173 GEN10_ALIGN1_3SRC_REG_TYPE_D = 0b001,
174 GEN10_ALIGN1_3SRC_REG_TYPE_UW = 0b010,
175 GEN10_ALIGN1_3SRC_REG_TYPE_W = 0b011,
176 GEN10_ALIGN1_3SRC_REG_TYPE_UB = 0b100,
177 GEN10_ALIGN1_3SRC_REG_TYPE_B = 0b101,
178 /** @} */
179 };
180
181 static const struct hw_3src_type {
182 enum hw_3src_reg_type reg_type;
183 enum gen10_align1_3src_exec_type exec_type;
184 } gen7_hw_3src_type[] = {
185 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
186
187 [BRW_REGISTER_TYPE_F] = { GEN7_3SRC_TYPE_F },
188 [BRW_REGISTER_TYPE_D] = { GEN7_3SRC_TYPE_D },
189 [BRW_REGISTER_TYPE_UD] = { GEN7_3SRC_TYPE_UD },
190 [BRW_REGISTER_TYPE_DF] = { GEN7_3SRC_TYPE_DF },
191 [BRW_REGISTER_TYPE_HF] = { GEN8_3SRC_TYPE_HF },
192 }, gen10_hw_3src_align1_type[] = {
193 #define E(x) BRW_ALIGN1_3SRC_EXEC_TYPE_##x
194 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
195
196 [BRW_REGISTER_TYPE_NF] = { GEN11_ALIGN1_3SRC_REG_TYPE_NF, E(FLOAT) },
197 [BRW_REGISTER_TYPE_DF] = { GEN10_ALIGN1_3SRC_REG_TYPE_DF, E(FLOAT) },
198 [BRW_REGISTER_TYPE_F] = { GEN10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) },
199 [BRW_REGISTER_TYPE_HF] = { GEN10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) },
200
201 [BRW_REGISTER_TYPE_D] = { GEN10_ALIGN1_3SRC_REG_TYPE_D, E(INT) },
202 [BRW_REGISTER_TYPE_UD] = { GEN10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) },
203 [BRW_REGISTER_TYPE_W] = { GEN10_ALIGN1_3SRC_REG_TYPE_W, E(INT) },
204 [BRW_REGISTER_TYPE_UW] = { GEN10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) },
205 [BRW_REGISTER_TYPE_B] = { GEN10_ALIGN1_3SRC_REG_TYPE_B, E(INT) },
206 [BRW_REGISTER_TYPE_UB] = { GEN10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) },
207 }, gen12_hw_3src_type[] = {
208 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
209
210 [BRW_REGISTER_TYPE_DF] = { GEN12_HW_REG_TYPE_UINT(3), E(FLOAT), },
211 [BRW_REGISTER_TYPE_F] = { GEN12_HW_REG_TYPE_UINT(2), E(FLOAT), },
212 [BRW_REGISTER_TYPE_HF] = { GEN12_HW_REG_TYPE_UINT(1), E(FLOAT), },
213
214 [BRW_REGISTER_TYPE_D] = { GEN12_HW_REG_TYPE_SINT(2), E(INT), },
215 [BRW_REGISTER_TYPE_UD] = { GEN12_HW_REG_TYPE_UINT(2), E(INT), },
216 [BRW_REGISTER_TYPE_W] = { GEN12_HW_REG_TYPE_SINT(1), E(INT), },
217 [BRW_REGISTER_TYPE_UW] = { GEN12_HW_REG_TYPE_UINT(1), E(INT), },
218 [BRW_REGISTER_TYPE_B] = { GEN12_HW_REG_TYPE_SINT(0), E(INT), },
219 [BRW_REGISTER_TYPE_UB] = { GEN12_HW_REG_TYPE_UINT(0), E(INT), },
220 #undef E
221 };
222
223 /**
224 * Convert a brw_reg_type enumeration value into the hardware representation.
225 *
226 * The hardware encoding may depend on whether the value is an immediate.
227 */
228 unsigned
229 brw_reg_type_to_hw_type(const struct gen_device_info *devinfo,
230 enum brw_reg_file file,
231 enum brw_reg_type type)
232 {
233 const struct hw_type *table;
234
235 if (devinfo->gen >= 12) {
236 assert(type < ARRAY_SIZE(gen12_hw_type));
237 table = gen12_hw_type;
238 } else if (devinfo->gen >= 11) {
239 assert(type < ARRAY_SIZE(gen11_hw_type));
240 table = gen11_hw_type;
241 } else {
242 assert(type < ARRAY_SIZE(gen4_hw_type));
243 table = gen4_hw_type;
244 }
245
246 assert(devinfo->gen == 11 || type != BRW_REGISTER_TYPE_NF);
247 assert(devinfo->has_64bit_float || type != BRW_REGISTER_TYPE_DF);
248 assert(devinfo->has_64bit_int ||
249 (type != BRW_REGISTER_TYPE_Q && type != BRW_REGISTER_TYPE_UQ));
250
251 if (file == BRW_IMMEDIATE_VALUE) {
252 assert(table[type].imm_type != (enum hw_imm_type)INVALID);
253 return table[type].imm_type;
254 } else {
255 assert(table[type].reg_type != (enum hw_reg_type)INVALID);
256 return table[type].reg_type;
257 }
258 }
259
260 /**
261 * Convert the hardware representation into a brw_reg_type enumeration value.
262 *
263 * The hardware encoding may depend on whether the value is an immediate.
264 */
265 enum brw_reg_type
266 brw_hw_type_to_reg_type(const struct gen_device_info *devinfo,
267 enum brw_reg_file file, unsigned hw_type)
268 {
269 const struct hw_type *table;
270
271 if (devinfo->gen >= 12) {
272 table = gen12_hw_type;
273 } else if (devinfo->gen >= 11) {
274 table = gen11_hw_type;
275 } else {
276 table = gen4_hw_type;
277 }
278
279 if (file == BRW_IMMEDIATE_VALUE) {
280 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
281 if (table[i].imm_type == (enum hw_imm_type)hw_type) {
282 return i;
283 }
284 }
285 } else {
286 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
287 if (table[i].reg_type == (enum hw_reg_type)hw_type) {
288 return i;
289 }
290 }
291 }
292 return INVALID_REG_TYPE;
293 }
294
295 /**
296 * Convert a brw_reg_type enumeration value into the hardware representation
297 * for a 3-src align16 instruction
298 */
299 unsigned
300 brw_reg_type_to_a16_hw_3src_type(const struct gen_device_info *devinfo,
301 enum brw_reg_type type)
302 {
303 assert(type < ARRAY_SIZE(gen7_hw_3src_type));
304 assert(devinfo->gen >= 8 || type != BRW_REGISTER_TYPE_HF);
305 assert(gen7_hw_3src_type[type].reg_type != (enum hw_3src_reg_type)INVALID);
306 return gen7_hw_3src_type[type].reg_type;
307 }
308
309 /**
310 * Convert a brw_reg_type enumeration value into the hardware representation
311 * for a 3-src align1 instruction
312 */
313 unsigned
314 brw_reg_type_to_a1_hw_3src_type(const struct gen_device_info *devinfo,
315 enum brw_reg_type type)
316 {
317 if (devinfo->gen >= 12) {
318 assert(type < ARRAY_SIZE(gen12_hw_3src_type));
319 assert(gen12_hw_3src_type[type].reg_type != (enum hw_3src_reg_type)INVALID);
320 return gen12_hw_3src_type[type].reg_type;
321 } else {
322 assert(type < ARRAY_SIZE(gen10_hw_3src_align1_type));
323 assert(gen10_hw_3src_align1_type[type].reg_type != (enum hw_3src_reg_type)INVALID);
324 return gen10_hw_3src_align1_type[type].reg_type;
325 }
326 }
327
328 /**
329 * Convert the hardware representation for a 3-src align16 instruction into a
330 * brw_reg_type enumeration value.
331 */
332 enum brw_reg_type
333 brw_a16_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo,
334 unsigned hw_type)
335 {
336 assert(devinfo->gen >= 8 || hw_type != GEN8_3SRC_TYPE_HF);
337 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
338 if (gen7_hw_3src_type[i].reg_type == hw_type) {
339 return i;
340 }
341 }
342 return INVALID_REG_TYPE;
343 }
344
345 /**
346 * Convert the hardware representation for a 3-src align1 instruction into a
347 * brw_reg_type enumeration value.
348 */
349 enum brw_reg_type
350 brw_a1_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo,
351 unsigned hw_type, unsigned exec_type)
352 {
353 const struct hw_3src_type *table = (devinfo->gen >= 12 ? gen12_hw_3src_type :
354 gen10_hw_3src_align1_type);
355
356 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
357 if (table[i].reg_type == hw_type &&
358 table[i].exec_type == exec_type) {
359 return i;
360 }
361 }
362 return INVALID_REG_TYPE;
363 }
364
365 /**
366 * Return the element size given a register type.
367 */
368 unsigned
369 brw_reg_type_to_size(enum brw_reg_type type)
370 {
371 static const unsigned type_size[] = {
372 [BRW_REGISTER_TYPE_NF] = 8,
373 [BRW_REGISTER_TYPE_DF] = 8,
374 [BRW_REGISTER_TYPE_F] = 4,
375 [BRW_REGISTER_TYPE_HF] = 2,
376 [BRW_REGISTER_TYPE_VF] = 4,
377
378 [BRW_REGISTER_TYPE_Q] = 8,
379 [BRW_REGISTER_TYPE_UQ] = 8,
380 [BRW_REGISTER_TYPE_D] = 4,
381 [BRW_REGISTER_TYPE_UD] = 4,
382 [BRW_REGISTER_TYPE_W] = 2,
383 [BRW_REGISTER_TYPE_UW] = 2,
384 [BRW_REGISTER_TYPE_B] = 1,
385 [BRW_REGISTER_TYPE_UB] = 1,
386 [BRW_REGISTER_TYPE_V] = 2,
387 [BRW_REGISTER_TYPE_UV] = 2,
388 };
389 return type_size[type];
390 }
391
392 /**
393 * Converts a BRW_REGISTER_TYPE_* enum to a short string (F, UD, and so on).
394 *
395 * This is different than reg_encoding from brw_disasm.c in that it operates
396 * on the abstract enum values, rather than the generation-specific encoding.
397 */
398 const char *
399 brw_reg_type_to_letters(enum brw_reg_type type)
400 {
401 static const char letters[][3] = {
402 [BRW_REGISTER_TYPE_NF] = "NF",
403 [BRW_REGISTER_TYPE_DF] = "DF",
404 [BRW_REGISTER_TYPE_F] = "F",
405 [BRW_REGISTER_TYPE_HF] = "HF",
406 [BRW_REGISTER_TYPE_VF] = "VF",
407
408 [BRW_REGISTER_TYPE_Q] = "Q",
409 [BRW_REGISTER_TYPE_UQ] = "UQ",
410 [BRW_REGISTER_TYPE_D] = "D",
411 [BRW_REGISTER_TYPE_UD] = "UD",
412 [BRW_REGISTER_TYPE_W] = "W",
413 [BRW_REGISTER_TYPE_UW] = "UW",
414 [BRW_REGISTER_TYPE_B] = "B",
415 [BRW_REGISTER_TYPE_UB] = "UB",
416 [BRW_REGISTER_TYPE_V] = "V",
417 [BRW_REGISTER_TYPE_UV] = "UV",
418 };
419 assert(type < ARRAY_SIZE(letters));
420 return letters[type];
421 }