intel/nir: Stop using nir_lower_vars_to_scratch
[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_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
98 [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
99
100 [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
101 [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
102 [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
103 [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
104 [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
105 [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
106 [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
107 }, gen6_hw_type[] = {
108 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
109
110 [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
111 [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
112
113 [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
114 [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
115 [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
116 [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
117 [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
118 [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
119 [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
120 [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV },
121 }, gen7_hw_type[] = {
122 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
123
124 [BRW_REGISTER_TYPE_DF] = { GEN7_HW_REG_TYPE_DF, INVALID },
125 [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
126 [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
127
128 [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
129 [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
130 [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
131 [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
132 [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
133 [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
134 [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
135 [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV },
136 }, gen8_hw_type[] = {
137 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
138
139 [BRW_REGISTER_TYPE_DF] = { GEN7_HW_REG_TYPE_DF, GEN8_HW_IMM_TYPE_DF },
140 [BRW_REGISTER_TYPE_F] = { BRW_HW_REG_TYPE_F, BRW_HW_IMM_TYPE_F },
141 [BRW_REGISTER_TYPE_HF] = { GEN8_HW_REG_TYPE_HF, GEN8_HW_IMM_TYPE_HF },
142 [BRW_REGISTER_TYPE_VF] = { INVALID, BRW_HW_IMM_TYPE_VF },
143
144 [BRW_REGISTER_TYPE_Q] = { GEN8_HW_REG_TYPE_Q, GEN8_HW_IMM_TYPE_Q },
145 [BRW_REGISTER_TYPE_UQ] = { GEN8_HW_REG_TYPE_UQ, GEN8_HW_IMM_TYPE_UQ },
146 [BRW_REGISTER_TYPE_D] = { BRW_HW_REG_TYPE_D, BRW_HW_IMM_TYPE_D },
147 [BRW_REGISTER_TYPE_UD] = { BRW_HW_REG_TYPE_UD, BRW_HW_IMM_TYPE_UD },
148 [BRW_REGISTER_TYPE_W] = { BRW_HW_REG_TYPE_W, BRW_HW_IMM_TYPE_W },
149 [BRW_REGISTER_TYPE_UW] = { BRW_HW_REG_TYPE_UW, BRW_HW_IMM_TYPE_UW },
150 [BRW_REGISTER_TYPE_B] = { BRW_HW_REG_TYPE_B, INVALID },
151 [BRW_REGISTER_TYPE_UB] = { BRW_HW_REG_TYPE_UB, INVALID },
152 [BRW_REGISTER_TYPE_V] = { INVALID, BRW_HW_IMM_TYPE_V },
153 [BRW_REGISTER_TYPE_UV] = { INVALID, BRW_HW_IMM_TYPE_UV },
154 }, gen11_hw_type[] = {
155 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
156
157 [BRW_REGISTER_TYPE_NF] = { GEN11_HW_REG_TYPE_NF, INVALID },
158 [BRW_REGISTER_TYPE_F] = { GEN11_HW_REG_TYPE_F, GEN11_HW_IMM_TYPE_F },
159 [BRW_REGISTER_TYPE_HF] = { GEN11_HW_REG_TYPE_HF, GEN11_HW_IMM_TYPE_HF },
160 [BRW_REGISTER_TYPE_VF] = { INVALID, GEN11_HW_IMM_TYPE_VF },
161
162 [BRW_REGISTER_TYPE_D] = { GEN11_HW_REG_TYPE_D, GEN11_HW_IMM_TYPE_D },
163 [BRW_REGISTER_TYPE_UD] = { GEN11_HW_REG_TYPE_UD, GEN11_HW_IMM_TYPE_UD },
164 [BRW_REGISTER_TYPE_W] = { GEN11_HW_REG_TYPE_W, GEN11_HW_IMM_TYPE_W },
165 [BRW_REGISTER_TYPE_UW] = { GEN11_HW_REG_TYPE_UW, GEN11_HW_IMM_TYPE_UW },
166 [BRW_REGISTER_TYPE_B] = { GEN11_HW_REG_TYPE_B, INVALID },
167 [BRW_REGISTER_TYPE_UB] = { GEN11_HW_REG_TYPE_UB, INVALID },
168 [BRW_REGISTER_TYPE_V] = { INVALID, GEN11_HW_IMM_TYPE_V },
169 [BRW_REGISTER_TYPE_UV] = { INVALID, GEN11_HW_IMM_TYPE_UV },
170 }, gen12_hw_type[] = {
171 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID, INVALID },
172
173 [BRW_REGISTER_TYPE_F] = { GEN12_HW_REG_TYPE_FLOAT(2), GEN12_HW_REG_TYPE_FLOAT(2) },
174 [BRW_REGISTER_TYPE_HF] = { GEN12_HW_REG_TYPE_FLOAT(1), GEN12_HW_REG_TYPE_FLOAT(1) },
175 [BRW_REGISTER_TYPE_VF] = { INVALID, GEN12_HW_REG_TYPE_FLOAT(0) },
176
177 [BRW_REGISTER_TYPE_D] = { GEN12_HW_REG_TYPE_SINT(2), GEN12_HW_REG_TYPE_SINT(2) },
178 [BRW_REGISTER_TYPE_UD] = { GEN12_HW_REG_TYPE_UINT(2), GEN12_HW_REG_TYPE_UINT(2) },
179 [BRW_REGISTER_TYPE_W] = { GEN12_HW_REG_TYPE_SINT(1), GEN12_HW_REG_TYPE_SINT(1) },
180 [BRW_REGISTER_TYPE_UW] = { GEN12_HW_REG_TYPE_UINT(1), GEN12_HW_REG_TYPE_UINT(1) },
181 [BRW_REGISTER_TYPE_B] = { GEN12_HW_REG_TYPE_SINT(0), INVALID },
182 [BRW_REGISTER_TYPE_UB] = { GEN12_HW_REG_TYPE_UINT(0), INVALID },
183 [BRW_REGISTER_TYPE_V] = { INVALID, GEN12_HW_REG_TYPE_SINT(0) },
184 [BRW_REGISTER_TYPE_UV] = { INVALID, GEN12_HW_REG_TYPE_UINT(0) },
185 };
186
187 /* SNB adds 3-src instructions (MAD and LRP) that only operate on floats, so
188 * the types were implied. IVB adds BFE and BFI2 that operate on doublewords
189 * and unsigned doublewords, so a new field is also available in the da3src
190 * struct (part of struct brw_instruction.bits1 in brw_structs.h) to select
191 * dst and shared-src types.
192 *
193 * CNL adds support for 3-src instructions in align1 mode, and with it support
194 * for most register types.
195 */
196 enum hw_3src_reg_type {
197 GEN7_3SRC_TYPE_F = 0,
198 GEN7_3SRC_TYPE_D = 1,
199 GEN7_3SRC_TYPE_UD = 2,
200 GEN7_3SRC_TYPE_DF = 3,
201 GEN8_3SRC_TYPE_HF = 4,
202
203 /** When ExecutionDatatype is 1: @{ */
204 GEN10_ALIGN1_3SRC_REG_TYPE_HF = 0b000,
205 GEN10_ALIGN1_3SRC_REG_TYPE_F = 0b001,
206 GEN10_ALIGN1_3SRC_REG_TYPE_DF = 0b010,
207 GEN11_ALIGN1_3SRC_REG_TYPE_NF = 0b011,
208 /** @} */
209
210 /** When ExecutionDatatype is 0: @{ */
211 GEN10_ALIGN1_3SRC_REG_TYPE_UD = 0b000,
212 GEN10_ALIGN1_3SRC_REG_TYPE_D = 0b001,
213 GEN10_ALIGN1_3SRC_REG_TYPE_UW = 0b010,
214 GEN10_ALIGN1_3SRC_REG_TYPE_W = 0b011,
215 GEN10_ALIGN1_3SRC_REG_TYPE_UB = 0b100,
216 GEN10_ALIGN1_3SRC_REG_TYPE_B = 0b101,
217 /** @} */
218 };
219
220 static const struct hw_3src_type {
221 enum hw_3src_reg_type reg_type;
222 enum gen10_align1_3src_exec_type exec_type;
223 } gen6_hw_3src_type[] = {
224 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
225
226 [BRW_REGISTER_TYPE_F] = { GEN7_3SRC_TYPE_F },
227 }, gen7_hw_3src_type[] = {
228 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
229
230 [BRW_REGISTER_TYPE_F] = { GEN7_3SRC_TYPE_F },
231 [BRW_REGISTER_TYPE_D] = { GEN7_3SRC_TYPE_D },
232 [BRW_REGISTER_TYPE_UD] = { GEN7_3SRC_TYPE_UD },
233 [BRW_REGISTER_TYPE_DF] = { GEN7_3SRC_TYPE_DF },
234 }, gen8_hw_3src_type[] = {
235 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
236
237 [BRW_REGISTER_TYPE_F] = { GEN7_3SRC_TYPE_F },
238 [BRW_REGISTER_TYPE_D] = { GEN7_3SRC_TYPE_D },
239 [BRW_REGISTER_TYPE_UD] = { GEN7_3SRC_TYPE_UD },
240 [BRW_REGISTER_TYPE_DF] = { GEN7_3SRC_TYPE_DF },
241 [BRW_REGISTER_TYPE_HF] = { GEN8_3SRC_TYPE_HF },
242 }, gen10_hw_3src_align1_type[] = {
243 #define E(x) BRW_ALIGN1_3SRC_EXEC_TYPE_##x
244 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
245
246 [BRW_REGISTER_TYPE_DF] = { GEN10_ALIGN1_3SRC_REG_TYPE_DF, E(FLOAT) },
247 [BRW_REGISTER_TYPE_F] = { GEN10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) },
248 [BRW_REGISTER_TYPE_HF] = { GEN10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) },
249
250 [BRW_REGISTER_TYPE_D] = { GEN10_ALIGN1_3SRC_REG_TYPE_D, E(INT) },
251 [BRW_REGISTER_TYPE_UD] = { GEN10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) },
252 [BRW_REGISTER_TYPE_W] = { GEN10_ALIGN1_3SRC_REG_TYPE_W, E(INT) },
253 [BRW_REGISTER_TYPE_UW] = { GEN10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) },
254 [BRW_REGISTER_TYPE_B] = { GEN10_ALIGN1_3SRC_REG_TYPE_B, E(INT) },
255 [BRW_REGISTER_TYPE_UB] = { GEN10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) },
256 }, gen11_hw_3src_type[] = {
257 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
258
259 [BRW_REGISTER_TYPE_NF] = { GEN11_ALIGN1_3SRC_REG_TYPE_NF, E(FLOAT) },
260 [BRW_REGISTER_TYPE_F] = { GEN10_ALIGN1_3SRC_REG_TYPE_F, E(FLOAT) },
261 [BRW_REGISTER_TYPE_HF] = { GEN10_ALIGN1_3SRC_REG_TYPE_HF, E(FLOAT) },
262
263 [BRW_REGISTER_TYPE_D] = { GEN10_ALIGN1_3SRC_REG_TYPE_D, E(INT) },
264 [BRW_REGISTER_TYPE_UD] = { GEN10_ALIGN1_3SRC_REG_TYPE_UD, E(INT) },
265 [BRW_REGISTER_TYPE_W] = { GEN10_ALIGN1_3SRC_REG_TYPE_W, E(INT) },
266 [BRW_REGISTER_TYPE_UW] = { GEN10_ALIGN1_3SRC_REG_TYPE_UW, E(INT) },
267 [BRW_REGISTER_TYPE_B] = { GEN10_ALIGN1_3SRC_REG_TYPE_B, E(INT) },
268 [BRW_REGISTER_TYPE_UB] = { GEN10_ALIGN1_3SRC_REG_TYPE_UB, E(INT) },
269 }, gen12_hw_3src_type[] = {
270 [0 ... BRW_REGISTER_TYPE_LAST] = { INVALID },
271
272 [BRW_REGISTER_TYPE_F] = { GEN12_HW_REG_TYPE_UINT(2), E(FLOAT), },
273 [BRW_REGISTER_TYPE_HF] = { GEN12_HW_REG_TYPE_UINT(1), E(FLOAT), },
274
275 [BRW_REGISTER_TYPE_D] = { GEN12_HW_REG_TYPE_SINT(2), E(INT), },
276 [BRW_REGISTER_TYPE_UD] = { GEN12_HW_REG_TYPE_UINT(2), E(INT), },
277 [BRW_REGISTER_TYPE_W] = { GEN12_HW_REG_TYPE_SINT(1), E(INT), },
278 [BRW_REGISTER_TYPE_UW] = { GEN12_HW_REG_TYPE_UINT(1), E(INT), },
279 [BRW_REGISTER_TYPE_B] = { GEN12_HW_REG_TYPE_SINT(0), E(INT), },
280 [BRW_REGISTER_TYPE_UB] = { GEN12_HW_REG_TYPE_UINT(0), E(INT), },
281 #undef E
282 };
283
284 /**
285 * Convert a brw_reg_type enumeration value into the hardware representation.
286 *
287 * The hardware encoding may depend on whether the value is an immediate.
288 */
289 unsigned
290 brw_reg_type_to_hw_type(const struct gen_device_info *devinfo,
291 enum brw_reg_file file,
292 enum brw_reg_type type)
293 {
294 const struct hw_type *table;
295
296 if (devinfo->gen >= 12) {
297 assert(type < ARRAY_SIZE(gen12_hw_type));
298 table = gen12_hw_type;
299 } else if (devinfo->gen >= 11) {
300 assert(type < ARRAY_SIZE(gen11_hw_type));
301 table = gen11_hw_type;
302 } else if (devinfo->gen >= 8) {
303 assert(type < ARRAY_SIZE(gen8_hw_type));
304 table = gen8_hw_type;
305 } else if (devinfo->gen >= 7) {
306 assert(type < ARRAY_SIZE(gen7_hw_type));
307 table = gen7_hw_type;
308 } else if (devinfo->gen >= 6) {
309 assert(type < ARRAY_SIZE(gen6_hw_type));
310 table = gen6_hw_type;
311 } else {
312 assert(type < ARRAY_SIZE(gen4_hw_type));
313 table = gen4_hw_type;
314 }
315
316 if (file == BRW_IMMEDIATE_VALUE) {
317 assert(table[type].imm_type != (enum hw_imm_type)INVALID);
318 return table[type].imm_type;
319 } else {
320 assert(table[type].reg_type != (enum hw_reg_type)INVALID);
321 return table[type].reg_type;
322 }
323 }
324
325 /**
326 * Convert the hardware representation into a brw_reg_type enumeration value.
327 *
328 * The hardware encoding may depend on whether the value is an immediate.
329 */
330 enum brw_reg_type
331 brw_hw_type_to_reg_type(const struct gen_device_info *devinfo,
332 enum brw_reg_file file, unsigned hw_type)
333 {
334 const struct hw_type *table;
335
336 if (devinfo->gen >= 12) {
337 table = gen12_hw_type;
338 } else if (devinfo->gen >= 11) {
339 table = gen11_hw_type;
340 } else if (devinfo->gen >= 8) {
341 table = gen8_hw_type;
342 } else if (devinfo->gen >= 7) {
343 table = gen7_hw_type;
344 } else if (devinfo->gen >= 6) {
345 table = gen6_hw_type;
346 } else {
347 table = gen4_hw_type;
348 }
349
350 if (file == BRW_IMMEDIATE_VALUE) {
351 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
352 if (table[i].imm_type == (enum hw_imm_type)hw_type) {
353 return i;
354 }
355 }
356 } else {
357 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
358 if (table[i].reg_type == (enum hw_reg_type)hw_type) {
359 return i;
360 }
361 }
362 }
363 return INVALID_REG_TYPE;
364 }
365
366 /**
367 * Convert a brw_reg_type enumeration value into the hardware representation
368 * for a 3-src align16 instruction
369 */
370 unsigned
371 brw_reg_type_to_a16_hw_3src_type(const struct gen_device_info *devinfo,
372 enum brw_reg_type type)
373 {
374 const struct hw_3src_type *table;
375
376 if (devinfo->gen >= 8) {
377 assert(type < ARRAY_SIZE(gen8_hw_3src_type));
378 table = gen8_hw_3src_type;
379 } else if (devinfo->gen >= 7) {
380 assert(type < ARRAY_SIZE(gen7_hw_3src_type));
381 table = gen7_hw_3src_type;
382 } else {
383 assert(type < ARRAY_SIZE(gen6_hw_3src_type));
384 table = gen6_hw_3src_type;
385 }
386
387 assert(table[type].reg_type != (enum hw_3src_reg_type)INVALID);
388 return table[type].reg_type;
389 }
390
391 /**
392 * Convert a brw_reg_type enumeration value into the hardware representation
393 * for a 3-src align1 instruction
394 */
395 unsigned
396 brw_reg_type_to_a1_hw_3src_type(const struct gen_device_info *devinfo,
397 enum brw_reg_type type)
398 {
399 if (devinfo->gen >= 12) {
400 assert(type < ARRAY_SIZE(gen12_hw_3src_type));
401 return gen12_hw_3src_type[type].reg_type;
402 } else if (devinfo->gen >= 11) {
403 assert(type < ARRAY_SIZE(gen11_hw_3src_type));
404 return gen11_hw_3src_type[type].reg_type;
405 } else {
406 assert(type < ARRAY_SIZE(gen10_hw_3src_align1_type));
407 return gen10_hw_3src_align1_type[type].reg_type;
408 }
409 }
410
411 /**
412 * Convert the hardware representation for a 3-src align16 instruction into a
413 * brw_reg_type enumeration value.
414 */
415 enum brw_reg_type
416 brw_a16_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo,
417 unsigned hw_type)
418 {
419 const struct hw_3src_type *table = NULL;
420
421 if (devinfo->gen >= 8) {
422 table = gen8_hw_3src_type;
423 } else if (devinfo->gen >= 7) {
424 table = gen7_hw_3src_type;
425 } else if (devinfo->gen >= 6) {
426 table = gen6_hw_3src_type;
427 }
428
429 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
430 if (table[i].reg_type == hw_type) {
431 return i;
432 }
433 }
434 return INVALID_REG_TYPE;
435 }
436
437 /**
438 * Convert the hardware representation for a 3-src align1 instruction into a
439 * brw_reg_type enumeration value.
440 */
441 enum brw_reg_type
442 brw_a1_hw_3src_type_to_reg_type(const struct gen_device_info *devinfo,
443 unsigned hw_type, unsigned exec_type)
444 {
445 const struct hw_3src_type *table = (devinfo->gen >= 12 ? gen12_hw_3src_type :
446 devinfo->gen >= 11 ? gen11_hw_3src_type :
447 gen10_hw_3src_align1_type);
448
449 for (enum brw_reg_type i = 0; i <= BRW_REGISTER_TYPE_LAST; i++) {
450 if (table[i].reg_type == hw_type &&
451 table[i].exec_type == exec_type) {
452 return i;
453 }
454 }
455 return INVALID_REG_TYPE;
456 }
457
458 /**
459 * Return the element size given a register type.
460 */
461 unsigned
462 brw_reg_type_to_size(enum brw_reg_type type)
463 {
464 static const unsigned type_size[] = {
465 [BRW_REGISTER_TYPE_NF] = 8,
466 [BRW_REGISTER_TYPE_DF] = 8,
467 [BRW_REGISTER_TYPE_F] = 4,
468 [BRW_REGISTER_TYPE_HF] = 2,
469 [BRW_REGISTER_TYPE_VF] = 4,
470
471 [BRW_REGISTER_TYPE_Q] = 8,
472 [BRW_REGISTER_TYPE_UQ] = 8,
473 [BRW_REGISTER_TYPE_D] = 4,
474 [BRW_REGISTER_TYPE_UD] = 4,
475 [BRW_REGISTER_TYPE_W] = 2,
476 [BRW_REGISTER_TYPE_UW] = 2,
477 [BRW_REGISTER_TYPE_B] = 1,
478 [BRW_REGISTER_TYPE_UB] = 1,
479 [BRW_REGISTER_TYPE_V] = 2,
480 [BRW_REGISTER_TYPE_UV] = 2,
481 };
482 if (type >= ARRAY_SIZE(type_size))
483 return -1;
484
485 return type_size[type];
486 }
487
488 /**
489 * Converts a BRW_REGISTER_TYPE_* enum to a short string (F, UD, and so on).
490 *
491 * This is different than reg_encoding from brw_disasm.c in that it operates
492 * on the abstract enum values, rather than the generation-specific encoding.
493 */
494 const char *
495 brw_reg_type_to_letters(enum brw_reg_type type)
496 {
497 static const char letters[][3] = {
498 [BRW_REGISTER_TYPE_NF] = "NF",
499 [BRW_REGISTER_TYPE_DF] = "DF",
500 [BRW_REGISTER_TYPE_F] = "F",
501 [BRW_REGISTER_TYPE_HF] = "HF",
502 [BRW_REGISTER_TYPE_VF] = "VF",
503
504 [BRW_REGISTER_TYPE_Q] = "Q",
505 [BRW_REGISTER_TYPE_UQ] = "UQ",
506 [BRW_REGISTER_TYPE_D] = "D",
507 [BRW_REGISTER_TYPE_UD] = "UD",
508 [BRW_REGISTER_TYPE_W] = "W",
509 [BRW_REGISTER_TYPE_UW] = "UW",
510 [BRW_REGISTER_TYPE_B] = "B",
511 [BRW_REGISTER_TYPE_UB] = "UB",
512 [BRW_REGISTER_TYPE_V] = "V",
513 [BRW_REGISTER_TYPE_UV] = "UV",
514 };
515 if (type >= ARRAY_SIZE(letters))
516 return "INVALID";
517
518 assert(type < ARRAY_SIZE(letters));
519 return letters[type];
520 }