1 /*
2 * Copyright © 2014 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 /**
25 * @file
26 *
27 * A representation of i965 EU assembly instructions, with helper methods to
28 * get and set various fields. This is the actual hardware format.
29 */
30
31 #pragma once
32
33 #include <assert.h>
34 #include <stdint.h>
35
36 #include "brw_eu_defines.h"
37 #include "brw_isa_info.h"
38 #include "brw_reg_type.h"
39 #include "dev/intel_device_info.h"
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 /* brw_context.h has a forward declaration of brw_eu_inst, so name the struct. */
46 typedef struct brw_eu_inst {
47 uint64_t data[2];
48 } brw_eu_inst;
49
50 static inline uint64_t brw_eu_inst_bits(const brw_eu_inst *inst,
51 unsigned high, unsigned low);
52 static inline void brw_eu_inst_set_bits(brw_eu_inst *inst,
53 unsigned high, unsigned low,
54 uint64_t value);
55
56 #define FC(name, hi9, lo9, hi12, lo12, assertions) \
57 static inline void \
58 brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
59 brw_eu_inst *inst, uint64_t v) \
60 { \
61 assert(assertions); \
62 if (devinfo->ver >= 12) \
63 brw_eu_inst_set_bits(inst, hi12, lo12, v); \
64 else \
65 brw_eu_inst_set_bits(inst, hi9, lo9, v); \
66 } \
67 static inline uint64_t \
68 brw_eu_inst_##name(const struct intel_device_info *devinfo, \
69 const brw_eu_inst *inst) \
70 { \
71 assert(assertions); \
72 if (devinfo->ver >= 12) \
73 return brw_eu_inst_bits(inst, hi12, lo12); \
74 else \
75 return brw_eu_inst_bits(inst, hi9, lo9); \
76 }
77
78 /* A simple macro for fields which stay in the same place on all generations,
79 * except for Gfx12!
80 */
81 #define F(name, hi9, lo9, hi12, lo12) FC(name, hi9, lo9, hi12, lo12, true)
82
83 /* A simple macro for fields which stay in the same place on all generations,
84 * except for Gfx12 and Gfx20.
85 */
86 #define F20(name, hi9, lo9, hi12, lo12, hi20, lo20) \
87 static inline void \
88 brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
89 brw_eu_inst *inst, uint64_t v) \
90 { \
91 if (devinfo->ver >= 20) \
92 brw_eu_inst_set_bits(inst, hi20, lo20, v); \
93 else if (devinfo->ver >= 12) \
94 brw_eu_inst_set_bits(inst, hi12, lo12, v); \
95 else \
96 brw_eu_inst_set_bits(inst, hi9, lo9, v); \
97 } \
98 static inline uint64_t \
99 brw_eu_inst_##name(const struct intel_device_info *devinfo, \
100 const brw_eu_inst *inst) \
101 { \
102 if (devinfo->ver >= 20) \
103 return brw_eu_inst_bits(inst, hi20, lo20); \
104 else if (devinfo->ver >= 12) \
105 return brw_eu_inst_bits(inst, hi12, lo12); \
106 else \
107 return brw_eu_inst_bits(inst, hi9, lo9); \
108 }
109
110 #define FV20(name, hi9, lo9, hi12, lo12, hi20, lo20) \
111 static inline void \
112 brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
113 brw_eu_inst *inst, uint64_t v) \
114 { \
115 if (devinfo->ver >= 20) \
116 brw_eu_inst_set_bits(inst, hi20, lo20, v & 0x7); \
117 else if (devinfo->ver >= 12) \
118 brw_eu_inst_set_bits(inst, hi12, lo12, v); \
119 else \
120 brw_eu_inst_set_bits(inst, hi9, lo9, v); \
121 } \
122 static inline uint64_t \
123 brw_eu_inst_##name(const struct intel_device_info *devinfo, \
124 const brw_eu_inst *inst) \
125 { \
126 if (devinfo->ver >= 20) \
127 return brw_eu_inst_bits(inst, hi20, lo20) == 0x7 ? 0xF : \
128 brw_eu_inst_bits(inst, hi20, lo20); \
129 else if (devinfo->ver >= 12) \
130 return brw_eu_inst_bits(inst, hi12, lo12); \
131 else \
132 return brw_eu_inst_bits(inst, hi9, lo9); \
133 }
134
135 #define FD20(name, hi9, lo9, hi12, lo12, hi20, lo20, zero20) \
136 static inline void \
137 brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
138 brw_eu_inst *inst, uint64_t v) \
139 { \
140 if (devinfo->ver >= 20) { \
141 brw_eu_inst_set_bits(inst, hi20, lo20, v >> 1); \
142 if (zero20 == -1) \
143 assert((v & 1) == 0); \
144 else \
145 brw_eu_inst_set_bits(inst, zero20, zero20, v & 1); \
146 } else if (devinfo->ver >= 12) \
147 brw_eu_inst_set_bits(inst, hi12, lo12, v); \
148 else \
149 brw_eu_inst_set_bits(inst, hi9, lo9, v); \
150 } \
151 static inline uint64_t \
152 brw_eu_inst_##name(const struct intel_device_info *devinfo, \
153 const brw_eu_inst *inst) \
154 { \
155 if (devinfo->ver >= 20) \
156 return (brw_eu_inst_bits(inst, hi20, lo20) << 1) | \
157 (zero20 == -1 ? 0 : \
158 brw_eu_inst_bits(inst, zero20, zero20)); \
159 else if (devinfo->ver >= 12) \
160 return brw_eu_inst_bits(inst, hi12, lo12); \
161 else \
162 return brw_eu_inst_bits(inst, hi9, lo9); \
163 }
164
165 /* Macro for fields that gained extra discontiguous MSBs in Gfx12 (specified
166 * by hi12ex-lo12ex).
167 */
168 #define FFDC(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12, assertions) \
169 static inline void \
170 brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
171 brw_eu_inst *inst, uint64_t value) \
172 { \
173 assert(assertions); \
174 if (devinfo->ver >= 12) { \
175 const unsigned k = hi12 - lo12 + 1; \
176 if (hi12ex != -1 && lo12ex != -1) \
177 brw_eu_inst_set_bits(inst, hi12ex, lo12ex, value >> k); \
178 brw_eu_inst_set_bits(inst, hi12, lo12, value & ((1ull << k) - 1)); \
179 } else { \
180 brw_eu_inst_set_bits(inst, hi9, lo9, value); \
181 } \
182 } \
183 static inline uint64_t \
184 brw_eu_inst_##name(const struct intel_device_info *devinfo, \
185 const brw_eu_inst *inst) \
186 { \
187 assert(assertions); \
188 if (devinfo->ver >= 12) { \
189 const unsigned k = hi12 - lo12 + 1; \
190 return (hi12ex == -1 || lo12ex == -1 ? 0 : \
191 brw_eu_inst_bits(inst, hi12ex, lo12ex) << k) | \
192 brw_eu_inst_bits(inst, hi12, lo12); \
193 } else { \
194 return brw_eu_inst_bits(inst, hi9, lo9); \
195 } \
196 }
197
198 #define FD(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12) \
199 FFDC(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12, true)
200
201 /* Macro for fields that didn't move across generations until Gfx12, and then
202 * gained extra discontiguous bits.
203 */
204 #define FDC(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12, assertions) \
205 FFDC(name, hi9, lo9, hi12ex, lo12ex, hi12, lo12, assertions)
206
207 static inline uint64_t
brw_reg_file_to_hw_reg_file(enum brw_reg_file file)208 brw_reg_file_to_hw_reg_file(enum brw_reg_file file)
209 {
210 switch (file) {
211 case ARF: return 0x0;
212 case FIXED_GRF: return 0x1;
213 default: /* Fallthrough. */
214 case IMM: return 0x3;
215 }
216 }
217
218 static inline enum brw_reg_file
hw_reg_file_to_brw_reg_file(uint64_t v)219 hw_reg_file_to_brw_reg_file(uint64_t v)
220 {
221 switch (v) {
222 case 0x0: return ARF;
223 case 0x1: return FIXED_GRF;
224 default: return IMM;
225 }
226 }
227
228 /* Macro for storing register file field. See variant FF below for no
229 * assertions.
230 *
231 * In Gfx12+, either a single bit is available (ARF or GRF) or two bits are
232 * available. In that case the register file is stored as the variable length
233 * combination of an IsImm (hi12) bit and an additional file (lo12) bit.
234 *
235 * For some instructions in Gfx11, the encoding uses 0 for GRF, and 1 for
236 * either ARF (for accumulator) or IMM.
237 */
238 #define FFC(name, hi9, lo9, hi12, lo12, assertions, ...) \
239 static inline void \
240 brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
241 brw_eu_inst *inst, enum brw_reg_file file) \
242 { \
243 assert(assertions); \
244 const struct { \
245 bool _; /* Exists to avoid empty initializer. */ \
246 bool grf_or_imm; \
247 bool grf_or_acc; \
248 } args = { ._ = false, __VA_ARGS__ }; \
249 uint64_t value = brw_reg_file_to_hw_reg_file(file); \
250 if (devinfo->ver < 12) { \
251 if (devinfo->ver == 11 && args.grf_or_imm) { \
252 assert(file == FIXED_GRF || file == IMM); \
253 value = file == FIXED_GRF ? 0 : 1; \
254 } else if (devinfo->ver == 11 && args.grf_or_acc) { \
255 assert(file == FIXED_GRF || file == ARF); \
256 value = file == FIXED_GRF ? 0 : 1; \
257 } \
258 brw_eu_inst_set_bits(inst, hi9, lo9, value); \
259 } else if (hi12 == lo12) { \
260 brw_eu_inst_set_bits(inst, hi12, lo12, value); \
261 } else { \
262 brw_eu_inst_set_bits(inst, hi12, hi12, value >> 1); \
263 if ((value >> 1) == 0) \
264 brw_eu_inst_set_bits(inst, lo12, lo12, value & 1); \
265 } \
266 } \
267 static inline uint64_t \
268 brw_eu_inst_##name(const struct intel_device_info *devinfo, \
269 const brw_eu_inst *inst) \
270 { \
271 assert(assertions); \
272 const struct { \
273 bool _; /* Exists to avoid empty initializer. */ \
274 bool grf_or_imm; \
275 bool grf_or_acc; \
276 } args = { ._ = false, __VA_ARGS__ }; \
277 uint64_t value; \
278 if (devinfo->ver < 12) { \
279 value = brw_eu_inst_bits(inst, hi9, lo9); \
280 if (devinfo->ver == 11 && args.grf_or_imm) \
281 return value ? IMM : FIXED_GRF; \
282 else if (devinfo->ver == 11 && args.grf_or_acc) \
283 return value ? ARF : FIXED_GRF; \
284 } else if (hi12 == lo12) { \
285 value = brw_eu_inst_bits(inst, hi12, lo12); \
286 } else { \
287 value = (brw_eu_inst_bits(inst, hi12, hi12) << 1) | \
288 (brw_eu_inst_bits(inst, hi12, hi12) == 0 ? \
289 brw_eu_inst_bits(inst, lo12, lo12) : 1); \
290 } \
291 return hw_reg_file_to_brw_reg_file(value); \
292 }
293
294 #define FF(name, hi9, lo9, hi12, lo12, ...) FFC(name, hi9, lo9, hi12, lo12, true, __VA_ARGS__)
295
296 /* Macro for fields that become a constant in Gfx12+ not actually represented
297 * in the instruction.
298 */
299 #define FK(name, hi9, lo9, const12) \
300 static inline void \
301 brw_eu_inst_set_##name(const struct intel_device_info *devinfo, \
302 brw_eu_inst *inst, uint64_t v) \
303 { \
304 if (devinfo->ver >= 12) \
305 assert(v == (const12)); \
306 else \
307 brw_eu_inst_set_bits(inst, hi9, lo9, v); \
308 } \
309 static inline uint64_t \
310 brw_eu_inst_##name(const struct intel_device_info *devinfo, \
311 const brw_eu_inst *inst) \
312 { \
313 if (devinfo->ver >= 12) \
314 return (const12); \
315 else \
316 return brw_eu_inst_bits(inst, hi9, lo9); \
317 }
318
319 FV20(src1_vstride, /* 9+ */ 120, 117, /* 12+ */ 119, 116, /* 20+ */ 118, 116)
320 F(src1_width, /* 9+ */ 116, 114, /* 12+ */ 115, 113)
321 F(src1_da16_swiz_w, /* 9+ */ 115, 114, /* 12+ */ -1, -1)
322 F(src1_da16_swiz_z, /* 9+ */ 113, 112, /* 12+ */ -1, -1)
323 F(src1_hstride, /* 9+ */ 113, 112, /* 12+ */ 97, 96)
324 F(src1_address_mode, /* 9+ */ 111, 111, /* 12+ */ 112, 112)
325 /** Src1.SrcMod @{ */
326 F(src1_negate, /* 9+ */ 110, 110, /* 12+ */ 121, 121)
327 F(src1_abs, /* 9+ */ 109, 109, /* 12+ */ 120, 120)
328 /** @} */
329 F(src1_ia_subreg_nr, /* 9+ */ 108, 105, /* 12+ */ 111, 108)
330 F(src1_da_reg_nr, /* 9+ */ 108, 101, /* 12+ */ 111, 104)
331 F(src1_da16_subreg_nr, /* 9+ */ 100, 100, /* 12+ */ -1, -1)
332 FD20(src1_da1_subreg_nr, /* 9+ */ 100, 96, /* 12+ */ 103, 99, /* 20+ */ 103, 99, -1)
333 F(src1_da16_swiz_y, /* 9+ */ 99, 98, /* 12+ */ -1, -1)
334 F(src1_da16_swiz_x, /* 9+ */ 97, 96, /* 12+ */ -1, -1)
335 F(src1_reg_hw_type, /* 9+ */ 94, 91, /* 12+ */ 91, 88)
336 FF(src1_reg_file, /* 9+ */ 90, 89, /* 12+ */ 47, 98)
337 F(src1_is_imm, /* 9+ */ -1, -1, /* 12+ */ 47, 47)
338 FV20(src0_vstride, /* 9+ */ 88, 85, /* 12+ */ 87, 84, /* 20+ */ 86, 84)
339 F(src0_width, /* 9+ */ 84, 82, /* 12+ */ 83, 81)
340 F(src0_da16_swiz_w, /* 9+ */ 83, 82, /* 12+ */ -1, -1)
341 F(src0_da16_swiz_z, /* 9+ */ 81, 80, /* 12+ */ -1, -1)
342 F(src0_hstride, /* 9+ */ 81, 80, /* 12+ */ 65, 64)
343 F(src0_address_mode, /* 9+ */ 79, 79, /* 12+ */ 80, 80)
344 /** Src0.SrcMod @{ */
345 F(src0_negate, /* 9+ */ 78, 78, /* 12+ */ 45, 45)
346 F(src0_abs, /* 9+ */ 77, 77, /* 12+ */ 44, 44)
347 /** @} */
348 F(src0_ia_subreg_nr, /* 9+ */ 76, 73, /* 12+ */ 79, 76)
349 F(src0_da_reg_nr, /* 9+ */ 76, 69, /* 12+ */ 79, 72)
350 F(src0_da16_subreg_nr, /* 9+ */ 68, 68, /* 12+ */ -1, -1)
351 FD20(src0_da1_subreg_nr, /* 9+ */ 68, 64, /* 12+ */ 71, 67, /* 20+ */ 71, 67, 87)
352 F(src0_da16_swiz_y, /* 9+ */ 67, 66, /* 12+ */ -1, -1)
353 F(src0_da16_swiz_x, /* 9+ */ 65, 64, /* 12+ */ -1, -1)
354 F(dst_address_mode, /* 9+ */ 63, 63, /* 12+ */ 35, 35)
355 F(dst_hstride, /* 9+ */ 62, 61, /* 12+ */ 49, 48)
356 F(dst_ia_subreg_nr, /* 9+ */ 60, 57, /* 12+ */ 63, 60)
357 F(dst_da_reg_nr, /* 9+ */ 60, 53, /* 12+ */ 63, 56)
358 F(dst_da16_subreg_nr, /* 9+ */ 52, 52, /* 12+ */ -1, -1)
359 FD20(dst_da1_subreg_nr, /* 9+ */ 52, 48, /* 12+ */ 55, 51, /* 20+ */ 55, 51, 33)
360 F(da16_writemask, /* 9+ */ 51, 48, /* 12+ */ -1, -1) /* Dst.ChanEn */
361 F(src0_reg_hw_type, /* 9+ */ 46, 43, /* 12+ */ 43, 40)
362 FF(src0_reg_file, /* 9+ */ 42, 41, /* 12+ */ 46, 66)
363 F(src0_is_imm, /* 9+ */ -1, -1, /* 12+ */ 46, 46)
364 F(dst_reg_hw_type, /* 9+ */ 40, 37, /* 12+ */ 39, 36)
365 FF(dst_reg_file, /* 9+ */ 36, 35, /* 12+ */ 50, 50)
366 F(mask_control, /* 9+ */ 34, 34, /* 12+ */ 31, 31)
367 F20(flag_reg_nr, /* 9+ */ 33, 33, /* 12+ */ 23, 23, /* 20+ */ 23, 22)
368 F20(flag_subreg_nr, /* 9+ */ 32, 32, /* 12+ */ 22, 22, /* 20+ */ 21, 21)
369 F(saturate, /* 9+ */ 31, 31, /* 12+ */ 34, 34)
370 F(debug_control, /* 9+ */ 30, 30, /* 12+ */ 30, 30)
371 F(cmpt_control, /* 9+ */ 29, 29, /* 12+ */ 29, 29)
372 F(branch_control, /* 9+ */ 28, 28, /* 12+ */ 33, 33)
373 FC(acc_wr_control, /* 9+ */ 28, 28, /* 12+ */ 33, 33, devinfo->ver < 20)
374 F(cond_modifier, /* 9+ */ 27, 24, /* 12+ */ 95, 92)
375 F(math_function, /* 9+ */ 27, 24, /* 12+ */ 95, 92)
376 F20(exec_size, /* 9+ */ 23, 21, /* 12+ */ 18, 16, /* 20+ */ 20, 18)
377 F(pred_inv, /* 9+ */ 20, 20, /* 12+ */ 28, 28)
378 F20(pred_control, /* 9+ */ 19, 16, /* 12+ */ 27, 24, /* 20+ */ 27, 26)
379 F(thread_control, /* 9+ */ 15, 14, /* 12+ */ -1, -1)
380 F(atomic_control, /* 9+ */ -1, -1, /* 12+ */ 32, 32)
381 F20(qtr_control, /* 9+ */ 13, 12, /* 12+ */ 21, 20, /* 20+ */ 25, 24)
382 F20(nib_control, /* 9+ */ 11, 11, /* 12+ */ 19, 19, /* 20+ */ -1, -1)
383 F(no_dd_check, /* 9+ */ 10, 10, /* 12+ */ -1, -1)
384 F(no_dd_clear, /* 9+ */ 9, 9, /* 12+ */ -1, -1)
385 F20(swsb, /* 9+ */ -1, -1, /* 12+ */ 15, 8, /* 20+ */ 17, 8)
386 FK(access_mode, /* 9+ */ 8, 8, /* 12+ */ BRW_ALIGN_1)
387 /* Bit 7 is Reserved (for future Opcode expansion) */
388 F(hw_opcode, /* 9+ */ 6, 0, /* 12+ */ 6, 0)
389
390 /**
391 * Three-source instructions:
392 * @{
393 */
394 F(3src_src2_reg_nr, /* 9+ */ 125, 118, /* 12+ */ 127, 120) /* same in align1 */
395 F(3src_a16_src2_swizzle, /* 9+ */ 114, 107, /* 12+ */ -1, -1)
396 F(3src_a16_src2_rep_ctrl, /* 9+ */ 106, 106, /* 12+ */ -1, -1)
397 F(3src_src1_reg_nr, /* 9+ */ 104, 97, /* 12+ */ 111, 104) /* same in align1 */
398 F(3src_a16_src1_swizzle, /* 9+ */ 93, 86, /* 12+ */ -1, -1)
399 F(3src_a16_src1_rep_ctrl, /* 9+ */ 85, 85, /* 12+ */ -1, -1)
400 F(3src_src0_reg_nr, /* 9+ */ 83, 76, /* 12+ */ 79, 72) /* same in align1 */
401 F(3src_a16_src0_swizzle, /* 9+ */ 72, 65, /* 12+ */ -1, -1)
402 F(3src_a16_src0_rep_ctrl, /* 9+ */ 64, 64, /* 12+ */ -1, -1)
403 F(3src_dst_reg_nr, /* 9+ */ 63, 56, /* 12+ */ 63, 56) /* same in align1 */
404 F(3src_a16_dst_subreg_nr, /* 9+ */ 55, 53, /* 12+ */ -1, -1)
405 F(3src_a16_dst_writemask, /* 9+ */ 52, 49, /* 12+ */ -1, -1)
406 F(3src_a16_nib_ctrl, /* 9+ */ 11, 11, /* 12+ */ -1, -1) /* only exists on IVB+ */
407 F(3src_a16_dst_hw_type, /* 9+ */ 48, 46, /* 12+ */ -1, -1) /* only exists on IVB+ */
408 F(3src_a16_src_hw_type, /* 9+ */ 45, 43, /* 12+ */ -1, -1)
409 F(3src_src2_negate, /* 9+ */ 42, 42, /* 12+ */ 85, 85)
410 F(3src_src2_abs, /* 9+ */ 41, 41, /* 12+ */ 84, 84)
411 F(3src_src1_negate, /* 9+ */ 40, 40, /* 12+ */ 87, 87)
412 F(3src_src1_abs, /* 9+ */ 39, 39, /* 12+ */ 86, 86)
413 F(3src_src0_negate, /* 9+ */ 38, 38, /* 12+ */ 45, 45)
414 F(3src_src0_abs, /* 9+ */ 37, 37, /* 12+ */ 44, 44)
415 F(3src_a16_src1_type, /* 9+ */ 36, 36, /* 12+ */ -1, -1)
416 F(3src_a16_src2_type, /* 9+ */ 35, 35, /* 12+ */ -1, -1)
417 F(3src_a16_flag_reg_nr, /* 9+ */ 33, 33, /* 12+ */ -1, -1)
418 F(3src_a16_flag_subreg_nr, /* 9+ */ 32, 32, /* 12+ */ -1, -1)
419 F(3src_saturate, /* 9+ */ 31, 31, /* 12+ */ 34, 34)
420 F(3src_debug_control, /* 9+ */ 30, 30, /* 12+ */ 30, 30)
421 F(3src_cmpt_control, /* 9+ */ 29, 29, /* 12+ */ 29, 29)
422 FC(3src_acc_wr_control, /* 9+ */ 28, 28, /* 12+ */ 33, 33, devinfo->ver < 20)
423 F(3src_cond_modifier, /* 9+ */ 27, 24, /* 12+ */ 95, 92)
424 F(3src_exec_size, /* 9+ */ 23, 21, /* 12+ */ 18, 16)
425 F(3src_pred_inv, /* 9+ */ 20, 20, /* 12+ */ 28, 28)
426 F20(3src_pred_control, /* 9+ */ 19, 16, /* 12+ */ 27, 24, /* 20+ */ 27, 26)
427 F(3src_thread_control, /* 9+ */ 15, 14, /* 12+ */ -1, -1)
428 F(3src_atomic_control, /* 9+ */ -1, -1, /* 12+ */ 32, 32)
429 F20(3src_qtr_control, /* 9+ */ 13, 12, /* 12+ */ 21, 20, /* 20+ */ 25, 24)
430 F(3src_no_dd_check, /* 9+ */ 10, 10, /* 12+ */ -1, -1)
431 F(3src_no_dd_clear, /* 9+ */ 9, 9, /* 12+ */ -1, -1)
432 F(3src_mask_control, /* 9+ */ 34, 34, /* 12+ */ 31, 31)
433 FK(3src_access_mode, /* 9+ */ 8, 8, /* 12+ */ BRW_ALIGN_1)
434 F20(3src_swsb, /* 9+ */ -1, -1, /* 12+ */ 15, 8, /* 20+ */ 17, 8)
435 /* Bit 7 is Reserved (for future Opcode expansion) */
436 F(3src_hw_opcode, /* 9+ */ 6, 0, /* 12+ */ 6, 0)
437 /** @} */
438
439 #define F_3SRC_A16_SUBREG_NR(srcN, src_base) \
440 static inline void \
441 brw_eu_inst_set_3src_a16_##srcN##_subreg_nr(const struct \
442 intel_device_info *devinfo, \
443 brw_eu_inst *inst, \
444 unsigned value) \
445 { \
446 assert(devinfo->ver == 9); \
447 assert((value & ~0b11110) == 0); \
448 brw_eu_inst_set_bits(inst, src_base + 11, src_base + 9, value >> 2); \
449 brw_eu_inst_set_bits(inst, src_base + 20, src_base + 20, (value >> 1) & 1); \
450 } \
451 static inline unsigned \
452 brw_eu_inst_3src_a16_##srcN##_subreg_nr(const struct \
453 intel_device_info *devinfo, \
454 const brw_eu_inst *inst) \
455 { \
456 assert(devinfo->ver == 9); \
457 return brw_eu_inst_bits(inst, src_base + 11, src_base + 9) << 2 | \
458 brw_eu_inst_bits(inst, src_base + 20, src_base + 20) << 1; \
459 }
460
461 F_3SRC_A16_SUBREG_NR(src0, 64)
462 F_3SRC_A16_SUBREG_NR(src1, 85)
463 F_3SRC_A16_SUBREG_NR(src2, 106)
464 #undef F_3SRC_A16_SUBREG_NR
465
466 #define REG_TYPE(reg) \
467 static inline void \
468 brw_eu_inst_set_3src_a16_##reg##_type(const struct intel_device_info *devinfo, \
469 brw_eu_inst *inst, \
470 enum brw_reg_type type) \
471 { \
472 unsigned hw_type = brw_type_encode_for_3src(devinfo, type); \
473 brw_eu_inst_set_3src_a16_##reg##_hw_type(devinfo, inst, hw_type); \
474 } \
475 \
476 static inline enum brw_reg_type \
477 brw_eu_inst_3src_a16_##reg##_type(const struct intel_device_info *devinfo, \
478 const brw_eu_inst *inst) \
479 { \
480 unsigned hw_type = brw_eu_inst_3src_a16_##reg##_hw_type(devinfo, inst); \
481 return brw_type_decode_for_3src(devinfo, hw_type, 0); \
482 }
483
REG_TYPE(dst)484 REG_TYPE(dst)
485 REG_TYPE(src)
486 #undef REG_TYPE
487
488 /**
489 * Three-source align1 instructions:
490 * @{
491 */
492 /* Reserved 127:126 */
493 /* src2_reg_nr same in align16 */
494 FD20(3src_a1_src2_subreg_nr,/* 9+ */ 117, 113, /* 12+ */ 119, 115, /* 20+ */ 119, 115, -1)
495 FC(3src_a1_src2_hstride, /* 9+ */ 112, 111, /* 12+ */ 113, 112, devinfo->ver >= 10)
496 /* Reserved 110:109. src2 vstride is an implied parameter */
497 FC(3src_a1_src2_hw_type, /* 9+ */ 108, 106, /* 12+ */ 82, 80, devinfo->ver >= 10)
498 /* Reserved 105 */
499 /* src1_reg_nr same in align16 */
500 FD20(3src_a1_src1_subreg_nr, /* 9+ */ 96, 92, /* 12+ */ 103, 99, /* 20+ */ 103, 99, -1)
501 FC(3src_a1_src1_hstride, /* 9+ */ 91, 90, /* 12+ */ 97, 96, devinfo->ver >= 10)
502 FDC(3src_a1_src1_vstride, /* 9+ */ 89, 88, /* 12+ */ 91, 91, 83, 83, devinfo->ver >= 10)
503 FC(3src_a1_src1_hw_type, /* 9+ */ 87, 85, /* 12+ */ 90, 88, devinfo->ver >= 10)
504 /* Reserved 84 */
505 /* src0_reg_nr same in align16 */
506 FD20(3src_a1_src0_subreg_nr, /* 9+ */ 75, 71, /* 12+ */ 71, 67, /* 20+ */ 71, 67, -1)
507 FC(3src_a1_src0_hstride, /* 9+ */ 70, 69, /* 12+ */ 65, 64, devinfo->ver >= 10)
508 FDC(3src_a1_src0_vstride, /* 9+ */ 68, 67, /* 12+ */ 43, 43, 35, 35, devinfo->ver >= 10)
509 FC(3src_a1_src0_hw_type, /* 9+ */ 66, 64, /* 12+ */ 42, 40, devinfo->ver >= 10)
510 /* dst_reg_nr same in align16 */
511 FC(3src_a1_dst_subreg_nr, /* 9+ */ 55, 54, /* 12+ */ 55, 54, devinfo->ver >= 10)
512 FC(3src_a1_special_acc, /* 9+ */ 55, 52, /* 12+ */ 54, 51, devinfo->ver >= 10) /* aliases dst_subreg_nr */
513 /* Reserved 51:50 */
514 FC(3src_a1_dst_hstride, /* 9+ */ 49, 49, /* 12+ */ 48, 48, devinfo->ver >= 10)
515 FC(3src_a1_dst_hw_type, /* 9+ */ 48, 46, /* 12+ */ 38, 36, devinfo->ver >= 10)
516 FF(3src_a1_src2_reg_file, /* 9+ */ 45, 45, /* 12+ */ 47, 114, .grf_or_imm = true)
517 FFC(3src_a1_src1_reg_file, /* 9+ */ 44, 44, /* 12+ */ 98, 98, devinfo->ver >= 10, .grf_or_acc = true)
518 FF(3src_a1_src0_reg_file, /* 9+ */ 43, 43, /* 12+ */ 46, 66, .grf_or_imm = true)
519
520 F(3src_a1_src2_is_imm, /* 9+ */ -1, -1, /* 12+ */ 47, 47)
521 F(3src_a1_src0_is_imm, /* 9+ */ -1, -1, /* 12+ */ 46, 46)
522
523 /* Source Modifier fields same in align16 */
524 FFC(3src_a1_dst_reg_file, /* 9+ */ 36, 36, /* 12+ */ 50, 50, devinfo->ver >= 10, .grf_or_acc = true)
525 FC(3src_a1_exec_type, /* 9+ */ 35, 35, /* 12+ */ 39, 39, devinfo->ver >= 10)
526 /* Fields below this same in align16 */
527 /** @} */
528
529 #define REG_TYPE(reg) \
530 static inline void \
531 brw_eu_inst_set_3src_a1_##reg##_type(const struct intel_device_info *devinfo, \
532 brw_eu_inst *inst, \
533 enum brw_reg_type type) \
534 { \
535 UNUSED enum gfx10_align1_3src_exec_type exec_type = \
536 (enum gfx10_align1_3src_exec_type) \
537 brw_eu_inst_3src_a1_exec_type(devinfo, inst); \
538 if (brw_type_is_float(type)) { \
539 assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT); \
540 } else { \
541 assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_INT); \
542 } \
543 unsigned hw_type = brw_type_encode_for_3src(devinfo, type); \
544 brw_eu_inst_set_3src_a1_##reg##_hw_type(devinfo, inst, hw_type); \
545 } \
546 \
547 static inline enum brw_reg_type \
548 brw_eu_inst_3src_a1_##reg##_type(const struct intel_device_info *devinfo, \
549 const brw_eu_inst *inst) \
550 { \
551 enum gfx10_align1_3src_exec_type exec_type = \
552 (enum gfx10_align1_3src_exec_type) \
553 brw_eu_inst_3src_a1_exec_type(devinfo, inst); \
554 unsigned hw_type = brw_eu_inst_3src_a1_##reg##_hw_type(devinfo, inst); \
555 return brw_type_decode_for_3src(devinfo, hw_type, exec_type); \
556 }
557
558 REG_TYPE(dst)
559 REG_TYPE(src0)
560 REG_TYPE(src1)
561 REG_TYPE(src2)
562 #undef REG_TYPE
563
564 /**
565 * Three-source align1 instruction immediates:
566 * @{
567 */
568 static inline uint16_t
569 brw_eu_inst_3src_a1_src0_imm(ASSERTED const struct intel_device_info *devinfo,
570 const brw_eu_inst *insn)
571 {
572 assert(devinfo->ver >= 10);
573 if (devinfo->ver >= 12)
574 return brw_eu_inst_bits(insn, 79, 64);
575 else
576 return brw_eu_inst_bits(insn, 82, 67);
577 }
578
579 static inline uint16_t
brw_eu_inst_3src_a1_src2_imm(ASSERTED const struct intel_device_info * devinfo,const brw_eu_inst * insn)580 brw_eu_inst_3src_a1_src2_imm(ASSERTED const struct intel_device_info *devinfo,
581 const brw_eu_inst *insn)
582 {
583 assert(devinfo->ver >= 10);
584 if (devinfo->ver >= 12)
585 return brw_eu_inst_bits(insn, 127, 112);
586 else
587 return brw_eu_inst_bits(insn, 124, 109);
588 }
589
590 static inline void
brw_eu_inst_set_3src_a1_src0_imm(ASSERTED const struct intel_device_info * devinfo,brw_eu_inst * insn,uint16_t value)591 brw_eu_inst_set_3src_a1_src0_imm(ASSERTED const struct intel_device_info *devinfo,
592 brw_eu_inst *insn, uint16_t value)
593 {
594 assert(devinfo->ver >= 10);
595 if (devinfo->ver >= 12)
596 brw_eu_inst_set_bits(insn, 79, 64, value);
597 else
598 brw_eu_inst_set_bits(insn, 82, 67, value);
599 }
600
601 static inline void
brw_eu_inst_set_3src_a1_src2_imm(ASSERTED const struct intel_device_info * devinfo,brw_eu_inst * insn,uint16_t value)602 brw_eu_inst_set_3src_a1_src2_imm(ASSERTED const struct intel_device_info *devinfo,
603 brw_eu_inst *insn, uint16_t value)
604 {
605 assert(devinfo->ver >= 10);
606 if (devinfo->ver >= 12)
607 brw_eu_inst_set_bits(insn, 127, 112, value);
608 else
609 brw_eu_inst_set_bits(insn, 124, 109, value);
610 }
611 /** @} */
612
613 /**
614 * Three-source systolic instructions:
615 * @{
616 */
617 F(dpas_3src_src2_reg_nr, /* 9+ */ -1, -1, /* 12+ */ 127, 120)
618 F(dpas_3src_src2_subreg_nr, /* 9+ */ -1, -1, /* 12+ */ 119, 115)
619 FF(dpas_3src_src2_reg_file, /* 9+ */ -1, -1, /* 12+ */ 114, 114)
620 F(dpas_3src_src1_reg_nr, /* 9+ */ -1, -1, /* 12+ */ 111, 104)
621 F(dpas_3src_src1_subreg_nr, /* 9+ */ -1, -1, /* 12+ */ 103, 99)
622 FF(dpas_3src_src1_reg_file, /* 9+ */ -1, -1, /* 12+ */ 98, 98)
623 F(dpas_3src_src1_hw_type, /* 9+ */ -1, -1, /* 12+ */ 90, 88)
624 F(dpas_3src_src1_subbyte, /* 9+ */ -1, -1, /* 12+ */ 87, 86)
625 F(dpas_3src_src2_subbyte, /* 9+ */ -1, -1, /* 12+ */ 85, 84)
626 F(dpas_3src_src2_hw_type, /* 9+ */ -1, -1, /* 12+ */ 82, 80)
627 F(dpas_3src_src0_reg_nr, /* 9+ */ -1, -1, /* 12+ */ 79, 72)
628 F(dpas_3src_src0_subreg_nr, /* 9+ */ -1, -1, /* 12+ */ 71, 67)
629 FF(dpas_3src_src0_reg_file, /* 9+ */ -1, -1, /* 12+ */ 66, 66)
630 F(dpas_3src_dst_reg_nr, /* 9+ */ -1, -1, /* 12+ */ 63, 56)
631 F(dpas_3src_dst_subreg_nr, /* 9+ */ -1, -1, /* 12+ */ 55, 51)
632 FF(dpas_3src_dst_reg_file, /* 9+ */ -1, -1, /* 12+ */ 50, 50)
633 F(dpas_3src_sdepth, /* 9+ */ -1, -1, /* 12+ */ 49, 48)
634 F(dpas_3src_rcount, /* 9+ */ -1, -1, /* 12+ */ 45, 43)
635 F(dpas_3src_src0_hw_type, /* 9+ */ -1, -1, /* 12+ */ 42, 40)
636 F(dpas_3src_exec_type, /* 9+ */ -1, -1, /* 12+ */ 39, 39)
637 F(dpas_3src_dst_hw_type, /* 9+ */ -1, -1, /* 12+ */ 38, 36)
638 /** @} */
639
640 #define REG_TYPE(reg) \
641 static inline void \
642 brw_eu_inst_set_dpas_3src_##reg##_type(const struct intel_device_info *devinfo, \
643 brw_eu_inst *inst, \
644 enum brw_reg_type type) \
645 { \
646 UNUSED enum gfx10_align1_3src_exec_type exec_type = \
647 (enum gfx10_align1_3src_exec_type) \
648 brw_eu_inst_dpas_3src_exec_type(devinfo, inst); \
649 if (brw_type_is_float(type)) { \
650 assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_FLOAT); \
651 } else { \
652 assert(exec_type == BRW_ALIGN1_3SRC_EXEC_TYPE_INT); \
653 } \
654 unsigned hw_type = brw_type_encode_for_3src(devinfo, type); \
655 brw_eu_inst_set_dpas_3src_##reg##_hw_type(devinfo, inst, hw_type); \
656 } \
657 \
658 static inline enum brw_reg_type \
659 brw_eu_inst_dpas_3src_##reg##_type(const struct intel_device_info *devinfo, \
660 const brw_eu_inst *inst) \
661 { \
662 enum gfx10_align1_3src_exec_type exec_type = \
663 (enum gfx10_align1_3src_exec_type) \
664 brw_eu_inst_dpas_3src_exec_type(devinfo, inst); \
665 unsigned hw_type = brw_eu_inst_dpas_3src_##reg##_hw_type(devinfo, inst); \
666 return brw_type_decode_for_3src(devinfo, hw_type, exec_type); \
667 }
668
REG_TYPE(dst)669 REG_TYPE(dst)
670 REG_TYPE(src0)
671 REG_TYPE(src1)
672 REG_TYPE(src2)
673 #undef REG_TYPE
674
675 /**
676 * Flow control instruction bits:
677 * @{
678 */
679 static inline void
680 brw_eu_inst_set_uip(const struct intel_device_info *devinfo,
681 brw_eu_inst *inst, int32_t value)
682 {
683 if (devinfo->ver >= 12)
684 brw_eu_inst_set_src1_is_imm(devinfo, inst, 1);
685
686 brw_eu_inst_set_bits(inst, 95, 64, (uint32_t)value);
687 }
688
689 static inline int32_t
brw_eu_inst_uip(const struct intel_device_info * devinfo,const brw_eu_inst * inst)690 brw_eu_inst_uip(const struct intel_device_info *devinfo, const brw_eu_inst *inst)
691 {
692 return brw_eu_inst_bits(inst, 95, 64);
693 }
694
695 static inline void
brw_eu_inst_set_jip(const struct intel_device_info * devinfo,brw_eu_inst * inst,int32_t value)696 brw_eu_inst_set_jip(const struct intel_device_info *devinfo,
697 brw_eu_inst *inst, int32_t value)
698 {
699 if (devinfo->ver >= 12)
700 brw_eu_inst_set_src0_is_imm(devinfo, inst, 1);
701
702 brw_eu_inst_set_bits(inst, 127, 96, (uint32_t)value);
703 }
704
705 static inline int32_t
brw_eu_inst_jip(const struct intel_device_info * devinfo,const brw_eu_inst * inst)706 brw_eu_inst_jip(const struct intel_device_info *devinfo, const brw_eu_inst *inst)
707 {
708 return brw_eu_inst_bits(inst, 127, 96);
709 }
710 /** @} */
711
712 /**
713 * SEND instructions:
714 * @{
715 */
716 F(send_ex_desc_ia_subreg_nr, /* 9+ */ 82, 80, /* 12+ */ 42, 40)
717 F(send_src0_address_mode, /* 9+ */ 79, 79, /* 12+ */ -1, -1)
718 F(send_sel_reg32_desc, /* 9+ */ 77, 77, /* 12+ */ 48, 48)
719 F(send_sel_reg32_ex_desc, /* 9+ */ 61, 61, /* 12+ */ 49, 49)
720 FF(send_src0_reg_file, /* 9+ */ 42, 41, /* 12+ */ 66, 66)
721 F(send_src1_reg_nr, /* 9+ */ 51, 44, /* 12+ */ 111, 104)
722 FC(send_src1_len, /* 9+ */ -1, -1, /* 12+ */ 103, 99, devinfo->verx10 >= 125)
723 FF(send_src1_reg_file, /* 9+ */ 36, 36, /* 12+ */ 98, 98)
724 FF(send_dst_reg_file, /* 9+ */ 35, 35, /* 12+ */ 50, 50)
725 FC(send_ex_bso, /* 9+ */ -1, -1, /* 12+ */ 39, 39, devinfo->verx10 >= 125)
726
727 /* When using scalar register for src0, this replaces src1_len, which is
728 * always zero.
729 */
730 FC(send_src0_subreg_nr, /* 9+ */ -1, -1, /* 12+ */ 103, 99, devinfo->verx10 >= 300)
731 /** @} */
732
733 /* Message descriptor bits */
734 #define MD(x) ((x) + 96)
735 #define MD12(x) ((x) >= 30 ? (x) - 30 + 122 : \
736 (x) >= 25 ? (x) - 25 + 67 : \
737 (x) >= 20 ? (x) - 20 + 51 : \
738 (x) >= 11 ? (x) - 11 + 113 : \
739 (x) - 0 + 81)
740
741 /**
742 * Set the SEND(C) message descriptor immediate.
743 *
744 * This doesn't include the SFID nor the EOT field that were considered to be
745 * part of the message descriptor by ancient versions of the BSpec, because
746 * they are present in the instruction even if the message descriptor is
747 * provided indirectly in the address register, so we want to specify them
748 * separately.
749 */
750 static inline void
brw_eu_inst_set_send_desc(const struct intel_device_info * devinfo,brw_eu_inst * inst,uint32_t value)751 brw_eu_inst_set_send_desc(const struct intel_device_info *devinfo,
752 brw_eu_inst *inst, uint32_t value)
753 {
754 if (devinfo->ver >= 12) {
755 brw_eu_inst_set_bits(inst, 123, 122, GET_BITS(value, 31, 30));
756 brw_eu_inst_set_bits(inst, 71, 67, GET_BITS(value, 29, 25));
757 brw_eu_inst_set_bits(inst, 55, 51, GET_BITS(value, 24, 20));
758 brw_eu_inst_set_bits(inst, 121, 113, GET_BITS(value, 19, 11));
759 brw_eu_inst_set_bits(inst, 91, 81, GET_BITS(value, 10, 0));
760 } else {
761 brw_eu_inst_set_bits(inst, 126, 96, value);
762 assert(value >> 31 == 0);
763 }
764 }
765
766 /**
767 * Get the SEND(C) message descriptor immediate.
768 *
769 * \sa brw_eu_inst_set_send_desc().
770 */
771 static inline uint32_t
brw_eu_inst_send_desc(const struct intel_device_info * devinfo,const brw_eu_inst * inst)772 brw_eu_inst_send_desc(const struct intel_device_info *devinfo,
773 const brw_eu_inst *inst)
774 {
775 if (devinfo->ver >= 12) {
776 return (brw_eu_inst_bits(inst, 123, 122) << 30 |
777 brw_eu_inst_bits(inst, 71, 67) << 25 |
778 brw_eu_inst_bits(inst, 55, 51) << 20 |
779 brw_eu_inst_bits(inst, 121, 113) << 11 |
780 brw_eu_inst_bits(inst, 91, 81));
781 } else {
782 return brw_eu_inst_bits(inst, 126, 96);
783 }
784 }
785
786 /**
787 * Set the SEND(C) message extended descriptor immediate.
788 *
789 * This doesn't include the SFID nor the EOT field that were considered to be
790 * part of the extended message descriptor by some versions of the BSpec,
791 * because they are present in the instruction even if the extended message
792 * descriptor is provided indirectly in a register, so we want to specify them
793 * separately.
794 */
795 static inline void
brw_eu_inst_set_send_ex_desc(const struct intel_device_info * devinfo,brw_eu_inst * inst,uint32_t value,bool gather)796 brw_eu_inst_set_send_ex_desc(const struct intel_device_info *devinfo,
797 brw_eu_inst *inst, uint32_t value, bool gather)
798 {
799 assert(!gather || devinfo->ver >= 30);
800
801 if (devinfo->ver >= 12) {
802 brw_eu_inst_set_bits(inst, 127, 124, GET_BITS(value, 31, 28));
803 brw_eu_inst_set_bits(inst, 97, 96, GET_BITS(value, 27, 26));
804 brw_eu_inst_set_bits(inst, 65, 64, GET_BITS(value, 25, 24));
805 brw_eu_inst_set_bits(inst, 47, 35, GET_BITS(value, 23, 11));
806
807 /* SEND gather uses these bits for src0 subreg nr, so they
808 * are not part of the ex_desc.
809 */
810 if (gather) {
811 assert(devinfo->ver >= 30);
812 assert(GET_BITS(value, 10, 6) == 0);
813 } else {
814 brw_eu_inst_set_bits(inst, 103, 99, GET_BITS(value, 10, 6));
815 }
816
817 assert(GET_BITS(value, 5, 0) == 0);
818 } else {
819 assert(devinfo->ver >= 9);
820 brw_eu_inst_set_bits(inst, 94, 91, GET_BITS(value, 31, 28));
821 brw_eu_inst_set_bits(inst, 88, 85, GET_BITS(value, 27, 24));
822 brw_eu_inst_set_bits(inst, 83, 80, GET_BITS(value, 23, 20));
823 brw_eu_inst_set_bits(inst, 67, 64, GET_BITS(value, 19, 16));
824 assert(GET_BITS(value, 15, 0) == 0);
825 }
826 }
827
828 /**
829 * Set the SENDS(C) message extended descriptor immediate.
830 *
831 * This doesn't include the SFID nor the EOT field that were considered to be
832 * part of the extended message descriptor by some versions of the BSpec,
833 * because they are present in the instruction even if the extended message
834 * descriptor is provided indirectly in a register, so we want to specify them
835 * separately.
836 */
837 static inline void
brw_eu_inst_set_sends_ex_desc(const struct intel_device_info * devinfo,brw_eu_inst * inst,uint32_t value,bool gather)838 brw_eu_inst_set_sends_ex_desc(const struct intel_device_info *devinfo,
839 brw_eu_inst *inst, uint32_t value, bool gather)
840 {
841 if (devinfo->ver >= 12) {
842 brw_eu_inst_set_send_ex_desc(devinfo, inst, value, gather);
843 } else {
844 brw_eu_inst_set_bits(inst, 95, 80, GET_BITS(value, 31, 16));
845 assert(GET_BITS(value, 15, 10) == 0);
846 brw_eu_inst_set_bits(inst, 67, 64, GET_BITS(value, 9, 6));
847 assert(GET_BITS(value, 5, 0) == 0);
848 }
849 }
850
851 /**
852 * Get the SEND(C) message extended descriptor immediate.
853 *
854 * \sa brw_eu_inst_set_send_ex_desc().
855 */
856 static inline uint32_t
brw_eu_inst_send_ex_desc(const struct intel_device_info * devinfo,const brw_eu_inst * inst,bool gather)857 brw_eu_inst_send_ex_desc(const struct intel_device_info *devinfo,
858 const brw_eu_inst *inst, bool gather)
859 {
860 assert(!gather || devinfo->ver >= 30);
861
862 if (devinfo->ver >= 12) {
863 return (brw_eu_inst_bits(inst, 127, 124) << 28 |
864 brw_eu_inst_bits(inst, 97, 96) << 26 |
865 brw_eu_inst_bits(inst, 65, 64) << 24 |
866 brw_eu_inst_bits(inst, 47, 35) << 11 |
867 (!gather ? brw_eu_inst_bits(inst, 103, 99) << 6 : 0));
868 } else {
869 assert(devinfo->ver >= 9);
870 return (brw_eu_inst_bits(inst, 94, 91) << 28 |
871 brw_eu_inst_bits(inst, 88, 85) << 24 |
872 brw_eu_inst_bits(inst, 83, 80) << 20 |
873 brw_eu_inst_bits(inst, 67, 64) << 16);
874 }
875 }
876
877 /**
878 * Get the SENDS(C) message extended descriptor immediate.
879 *
880 * \sa brw_eu_inst_set_send_ex_desc().
881 */
882 static inline uint32_t
brw_eu_inst_sends_ex_desc(const struct intel_device_info * devinfo,const brw_eu_inst * inst,bool gather)883 brw_eu_inst_sends_ex_desc(const struct intel_device_info *devinfo,
884 const brw_eu_inst *inst, bool gather)
885 {
886 if (devinfo->ver >= 12) {
887 return brw_eu_inst_send_ex_desc(devinfo, inst, gather);
888 } else {
889 assert(!gather);
890 return (brw_eu_inst_bits(inst, 95, 80) << 16 |
891 brw_eu_inst_bits(inst, 67, 64) << 6);
892 }
893 }
894
895 /**
896 * Fields for SEND messages:
897 * @{
898 */
899 F(eot, /* 9+ */ 127, 127, /* 12+ */ 34, 34)
900 F(mlen, /* 9+ */ 124, 121, /* 12+ */ MD12(28), MD12(25))
901 F(rlen, /* 9+ */ 120, 116, /* 12+ */ MD12(24), MD12(20))
902 F(header_present, /* 9+ */ 115, 115, /* 12+ */ MD12(19), MD12(19))
903 F(gateway_notify, /* 9+ */ MD(16), MD(15), /* 12+ */ -1, -1)
904 FD(function_control, /* 9+ */ 114, 96, /* 12+ */ MD12(18), MD12(11), MD12(10), MD12(0))
905 F(gateway_subfuncid, /* 9+ */ MD(2), MD(0), /* 12+ */ MD12(2), MD12(0))
906 F(sfid, /* 9+ */ 27, 24, /* 12+ */ 95, 92)
907 F(null_rt, /* 9+ */ 80, 80, /* 12+ */ 44, 44) /* actually only Gfx11+ */
908 F(send_rta_index, /* 9+ */ -1, -1, /* 12+ */ 38, 36)
909 /** @} */
910
911 /**
912 * URB message function control bits:
913 * @{
914 */
915 F(urb_per_slot_offset, /* 9+ */ MD(17), MD(17), /* 12+ */ MD12(17), MD12(17))
916 F(urb_channel_mask_present, /* 9+ */ MD(15), MD(15), /* 12+ */ MD12(15), MD12(15))
917 F(urb_swizzle_control, /* 9+ */ MD(15), MD(15), /* 12+ */ -1, -1)
918 FD(urb_global_offset, /* 9+ */ MD(14), MD(4), /* 12+ */ MD12(14), MD12(11), MD12(10), MD12(4))
919 F(urb_opcode, /* 9+ */ MD( 3), MD(0), /* 12+ */ MD12(3), MD12(0))
920 /** @} */
921
922 /**
923 * Sampler message function control bits:
924 * @{
925 */
926 F(sampler_simd_mode, /* 9+ */ MD(18), MD(17), /* 12+ */ MD12(18), MD12(17))
927 F(sampler_msg_type, /* 9+ */ MD(16), MD(12), /* 12+ */ MD12(16), MD12(12))
928 FD(sampler, /* 9+ */ MD(11), MD(8), /* 12+ */ MD12(11), MD12(11), MD12(10), MD12(8))
929 F(binding_table_index, /* 9+ */ MD(7), MD(0), /* 12+ */ MD12(7), MD12(0)) /* also used by other messages */
930 /** @} */
931
932 /**
933 * Data port message function control bits:
934 * @{
935 */
936 F(dp_category, /* 9+ */ MD(18), MD(18), /* 12+ */ MD12(18), MD12(18))
937
938 F(dp_read_msg_type, /* 9+ */ MD(17), MD(14), /* 12+ */ MD12(17), MD12(14))
939 F(dp_write_msg_type, /* 9+ */ MD(17), MD(14), /* 12+ */ MD12(17), MD12(14))
940 FD(dp_read_msg_control, /* 9+ */ MD(13), MD( 8), /* 12+ */ MD12(13), MD12(11), MD12(10), MD12(8))
941 FD(dp_write_msg_control, /* 9+ */ MD(13), MD( 8), /* 12+ */ MD12(13), MD12(11), MD12(10), MD12(8))
942
943 F(dp_msg_type, /* 9+ */ MD(18), MD(14), /* 12+ */ MD12(18), MD12(14))
944 FD(dp_msg_control, /* 9+ */ MD(13), MD( 8), /* 12+ */ MD12(13), MD12(11), MD12(10), MD12(8))
945 /** @} */
946
947 /**
948 * Scratch message bits:
949 * @{
950 */
951 F(scratch_read_write, /* 9+ */ MD(17), MD(17), /* 12+ */ MD12(17), MD12(17)) /* 0 = read, 1 = write */
952 F(scratch_type, /* 9+ */ MD(16), MD(16), /* 12+ */ -1, -1) /* 0 = OWord, 1 = DWord */
953 F(scratch_invalidate_after_read, /* 9+ */ MD(15), MD(15), /* 12+ */ MD12(15), MD12(15))
954 F(scratch_block_size, /* 9+ */ MD(13), MD(12), /* 12+ */ MD12(13), MD12(12))
955 FD(scratch_addr_offset,
956 /* 9: */ MD(11), MD(0),
957 /* 12: */ MD12(11), MD12(11), MD12(10), MD12(0))
958 /** @} */
959
960 /**
961 * Render Target message function control bits:
962 * @{
963 */
964 F(rt_last, /* 9+ */ MD(12), MD(12), /* 12+ */ MD12(12), MD12(12))
965 F(rt_slot_group, /* 9+ */ MD(11), MD(11), /* 12+ */ MD12(11), MD12(11))
966 F(rt_message_type, /* 9+ */ MD(10), MD( 8), /* 12+ */ MD12(10), MD12(8))
967 /** @} */
968
969 /**
970 * Pixel Interpolator message function control bits:
971 * @{
972 */
973 F(pi_simd_mode, /* 9+ */ MD(16), MD(16), /* 12+ */ MD12(16), MD12(16))
974 F(pi_nopersp, /* 9+ */ MD(14), MD(14), /* 12+ */ MD12(14), MD12(14))
975 F(pi_message_type, /* 9+ */ MD(13), MD(12), /* 12+ */ MD12(13), MD12(12))
976 F(pi_slot_group, /* 9+ */ MD(11), MD(11), /* 12+ */ MD12(11), MD12(11))
977 F(pi_message_data, /* 9+ */ MD(7), MD(0), /* 12+ */ MD12(7), MD12(0))
978 /** @} */
979
980 /**
981 * Immediates:
982 * @{
983 */
984 static inline int
brw_eu_inst_imm_d(const struct intel_device_info * devinfo,const brw_eu_inst * insn)985 brw_eu_inst_imm_d(const struct intel_device_info *devinfo, const brw_eu_inst *insn)
986 {
987 (void) devinfo;
988 return brw_eu_inst_bits(insn, 127, 96);
989 }
990
991 static inline unsigned
brw_eu_inst_imm_ud(const struct intel_device_info * devinfo,const brw_eu_inst * insn)992 brw_eu_inst_imm_ud(const struct intel_device_info *devinfo, const brw_eu_inst *insn)
993 {
994 (void) devinfo;
995 return brw_eu_inst_bits(insn, 127, 96);
996 }
997
998 static inline uint64_t
brw_eu_inst_imm_uq(const struct intel_device_info * devinfo,const brw_eu_inst * insn)999 brw_eu_inst_imm_uq(const struct intel_device_info *devinfo,
1000 const brw_eu_inst *insn)
1001 {
1002 if (devinfo->ver >= 12) {
1003 return brw_eu_inst_bits(insn, 95, 64) << 32 |
1004 brw_eu_inst_bits(insn, 127, 96);
1005 } else {
1006 return brw_eu_inst_bits(insn, 127, 64);
1007 }
1008 }
1009
1010 static inline float
brw_eu_inst_imm_f(const struct intel_device_info * devinfo,const brw_eu_inst * insn)1011 brw_eu_inst_imm_f(const struct intel_device_info *devinfo, const brw_eu_inst *insn)
1012 {
1013 union {
1014 float f;
1015 uint32_t u;
1016 } ft;
1017 (void) devinfo;
1018 ft.u = brw_eu_inst_bits(insn, 127, 96);
1019 return ft.f;
1020 }
1021
1022 static inline double
brw_eu_inst_imm_df(const struct intel_device_info * devinfo,const brw_eu_inst * insn)1023 brw_eu_inst_imm_df(const struct intel_device_info *devinfo, const brw_eu_inst *insn)
1024 {
1025 union {
1026 double d;
1027 uint64_t u;
1028 } dt;
1029 dt.u = brw_eu_inst_imm_uq(devinfo, insn);
1030 return dt.d;
1031 }
1032
1033 static inline void
brw_eu_inst_set_imm_d(const struct intel_device_info * devinfo,brw_eu_inst * insn,int value)1034 brw_eu_inst_set_imm_d(const struct intel_device_info *devinfo,
1035 brw_eu_inst *insn, int value)
1036 {
1037 (void) devinfo;
1038 return brw_eu_inst_set_bits(insn, 127, 96, value);
1039 }
1040
1041 static inline void
brw_eu_inst_set_imm_ud(const struct intel_device_info * devinfo,brw_eu_inst * insn,unsigned value)1042 brw_eu_inst_set_imm_ud(const struct intel_device_info *devinfo,
1043 brw_eu_inst *insn, unsigned value)
1044 {
1045 (void) devinfo;
1046 return brw_eu_inst_set_bits(insn, 127, 96, value);
1047 }
1048
1049 static inline void
brw_eu_inst_set_imm_f(const struct intel_device_info * devinfo,brw_eu_inst * insn,float value)1050 brw_eu_inst_set_imm_f(const struct intel_device_info *devinfo,
1051 brw_eu_inst *insn, float value)
1052 {
1053 union {
1054 float f;
1055 uint32_t u;
1056 } ft;
1057 (void) devinfo;
1058 ft.f = value;
1059 brw_eu_inst_set_bits(insn, 127, 96, ft.u);
1060 }
1061
1062 static inline void
brw_eu_inst_set_imm_df(const struct intel_device_info * devinfo,brw_eu_inst * insn,double value)1063 brw_eu_inst_set_imm_df(const struct intel_device_info *devinfo,
1064 brw_eu_inst *insn, double value)
1065 {
1066 union {
1067 double d;
1068 uint64_t u;
1069 } dt;
1070 (void) devinfo;
1071 dt.d = value;
1072
1073 if (devinfo->ver >= 12) {
1074 brw_eu_inst_set_bits(insn, 95, 64, dt.u >> 32);
1075 brw_eu_inst_set_bits(insn, 127, 96, dt.u & 0xFFFFFFFF);
1076 } else {
1077 brw_eu_inst_set_bits(insn, 127, 64, dt.u);
1078 }
1079 }
1080
1081 static inline void
brw_eu_inst_set_imm_uq(const struct intel_device_info * devinfo,brw_eu_inst * insn,uint64_t value)1082 brw_eu_inst_set_imm_uq(const struct intel_device_info *devinfo,
1083 brw_eu_inst *insn, uint64_t value)
1084 {
1085 (void) devinfo;
1086 if (devinfo->ver >= 12) {
1087 brw_eu_inst_set_bits(insn, 95, 64, value >> 32);
1088 brw_eu_inst_set_bits(insn, 127, 96, value & 0xFFFFFFFF);
1089 } else {
1090 brw_eu_inst_set_bits(insn, 127, 64, value);
1091 }
1092 }
1093
1094 /** @} */
1095
1096 #define REG_TYPE(reg) \
1097 static inline void \
1098 brw_eu_inst_set_##reg##_file_type(const struct intel_device_info *devinfo, \
1099 brw_eu_inst *inst, enum brw_reg_file file, \
1100 enum brw_reg_type type) \
1101 { \
1102 assert(file <= IMM); \
1103 unsigned hw_type = brw_type_encode(devinfo, file, type); \
1104 brw_eu_inst_set_##reg##_reg_file(devinfo, inst, file); \
1105 brw_eu_inst_set_##reg##_reg_hw_type(devinfo, inst, hw_type); \
1106 } \
1107 \
1108 static inline enum brw_reg_type \
1109 brw_eu_inst_##reg##_type(const struct intel_device_info *devinfo, \
1110 const brw_eu_inst *inst) \
1111 { \
1112 unsigned file = __builtin_strcmp("dst", #reg) == 0 ? \
1113 (unsigned) FIXED_GRF : \
1114 brw_eu_inst_##reg##_reg_file(devinfo, inst); \
1115 unsigned hw_type = brw_eu_inst_##reg##_reg_hw_type(devinfo, inst); \
1116 return brw_type_decode(devinfo, (enum brw_reg_file)file, hw_type); \
1117 }
1118
1119 REG_TYPE(dst)
REG_TYPE(src0)1120 REG_TYPE(src0)
1121 REG_TYPE(src1)
1122 #undef REG_TYPE
1123
1124
1125 /* The AddrImm fields are split into two discontiguous sections on Gfx9+ */
1126 #define BRW_IA1_ADDR_IMM(reg, g9_nine, g9_high, g9_low, \
1127 g12_high, g12_low, g20_high, g20_low, g20_zero) \
1128 static inline void \
1129 brw_eu_inst_set_##reg##_ia1_addr_imm(const struct \
1130 intel_device_info *devinfo, \
1131 brw_eu_inst *inst, \
1132 unsigned value) \
1133 { \
1134 if (devinfo->ver >= 20) { \
1135 assert((value & ~0x7ff) == 0); \
1136 brw_eu_inst_set_bits(inst, g20_high, g20_low, value >> 1); \
1137 if (g20_zero == -1) \
1138 assert((value & 1) == 0); \
1139 else \
1140 brw_eu_inst_set_bits(inst, g20_zero, g20_zero, value & 1); \
1141 } else if (devinfo->ver >= 12) { \
1142 assert((value & ~0x3ff) == 0); \
1143 brw_eu_inst_set_bits(inst, g12_high, g12_low, value); \
1144 } else { \
1145 assert((value & ~0x3ff) == 0); \
1146 brw_eu_inst_set_bits(inst, g9_high, g9_low, value & 0x1ff); \
1147 brw_eu_inst_set_bits(inst, g9_nine, g9_nine, value >> 9); \
1148 } \
1149 } \
1150 static inline unsigned \
1151 brw_eu_inst_##reg##_ia1_addr_imm(const struct intel_device_info *devinfo,\
1152 const brw_eu_inst *inst) \
1153 { \
1154 if (devinfo->ver >= 20) { \
1155 return brw_eu_inst_bits(inst, g20_high, g20_low) << 1 | \
1156 (g20_zero == -1 ? 0 : \
1157 brw_eu_inst_bits(inst, g20_zero, g20_zero)); \
1158 } else if (devinfo->ver >= 12) { \
1159 return brw_eu_inst_bits(inst, g12_high, g12_low); \
1160 } else { \
1161 return brw_eu_inst_bits(inst, g9_high, g9_low) | \
1162 (brw_eu_inst_bits(inst, g9_nine, g9_nine) << 9); \
1163 } \
1164 }
1165
1166 /* AddrImm for Align1 Indirect Addressing */
1167 /* ----Gfx9---- -Gfx12- ---Gfx20--- */
1168 BRW_IA1_ADDR_IMM(src1, 121, 104, 96, 107, 98, 107, 98, -1)
1169 BRW_IA1_ADDR_IMM(src0, 95, 72, 64, 75, 66, 75, 66, 87)
1170 BRW_IA1_ADDR_IMM(dst, 47, 56, 48, 59, 50, 59, 50, 33)
1171
1172 #define BRW_IA16_ADDR_IMM(reg, g9_nine, g9_high, g9_low) \
1173 static inline void \
1174 brw_eu_inst_set_##reg##_ia16_addr_imm(const struct \
1175 intel_device_info *devinfo, \
1176 brw_eu_inst *inst, unsigned value) \
1177 { \
1178 assert(devinfo->ver < 12); \
1179 assert((value & ~0x3ff) == 0); \
1180 assert(GET_BITS(value, 3, 0) == 0); \
1181 brw_eu_inst_set_bits(inst, g9_high, g9_low, GET_BITS(value, 8, 4)); \
1182 brw_eu_inst_set_bits(inst, g9_nine, g9_nine, GET_BITS(value, 9, 9)); \
1183 } \
1184 static inline unsigned \
1185 brw_eu_inst_##reg##_ia16_addr_imm(const struct intel_device_info *devinfo,\
1186 const brw_eu_inst *inst) \
1187 { \
1188 assert(devinfo->ver < 12); \
1189 return (brw_eu_inst_bits(inst, g9_high, g9_low) << 4) | \
1190 (brw_eu_inst_bits(inst, g9_nine, g9_nine) << 9); \
1191 }
1192
1193 /* AddrImm[9:0] for Align16 Indirect Addressing:
1194 * Compared to Align1, these are missing the low 4 bits.
1195 * ----Gfx9----
1196 */
1197 BRW_IA16_ADDR_IMM(src1, 121, 104, 100)
1198 BRW_IA16_ADDR_IMM(src0, 95, 72, 68)
1199 BRW_IA16_ADDR_IMM(dst, 47, 56, 52)
1200 BRW_IA16_ADDR_IMM(send_src0, 78, 72, 68)
1201 BRW_IA16_ADDR_IMM(send_dst, 62, 56, 52)
1202
1203 /**
1204 * Fetch a set of contiguous bits from the instruction.
1205 *
1206 * Bits indices range from 0..127; fields may not cross 64-bit boundaries.
1207 */
1208 static inline uint64_t
1209 brw_eu_inst_bits(const brw_eu_inst *inst, unsigned high, unsigned low)
1210 {
1211 assume(high < 128);
1212 assume(high >= low);
1213 /* We assume the field doesn't cross 64-bit boundaries. */
1214 const unsigned word = high / 64;
1215 assert(word == low / 64);
1216
1217 high %= 64;
1218 low %= 64;
1219
1220 const uint64_t mask = (~0ull >> (64 - (high - low + 1)));
1221
1222 return (inst->data[word] >> low) & mask;
1223 }
1224
1225 /**
1226 * Set bits in the instruction, with proper shifting and masking.
1227 *
1228 * Bits indices range from 0..127; fields may not cross 64-bit boundaries.
1229 */
1230 static inline void
brw_eu_inst_set_bits(brw_eu_inst * inst,unsigned high,unsigned low,uint64_t value)1231 brw_eu_inst_set_bits(brw_eu_inst *inst, unsigned high, unsigned low, uint64_t value)
1232 {
1233 assume(high < 128);
1234 assume(high >= low);
1235 const unsigned word = high / 64;
1236 assert(word == low / 64);
1237
1238 high %= 64;
1239 low %= 64;
1240
1241 const uint64_t mask = (~0ull >> (64 - (high - low + 1))) << low;
1242
1243 /* Make sure the supplied value actually fits in the given bitfield. */
1244 assert((value & (mask >> low)) == value);
1245
1246 inst->data[word] = (inst->data[word] & ~mask) | (value << low);
1247 }
1248
1249 #undef BRW_IA16_ADDR_IMM
1250 #undef BRW_IA1_ADDR_IMM
1251 #undef MD
1252 #undef F
1253 #undef FC
1254 #undef F20
1255 #undef FD20
1256
1257 typedef struct {
1258 uint64_t data;
1259 } brw_eu_compact_inst;
1260
1261 /**
1262 * Fetch a set of contiguous bits from the compacted instruction.
1263 *
1264 * Bits indices range from 0..63.
1265 */
1266 static inline unsigned
brw_eu_compact_inst_bits(const brw_eu_compact_inst * inst,unsigned high,unsigned low)1267 brw_eu_compact_inst_bits(const brw_eu_compact_inst *inst, unsigned high, unsigned low)
1268 {
1269 assume(high < 64);
1270 assume(high >= low);
1271 const uint64_t mask = (1ull << (high - low + 1)) - 1;
1272
1273 return (inst->data >> low) & mask;
1274 }
1275
1276 /**
1277 * Set bits in the compacted instruction.
1278 *
1279 * Bits indices range from 0..63.
1280 */
1281 static inline void
brw_eu_compact_inst_set_bits(brw_eu_compact_inst * inst,unsigned high,unsigned low,uint64_t value)1282 brw_eu_compact_inst_set_bits(brw_eu_compact_inst *inst, unsigned high, unsigned low,
1283 uint64_t value)
1284 {
1285 assume(high < 64);
1286 assume(high >= low);
1287 const uint64_t mask = ((1ull << (high - low + 1)) - 1) << low;
1288
1289 /* Make sure the supplied value actually fits in the given bitfield. */
1290 assert((value & (mask >> low)) == value);
1291
1292 inst->data = (inst->data & ~mask) | (value << low);
1293 }
1294
1295 #define FC(name, hi9, lo9, hi12, lo12, assertions) \
1296 static inline void \
1297 brw_eu_compact_inst_set_##name(const struct \
1298 intel_device_info *devinfo, \
1299 brw_eu_compact_inst *inst, \
1300 unsigned v) \
1301 { \
1302 assert(assertions); \
1303 if (devinfo->ver >= 12) \
1304 brw_eu_compact_inst_set_bits(inst, hi12, lo12, v); \
1305 else \
1306 brw_eu_compact_inst_set_bits(inst, hi9, lo9, v); \
1307 } \
1308 static inline unsigned \
1309 brw_eu_compact_inst_##name(const struct intel_device_info *devinfo,\
1310 const brw_eu_compact_inst *inst) \
1311 { \
1312 assert(assertions); \
1313 if (devinfo->ver >= 12) \
1314 return brw_eu_compact_inst_bits(inst, hi12, lo12); \
1315 else \
1316 return brw_eu_compact_inst_bits(inst, hi9, lo9); \
1317 }
1318
1319 /* A simple macro for fields which stay in the same place on all generations
1320 * except for Gfx12.
1321 */
1322 #define F(name, hi9, lo9, hi12, lo12) FC(name, hi9, lo9, hi12, lo12, true)
1323
1324 /* A macro for fields which moved to several different locations
1325 * across generations.
1326 */
1327 #define F20(name, hi9, lo9, hi12, lo12, hi20, lo20) \
1328 static inline void \
1329 brw_eu_compact_inst_set_##name(const struct \
1330 intel_device_info *devinfo, \
1331 brw_eu_compact_inst *inst, \
1332 unsigned v) \
1333 { \
1334 if (devinfo->ver >= 20) \
1335 brw_eu_compact_inst_set_bits(inst, hi20, lo20, v); \
1336 else if (devinfo->ver >= 12) \
1337 brw_eu_compact_inst_set_bits(inst, hi12, lo12, v); \
1338 else \
1339 brw_eu_compact_inst_set_bits(inst, hi9, lo9, v); \
1340 } \
1341 static inline unsigned \
1342 brw_eu_compact_inst_##name(const struct intel_device_info *devinfo,\
1343 const brw_eu_compact_inst *inst) \
1344 { \
1345 if (devinfo->ver >= 20) \
1346 return brw_eu_compact_inst_bits(inst, hi20, lo20); \
1347 else if (devinfo->ver >= 12) \
1348 return brw_eu_compact_inst_bits(inst, hi12, lo12); \
1349 else \
1350 return brw_eu_compact_inst_bits(inst, hi9, lo9); \
1351 }
1352
1353 /* A macro for fields which gained extra discontiguous bits in Gfx20
1354 * (specified by hi20ex-lo20ex).
1355 */
1356 #define FD20(name, hi9, lo9, hi12, lo12, \
1357 hi20, lo20, hi20ex, lo20ex) \
1358 static inline void \
1359 brw_eu_compact_inst_set_##name(const struct \
1360 intel_device_info *devinfo, \
1361 brw_eu_compact_inst *inst, unsigned v) \
1362 { \
1363 if (devinfo->ver >= 20) { \
1364 const unsigned k = hi20 - lo20 + 1; \
1365 brw_eu_compact_inst_set_bits(inst, hi20ex, lo20ex, v >> k); \
1366 brw_eu_compact_inst_set_bits(inst, hi20, lo20, v & ((1u << k) - 1)); \
1367 } else if (devinfo->ver >= 12) { \
1368 brw_eu_compact_inst_set_bits(inst, hi12, lo12, v); \
1369 } else { \
1370 brw_eu_compact_inst_set_bits(inst, hi9, lo9, v); \
1371 } \
1372 } \
1373 static inline unsigned \
1374 brw_eu_compact_inst_##name(const struct intel_device_info *devinfo, \
1375 const brw_eu_compact_inst *inst) \
1376 { \
1377 if (devinfo->ver >= 20) { \
1378 const unsigned k = hi20 - lo20 + 1; \
1379 return (brw_eu_compact_inst_bits(inst, hi20ex, lo20ex) << k | \
1380 brw_eu_compact_inst_bits(inst, hi20, lo20)); \
1381 } else if (devinfo->ver >= 12) { \
1382 return brw_eu_compact_inst_bits(inst, hi12, lo12); \
1383 } else { \
1384 return brw_eu_compact_inst_bits(inst, hi9, lo9); \
1385 } \
1386 }
1387
1388 F(src1_reg_nr, /* 9+ */ 63, 56, /* 12+ */ 63, 56)
1389 F(src0_reg_nr, /* 9+ */ 55, 48, /* 12+ */ 47, 40)
1390 F20(dst_reg_nr, /* 9+ */ 47, 40, /* 12+ */ 23, 16, /* 20+ */ 39, 32)
1391 F(src1_index, /* 9+ */ 39, 35, /* 12+ */ 55, 52)
1392 F20(src0_index, /* 9+ */ 34, 30, /* 12+ */ 51, 48, /* 20+ */ 25, 23)
1393 F(cmpt_control, /* 9+ */ 29, 29, /* 12+ */ 29, 29) /* Same location as brw_eu_inst */
1394 F(cond_modifier, /* 9+ */ 27, 24, /* 12+ */ -1, -1) /* Same location as brw_eu_inst */
1395 F(acc_wr_control, /* 9+ */ 23, 23, /* 12+ */ -1, -1)
1396 F20(subreg_index, /* 9+ */ 22, 18, /* 12+ */ 39, 35, /* 20+ */ 51, 48)
1397 FD20(datatype_index, /* 9+ */ 17, 13, /* 12+ */ 34, 30, /* 20+ */ 28, 26, 31, 30)
1398 F20(control_index, /* 9+ */ 12, 8, /* 12+ */ 28, 24, /* 20+ */ 22, 18)
1399 F20(swsb, /* 9+ */ -1, -1, /* 12+ */ 15, 8, /* 20+ */ 17, 8)
1400 F(debug_control, /* 9+ */ 7, 7, /* 12+ */ 7, 7)
1401 F(hw_opcode, /* 9+ */ 6, 0, /* 12+ */ 6, 0) /* Same location as brw_eu_inst */
1402
1403 static inline unsigned
brw_eu_compact_inst_imm(const struct intel_device_info * devinfo,const brw_eu_compact_inst * inst)1404 brw_eu_compact_inst_imm(const struct intel_device_info *devinfo,
1405 const brw_eu_compact_inst *inst)
1406 {
1407 if (devinfo->ver >= 12) {
1408 return brw_eu_compact_inst_bits(inst, 63, 52);
1409 } else {
1410 return (brw_eu_compact_inst_bits(inst, 39, 35) << 8) |
1411 (brw_eu_compact_inst_bits(inst, 63, 56));
1412 }
1413 }
1414
1415 /**
1416 * Compacted three-source instructions:
1417 * @{
1418 */
1419 F(3src_src2_reg_nr, /* 9+ */ 63, 57, /* 12+ */ 55, 48)
1420 F(3src_src1_reg_nr, /* 9+ */ 56, 50, /* 12+ */ 63, 56)
1421 F(3src_src0_reg_nr, /* 9+ */ 49, 43, /* 12+ */ 47, 40)
1422 F(3src_src2_subreg_nr, /* 9+ */ 42, 40, /* 12+ */ -1, -1)
1423 F(3src_src1_subreg_nr, /* 9+ */ 39, 37, /* 12+ */ -1, -1)
1424 F(3src_src0_subreg_nr, /* 9+ */ 36, 34, /* 12+ */ -1, -1)
1425 F(3src_src2_rep_ctrl, /* 9+ */ 33, 33, /* 12+ */ -1, -1)
1426 F(3src_src1_rep_ctrl, /* 9+ */ 32, 32, /* 12+ */ -1, -1)
1427 F(3src_saturate, /* 9+ */ 31, 31, /* 12+ */ -1, -1)
1428 F(3src_debug_control, /* 9+ */ 30, 30, /* 12+ */ 7, 7)
1429 F(3src_cmpt_control, /* 9+ */ 29, 29, /* 12+ */ 29, 29)
1430 F(3src_src0_rep_ctrl, /* 9+ */ 28, 28, /* 12+ */ -1, -1)
1431 /* Reserved */
1432 F20(3src_dst_reg_nr, /* 9+ */ 18, 12, /* 12+ */ 23, 16, /* 20+ */ 39, 32)
1433 F20(3src_source_index, /* 9+ */ 11, 10, /* 12+ */ 34, 30, /* 20+ */ 25, 22)
1434 FD20(3src_subreg_index, /* 9+ */ -1, -1, /* 12+ */ 39, 35, /* 20+ */ 28, 26, 31, 30)
1435 F20(3src_control_index, /* 9+ */ 9, 8, /* 12+ */ 28, 24, /* 20+ */ 21, 18)
1436 F20(3src_swsb, /* 9+ */ -1, -1, /* 12+ */ 15, 8, /* 20+ */ 17, 8)
1437 /* Bit 7 is Reserved (for future Opcode expansion) */
1438 F(3src_hw_opcode, /* 9+ */ 6, 0, /* 12+ */ 6, 0)
1439 /** @} */
1440
1441 #undef F
1442
1443 static inline void
brw_eu_inst_set_opcode(const struct brw_isa_info * isa,struct brw_eu_inst * inst,enum opcode opcode)1444 brw_eu_inst_set_opcode(const struct brw_isa_info *isa,
1445 struct brw_eu_inst *inst, enum opcode opcode)
1446 {
1447 brw_eu_inst_set_hw_opcode(isa->devinfo, inst, brw_opcode_encode(isa, opcode));
1448 }
1449
1450 static inline enum opcode
brw_eu_inst_opcode(const struct brw_isa_info * isa,const struct brw_eu_inst * inst)1451 brw_eu_inst_opcode(const struct brw_isa_info *isa,
1452 const struct brw_eu_inst *inst)
1453 {
1454 return brw_opcode_decode(isa, brw_eu_inst_hw_opcode(isa->devinfo, inst));
1455 }
1456
1457 #ifdef __cplusplus
1458 }
1459 #endif
1460