1 /*
2 * Copyright © 2008 Keith Packard
3 * Copyright © 2014 Intel Corporation
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting documentation, and
9 * that the name of the copyright holders not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. The copyright holders make no representations
12 * about the suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 * OF THIS SOFTWARE.
22 */
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "brw_disasm.h"
30 #include "brw_disasm_info.h"
31 #include "brw_eu_defines.h"
32 #include "brw_eu.h"
33 #include "brw_inst.h"
34 #include "brw_isa_info.h"
35 #include "brw_reg.h"
36 #include "brw_shader.h"
37 #include "util/half_float.h"
38
39 bool
brw_has_jip(const struct intel_device_info * devinfo,enum opcode opcode)40 brw_has_jip(const struct intel_device_info *devinfo, enum opcode opcode)
41 {
42 return opcode == BRW_OPCODE_IF ||
43 opcode == BRW_OPCODE_ELSE ||
44 opcode == BRW_OPCODE_ENDIF ||
45 opcode == BRW_OPCODE_WHILE ||
46 opcode == BRW_OPCODE_BREAK ||
47 opcode == BRW_OPCODE_CONTINUE ||
48 opcode == BRW_OPCODE_HALT;
49 }
50
51 bool
brw_has_uip(const struct intel_device_info * devinfo,enum opcode opcode)52 brw_has_uip(const struct intel_device_info *devinfo, enum opcode opcode)
53 {
54 return opcode == BRW_OPCODE_IF ||
55 opcode == BRW_OPCODE_ELSE ||
56 opcode == BRW_OPCODE_BREAK ||
57 opcode == BRW_OPCODE_CONTINUE ||
58 opcode == BRW_OPCODE_HALT;
59 }
60
61 static bool
has_branch_ctrl(const struct intel_device_info * devinfo,enum opcode opcode)62 has_branch_ctrl(const struct intel_device_info *devinfo, enum opcode opcode)
63 {
64 return opcode == BRW_OPCODE_IF ||
65 opcode == BRW_OPCODE_ELSE;
66 }
67
68 static bool
is_logic_instruction(unsigned opcode)69 is_logic_instruction(unsigned opcode)
70 {
71 return opcode == BRW_OPCODE_AND ||
72 opcode == BRW_OPCODE_NOT ||
73 opcode == BRW_OPCODE_OR ||
74 opcode == BRW_OPCODE_XOR;
75 }
76
77 static bool
is_send(unsigned opcode)78 is_send(unsigned opcode)
79 {
80 return opcode == BRW_OPCODE_SEND ||
81 opcode == BRW_OPCODE_SENDC ||
82 opcode == BRW_OPCODE_SENDS ||
83 opcode == BRW_OPCODE_SENDSC;
84 }
85
86 static bool
is_split_send(UNUSED const struct intel_device_info * devinfo,unsigned opcode)87 is_split_send(UNUSED const struct intel_device_info *devinfo, unsigned opcode)
88 {
89 if (devinfo->ver >= 12)
90 return is_send(opcode);
91 else
92 return opcode == BRW_OPCODE_SENDS ||
93 opcode == BRW_OPCODE_SENDSC;
94 }
95
96 const char *const conditional_modifier[16] = {
97 [BRW_CONDITIONAL_NONE] = "",
98 [BRW_CONDITIONAL_Z] = ".z",
99 [BRW_CONDITIONAL_NZ] = ".nz",
100 [BRW_CONDITIONAL_G] = ".g",
101 [BRW_CONDITIONAL_GE] = ".ge",
102 [BRW_CONDITIONAL_L] = ".l",
103 [BRW_CONDITIONAL_LE] = ".le",
104 [BRW_CONDITIONAL_R] = ".r",
105 [BRW_CONDITIONAL_O] = ".o",
106 [BRW_CONDITIONAL_U] = ".u",
107 };
108
109 static const char *const m_negate[2] = {
110 [0] = "",
111 [1] = "-",
112 };
113
114 static const char *const _abs[2] = {
115 [0] = "",
116 [1] = "(abs)",
117 };
118
119 static const char *const m_bitnot[2] = { "", "~" };
120
121 static const char *const vert_stride[16] = {
122 [0] = "0",
123 [1] = "1",
124 [2] = "2",
125 [3] = "4",
126 [4] = "8",
127 [5] = "16",
128 [6] = "32",
129 [15] = "VxH",
130 };
131
132 static const char *const width[8] = {
133 [0] = "1",
134 [1] = "2",
135 [2] = "4",
136 [3] = "8",
137 [4] = "16",
138 };
139
140 static const char *const horiz_stride[4] = {
141 [0] = "0",
142 [1] = "1",
143 [2] = "2",
144 [3] = "4"
145 };
146
147 static const char *const chan_sel[4] = {
148 [0] = "x",
149 [1] = "y",
150 [2] = "z",
151 [3] = "w",
152 };
153
154 static const char *const debug_ctrl[2] = {
155 [0] = "",
156 [1] = ".breakpoint"
157 };
158
159 static const char *const saturate[2] = {
160 [0] = "",
161 [1] = ".sat"
162 };
163
164 static const char *const cmpt_ctrl[2] = {
165 [0] = "",
166 [1] = "compacted"
167 };
168
169 static const char *const accwr[2] = {
170 [0] = "",
171 [1] = "AccWrEnable"
172 };
173
174 static const char *const branch_ctrl[2] = {
175 [0] = "",
176 [1] = "BranchCtrl"
177 };
178
179 static const char *const wectrl[2] = {
180 [0] = "",
181 [1] = "WE_all"
182 };
183
184 static const char *const exec_size[8] = {
185 [0] = "1",
186 [1] = "2",
187 [2] = "4",
188 [3] = "8",
189 [4] = "16",
190 [5] = "32"
191 };
192
193 static const char *const pred_inv[2] = {
194 [0] = "+",
195 [1] = "-"
196 };
197
198 const char *const pred_ctrl_align16[16] = {
199 [1] = "",
200 [2] = ".x",
201 [3] = ".y",
202 [4] = ".z",
203 [5] = ".w",
204 [6] = ".any4h",
205 [7] = ".all4h",
206 };
207
208 static const char *const pred_ctrl_align1[16] = {
209 [BRW_PREDICATE_NORMAL] = "",
210 [BRW_PREDICATE_ALIGN1_ANYV] = ".anyv",
211 [BRW_PREDICATE_ALIGN1_ALLV] = ".allv",
212 [BRW_PREDICATE_ALIGN1_ANY2H] = ".any2h",
213 [BRW_PREDICATE_ALIGN1_ALL2H] = ".all2h",
214 [BRW_PREDICATE_ALIGN1_ANY4H] = ".any4h",
215 [BRW_PREDICATE_ALIGN1_ALL4H] = ".all4h",
216 [BRW_PREDICATE_ALIGN1_ANY8H] = ".any8h",
217 [BRW_PREDICATE_ALIGN1_ALL8H] = ".all8h",
218 [BRW_PREDICATE_ALIGN1_ANY16H] = ".any16h",
219 [BRW_PREDICATE_ALIGN1_ALL16H] = ".all16h",
220 [BRW_PREDICATE_ALIGN1_ANY32H] = ".any32h",
221 [BRW_PREDICATE_ALIGN1_ALL32H] = ".all32h",
222 };
223
224 static const char *const xe2_pred_ctrl[4] = {
225 [BRW_PREDICATE_NORMAL] = "",
226 [XE2_PREDICATE_ANY] = ".any",
227 [XE2_PREDICATE_ALL] = ".all",
228 };
229
230 static const char *const thread_ctrl[4] = {
231 [BRW_THREAD_NORMAL] = "",
232 [BRW_THREAD_ATOMIC] = "atomic",
233 [BRW_THREAD_SWITCH] = "switch",
234 };
235
236 static const char *const dep_ctrl[4] = {
237 [0] = "",
238 [1] = "NoDDClr",
239 [2] = "NoDDChk",
240 [3] = "NoDDClr,NoDDChk",
241 };
242
243 static const char *const access_mode[2] = {
244 [0] = "align1",
245 [1] = "align16",
246 };
247
248 static const char *const reg_file[4] = {
249 [0] = "A",
250 [1] = "g",
251 [2] = "m",
252 [3] = "imm",
253 };
254
255 static const char *const writemask[16] = {
256 [0x0] = ".",
257 [0x1] = ".x",
258 [0x2] = ".y",
259 [0x3] = ".xy",
260 [0x4] = ".z",
261 [0x5] = ".xz",
262 [0x6] = ".yz",
263 [0x7] = ".xyz",
264 [0x8] = ".w",
265 [0x9] = ".xw",
266 [0xa] = ".yw",
267 [0xb] = ".xyw",
268 [0xc] = ".zw",
269 [0xd] = ".xzw",
270 [0xe] = ".yzw",
271 [0xf] = "",
272 };
273
274 static const char *const end_of_thread[2] = {
275 [0] = "",
276 [1] = "EOT"
277 };
278
279 static const char *const gfx6_sfid[16] = {
280 [BRW_SFID_NULL] = "null",
281 [BRW_SFID_MATH] = "math",
282 [BRW_SFID_SAMPLER] = "sampler",
283 [BRW_SFID_MESSAGE_GATEWAY] = "gateway",
284 [BRW_SFID_URB] = "urb",
285 [BRW_SFID_THREAD_SPAWNER] = "thread_spawner",
286 [GFX6_SFID_DATAPORT_SAMPLER_CACHE] = "dp_sampler",
287 [GFX6_SFID_DATAPORT_RENDER_CACHE] = "render",
288 [GFX6_SFID_DATAPORT_CONSTANT_CACHE] = "const",
289 [GFX7_SFID_DATAPORT_DATA_CACHE] = "data",
290 [GFX7_SFID_PIXEL_INTERPOLATOR] = "pixel interp",
291 [HSW_SFID_DATAPORT_DATA_CACHE_1] = "dp data 1",
292 [HSW_SFID_CRE] = "cre",
293 [GEN_RT_SFID_RAY_TRACE_ACCELERATOR] = "rt accel",
294 [GFX12_SFID_SLM] = "slm",
295 [GFX12_SFID_TGM] = "tgm",
296 [GFX12_SFID_UGM] = "ugm",
297 };
298
299 static const char *const gfx7_gateway_subfuncid[8] = {
300 [BRW_MESSAGE_GATEWAY_SFID_OPEN_GATEWAY] = "open",
301 [BRW_MESSAGE_GATEWAY_SFID_CLOSE_GATEWAY] = "close",
302 [BRW_MESSAGE_GATEWAY_SFID_FORWARD_MSG] = "forward msg",
303 [BRW_MESSAGE_GATEWAY_SFID_GET_TIMESTAMP] = "get timestamp",
304 [BRW_MESSAGE_GATEWAY_SFID_BARRIER_MSG] = "barrier msg",
305 [BRW_MESSAGE_GATEWAY_SFID_UPDATE_GATEWAY_STATE] = "update state",
306 [BRW_MESSAGE_GATEWAY_SFID_MMIO_READ_WRITE] = "mmio read/write",
307 };
308
309 static const char *const dp_rc_msg_type_gfx9[16] = {
310 [GFX9_DATAPORT_RC_RENDER_TARGET_WRITE] = "RT write",
311 [GFX9_DATAPORT_RC_RENDER_TARGET_READ] = "RT read"
312 };
313
314 static const char *const *
dp_rc_msg_type(const struct intel_device_info * devinfo)315 dp_rc_msg_type(const struct intel_device_info *devinfo)
316 {
317 return dp_rc_msg_type_gfx9;
318 }
319
320 static const char *const m_rt_write_subtype[] = {
321 [0b000] = "SIMD16",
322 [0b001] = "SIMD16/RepData",
323 [0b010] = "SIMD8/DualSrcLow",
324 [0b011] = "SIMD8/DualSrcHigh",
325 [0b100] = "SIMD8",
326 [0b101] = "SIMD8/ImageWrite", /* Gfx6+ */
327 [0b111] = "SIMD16/RepData-111", /* no idea how this is different than 1 */
328 };
329
330 static const char *const dp_dc0_msg_type_gfx7[16] = {
331 [GFX7_DATAPORT_DC_OWORD_BLOCK_READ] = "DC OWORD block read",
332 [GFX7_DATAPORT_DC_UNALIGNED_OWORD_BLOCK_READ] =
333 "DC unaligned OWORD block read",
334 [GFX7_DATAPORT_DC_OWORD_DUAL_BLOCK_READ] = "DC OWORD dual block read",
335 [GFX7_DATAPORT_DC_DWORD_SCATTERED_READ] = "DC DWORD scattered read",
336 [GFX7_DATAPORT_DC_BYTE_SCATTERED_READ] = "DC byte scattered read",
337 [GFX7_DATAPORT_DC_UNTYPED_SURFACE_READ] = "DC untyped surface read",
338 [GFX7_DATAPORT_DC_UNTYPED_ATOMIC_OP] = "DC untyped atomic",
339 [GFX7_DATAPORT_DC_MEMORY_FENCE] = "DC mfence",
340 [GFX7_DATAPORT_DC_OWORD_BLOCK_WRITE] = "DC OWORD block write",
341 [GFX7_DATAPORT_DC_OWORD_DUAL_BLOCK_WRITE] = "DC OWORD dual block write",
342 [GFX7_DATAPORT_DC_DWORD_SCATTERED_WRITE] = "DC DWORD scatterd write",
343 [GFX7_DATAPORT_DC_BYTE_SCATTERED_WRITE] = "DC byte scattered write",
344 [GFX7_DATAPORT_DC_UNTYPED_SURFACE_WRITE] = "DC untyped surface write",
345 };
346
347 static const char *const dp_oword_block_rw[8] = {
348 [BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW] = "1-low",
349 [BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH] = "1-high",
350 [BRW_DATAPORT_OWORD_BLOCK_2_OWORDS] = "2",
351 [BRW_DATAPORT_OWORD_BLOCK_4_OWORDS] = "4",
352 [BRW_DATAPORT_OWORD_BLOCK_8_OWORDS] = "8",
353 };
354
355 static const char *const dp_dc1_msg_type_hsw[32] = {
356 [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ] = "untyped surface read",
357 [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP] = "DC untyped atomic op",
358 [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2] =
359 "DC untyped 4x2 atomic op",
360 [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_READ] = "DC media block read",
361 [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ] = "DC typed surface read",
362 [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP] = "DC typed atomic",
363 [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2] = "DC typed 4x2 atomic op",
364 [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE] = "DC untyped surface write",
365 [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_WRITE] = "DC media block write",
366 [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP] = "DC atomic counter op",
367 [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2] =
368 "DC 4x2 atomic counter op",
369 [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE] = "DC typed surface write",
370 [GFX9_DATAPORT_DC_PORT1_A64_SCATTERED_READ] = "DC A64 scattered read",
371 [GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_READ] = "DC A64 untyped surface read",
372 [GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_OP] = "DC A64 untyped atomic op",
373 [GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_READ] = "DC A64 oword block read",
374 [GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_WRITE] = "DC A64 oword block write",
375 [GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_WRITE] = "DC A64 untyped surface write",
376 [GFX8_DATAPORT_DC_PORT1_A64_SCATTERED_WRITE] = "DC A64 scattered write",
377 [GFX9_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_FLOAT_OP] =
378 "DC untyped atomic float op",
379 [GFX9_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_FLOAT_OP] =
380 "DC A64 untyped atomic float op",
381 [GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_INT_OP] =
382 "DC A64 untyped atomic half-integer op",
383 [GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_FLOAT_OP] =
384 "DC A64 untyped atomic half-float op",
385 };
386
387 static const char *const aop[16] = {
388 [BRW_AOP_AND] = "and",
389 [BRW_AOP_OR] = "or",
390 [BRW_AOP_XOR] = "xor",
391 [BRW_AOP_MOV] = "mov",
392 [BRW_AOP_INC] = "inc",
393 [BRW_AOP_DEC] = "dec",
394 [BRW_AOP_ADD] = "add",
395 [BRW_AOP_SUB] = "sub",
396 [BRW_AOP_REVSUB] = "revsub",
397 [BRW_AOP_IMAX] = "imax",
398 [BRW_AOP_IMIN] = "imin",
399 [BRW_AOP_UMAX] = "umax",
400 [BRW_AOP_UMIN] = "umin",
401 [BRW_AOP_CMPWR] = "cmpwr",
402 [BRW_AOP_PREDEC] = "predec",
403 };
404
405 static const char *const aop_float[5] = {
406 [BRW_AOP_FMAX] = "fmax",
407 [BRW_AOP_FMIN] = "fmin",
408 [BRW_AOP_FCMPWR] = "fcmpwr",
409 [BRW_AOP_FADD] = "fadd",
410 };
411
412 static const char * const pixel_interpolator_msg_types[4] = {
413 [GFX7_PIXEL_INTERPOLATOR_LOC_SHARED_OFFSET] = "per_message_offset",
414 [GFX7_PIXEL_INTERPOLATOR_LOC_SAMPLE] = "sample_position",
415 [GFX7_PIXEL_INTERPOLATOR_LOC_CENTROID] = "centroid",
416 [GFX7_PIXEL_INTERPOLATOR_LOC_PER_SLOT_OFFSET] = "per_slot_offset",
417 };
418
419 static const char *const math_function[16] = {
420 [BRW_MATH_FUNCTION_INV] = "inv",
421 [BRW_MATH_FUNCTION_LOG] = "log",
422 [BRW_MATH_FUNCTION_EXP] = "exp",
423 [BRW_MATH_FUNCTION_SQRT] = "sqrt",
424 [BRW_MATH_FUNCTION_RSQ] = "rsq",
425 [BRW_MATH_FUNCTION_SIN] = "sin",
426 [BRW_MATH_FUNCTION_COS] = "cos",
427 [BRW_MATH_FUNCTION_SINCOS] = "sincos",
428 [BRW_MATH_FUNCTION_FDIV] = "fdiv",
429 [BRW_MATH_FUNCTION_POW] = "pow",
430 [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod",
431 [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT] = "intdiv",
432 [BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intmod",
433 [GFX8_MATH_FUNCTION_INVM] = "invm",
434 [GFX8_MATH_FUNCTION_RSQRTM] = "rsqrtm",
435 };
436
437 static const char *const sync_function[16] = {
438 [TGL_SYNC_NOP] = "nop",
439 [TGL_SYNC_ALLRD] = "allrd",
440 [TGL_SYNC_ALLWR] = "allwr",
441 [TGL_SYNC_FENCE] = "fence",
442 [TGL_SYNC_BAR] = "bar",
443 [TGL_SYNC_HOST] = "host",
444 };
445
446 static const char *const gfx7_urb_opcode[] = {
447 [BRW_URB_OPCODE_WRITE_HWORD] = "write HWord",
448 [BRW_URB_OPCODE_WRITE_OWORD] = "write OWord",
449 [BRW_URB_OPCODE_READ_HWORD] = "read HWord",
450 [BRW_URB_OPCODE_READ_OWORD] = "read OWord",
451 [GFX7_URB_OPCODE_ATOMIC_MOV] = "atomic mov", /* Gfx7+ */
452 [GFX7_URB_OPCODE_ATOMIC_INC] = "atomic inc", /* Gfx7+ */
453 [GFX8_URB_OPCODE_ATOMIC_ADD] = "atomic add", /* Gfx8+ */
454 [GFX8_URB_OPCODE_SIMD8_WRITE] = "SIMD8 write", /* Gfx8+ */
455 [GFX8_URB_OPCODE_SIMD8_READ] = "SIMD8 read", /* Gfx8+ */
456 [GFX125_URB_OPCODE_FENCE] = "fence", /* Gfx12.5+ */
457 /* [10-15] - reserved */
458 };
459
460 static const char *const urb_swizzle[4] = {
461 [BRW_URB_SWIZZLE_NONE] = "",
462 [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave",
463 [BRW_URB_SWIZZLE_TRANSPOSE] = "transpose",
464 };
465
466 static const char *const gfx5_sampler_msg_type[] = {
467 [GFX5_SAMPLER_MESSAGE_SAMPLE] = "sample",
468 [GFX5_SAMPLER_MESSAGE_SAMPLE_BIAS] = "sample_b",
469 [GFX5_SAMPLER_MESSAGE_SAMPLE_LOD] = "sample_l",
470 [GFX5_SAMPLER_MESSAGE_SAMPLE_COMPARE] = "sample_c",
471 [GFX5_SAMPLER_MESSAGE_SAMPLE_DERIVS] = "sample_d",
472 [GFX5_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE] = "sample_b_c",
473 [GFX5_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE] = "sample_l_c",
474 [GFX5_SAMPLER_MESSAGE_SAMPLE_LD] = "ld",
475 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4] = "gather4",
476 [GFX5_SAMPLER_MESSAGE_LOD] = "lod",
477 [GFX5_SAMPLER_MESSAGE_SAMPLE_RESINFO] = "resinfo",
478 [GFX6_SAMPLER_MESSAGE_SAMPLE_SAMPLEINFO] = "sampleinfo",
479 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4_C] = "gather4_c",
480 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO] = "gather4_po",
481 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_C] = "gather4_po_c",
482 [HSW_SAMPLER_MESSAGE_SAMPLE_DERIV_COMPARE] = "sample_d_c",
483 [GFX9_SAMPLER_MESSAGE_SAMPLE_LZ] = "sample_lz",
484 [GFX9_SAMPLER_MESSAGE_SAMPLE_C_LZ] = "sample_c_lz",
485 [GFX9_SAMPLER_MESSAGE_SAMPLE_LD_LZ] = "ld_lz",
486 [GFX9_SAMPLER_MESSAGE_SAMPLE_LD2DMS_W] = "ld2dms_w",
487 [GFX7_SAMPLER_MESSAGE_SAMPLE_LD_MCS] = "ld_mcs",
488 [GFX7_SAMPLER_MESSAGE_SAMPLE_LD2DMS] = "ld2dms",
489 [GFX7_SAMPLER_MESSAGE_SAMPLE_LD2DSS] = "ld2dss",
490 };
491
492 static const char *const xe2_sampler_msg_type[] = {
493 [GFX5_SAMPLER_MESSAGE_SAMPLE] = "sample",
494 [GFX5_SAMPLER_MESSAGE_SAMPLE_BIAS] = "sample_b",
495 [GFX5_SAMPLER_MESSAGE_SAMPLE_LOD] = "sample_l",
496 [GFX5_SAMPLER_MESSAGE_SAMPLE_COMPARE] = "sample_c",
497 [GFX5_SAMPLER_MESSAGE_SAMPLE_DERIVS] = "sample_d",
498 [GFX5_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE] = "sample_b_c",
499 [GFX5_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE] = "sample_l_c",
500 [GFX5_SAMPLER_MESSAGE_SAMPLE_LD] = "ld",
501 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4] = "gather4",
502 [GFX5_SAMPLER_MESSAGE_LOD] = "lod",
503 [GFX5_SAMPLER_MESSAGE_SAMPLE_RESINFO] = "resinfo",
504 [GFX6_SAMPLER_MESSAGE_SAMPLE_SAMPLEINFO] = "sampleinfo",
505 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4_C] = "gather4_c",
506 [GFX7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO] = "gather4_po",
507 [XE2_SAMPLER_MESSAGE_SAMPLE_MLOD] = "sample_mlod",
508 [XE2_SAMPLER_MESSAGE_SAMPLE_COMPARE_MLOD] = "sample_c_mlod",
509 [XE2_SAMPLER_MESSAGE_SAMPLE_GATHER4_I] = "gather4_i",
510 [XE2_SAMPLER_MESSAGE_SAMPLE_GATHER4_L] = "gather4_l",
511 [XE2_SAMPLER_MESSAGE_SAMPLE_GATHER4_B] = "gather4_b",
512 [XE2_SAMPLER_MESSAGE_SAMPLE_GATHER4_I_C] = "gather4_i_c",
513 [XE2_SAMPLER_MESSAGE_SAMPLE_GATHER4_L_C] = "gather4_l_c",
514 [XE2_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_L] = "gather4_po_l",
515 [XE2_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_L_C] = "gather4_po_l_c",
516 [XE2_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_B] = "gather4_po_b",
517 [HSW_SAMPLER_MESSAGE_SAMPLE_DERIV_COMPARE] = "sample_d_c",
518 [GFX9_SAMPLER_MESSAGE_SAMPLE_LZ] = "sample_lz",
519 [GFX9_SAMPLER_MESSAGE_SAMPLE_C_LZ] = "sample_c_lz",
520 [GFX9_SAMPLER_MESSAGE_SAMPLE_LD_LZ] = "ld_lz",
521 [GFX9_SAMPLER_MESSAGE_SAMPLE_LD2DMS_W] = "ld2dms_w",
522 [GFX7_SAMPLER_MESSAGE_SAMPLE_LD_MCS] = "ld_mcs",
523 [GFX7_SAMPLER_MESSAGE_SAMPLE_LD2DMS] = "ld2dms",
524 [GFX7_SAMPLER_MESSAGE_SAMPLE_LD2DSS] = "ld2dss",
525 };
526
527 static const char *const gfx5_sampler_simd_mode[7] = {
528 [BRW_SAMPLER_SIMD_MODE_SIMD4X2] = "SIMD4x2",
529 [BRW_SAMPLER_SIMD_MODE_SIMD8] = "SIMD8",
530 [BRW_SAMPLER_SIMD_MODE_SIMD16] = "SIMD16",
531 [BRW_SAMPLER_SIMD_MODE_SIMD32_64] = "SIMD32/64",
532 [GFX10_SAMPLER_SIMD_MODE_SIMD8H] = "SIMD8H",
533 [GFX10_SAMPLER_SIMD_MODE_SIMD16H] = "SIMD16H",
534 };
535
536 static const char *const xe2_sampler_simd_mode[7] = {
537 [XE2_SAMPLER_SIMD_MODE_SIMD16] = "SIMD16",
538 [XE2_SAMPLER_SIMD_MODE_SIMD32] = "SIMD32",
539 [XE2_SAMPLER_SIMD_MODE_SIMD16H] = "SIMD16H",
540 [XE2_SAMPLER_SIMD_MODE_SIMD32H] = "SIMD32H",
541 };
542
543 static const char *const lsc_operation[] = {
544 [LSC_OP_LOAD] = "load",
545 [LSC_OP_LOAD_CMASK] = "load_cmask",
546 [LSC_OP_STORE] = "store",
547 [LSC_OP_STORE_CMASK] = "store_cmask",
548 [LSC_OP_FENCE] = "fence",
549 [LSC_OP_ATOMIC_INC] = "atomic_inc",
550 [LSC_OP_ATOMIC_DEC] = "atomic_dec",
551 [LSC_OP_ATOMIC_LOAD] = "atomic_load",
552 [LSC_OP_ATOMIC_STORE] = "atomic_store",
553 [LSC_OP_ATOMIC_ADD] = "atomic_add",
554 [LSC_OP_ATOMIC_SUB] = "atomic_sub",
555 [LSC_OP_ATOMIC_MIN] = "atomic_min",
556 [LSC_OP_ATOMIC_MAX] = "atomic_max",
557 [LSC_OP_ATOMIC_UMIN] = "atomic_umin",
558 [LSC_OP_ATOMIC_UMAX] = "atomic_umax",
559 [LSC_OP_ATOMIC_CMPXCHG] = "atomic_cmpxchg",
560 [LSC_OP_ATOMIC_FADD] = "atomic_fadd",
561 [LSC_OP_ATOMIC_FSUB] = "atomic_fsub",
562 [LSC_OP_ATOMIC_FMIN] = "atomic_fmin",
563 [LSC_OP_ATOMIC_FMAX] = "atomic_fmax",
564 [LSC_OP_ATOMIC_FCMPXCHG] = "atomic_fcmpxchg",
565 [LSC_OP_ATOMIC_AND] = "atomic_and",
566 [LSC_OP_ATOMIC_OR] = "atomic_or",
567 [LSC_OP_ATOMIC_XOR] = "atomic_xor",
568 };
569
570 static const char *const lsc_addr_surface_type[] = {
571 [LSC_ADDR_SURFTYPE_FLAT] = "flat",
572 [LSC_ADDR_SURFTYPE_BSS] = "bss",
573 [LSC_ADDR_SURFTYPE_SS] = "ss",
574 [LSC_ADDR_SURFTYPE_BTI] = "bti",
575 };
576
577 static const char* const lsc_fence_scope[] = {
578 [LSC_FENCE_THREADGROUP] = "threadgroup",
579 [LSC_FENCE_LOCAL] = "local",
580 [LSC_FENCE_TILE] = "tile",
581 [LSC_FENCE_GPU] = "gpu",
582 [LSC_FENCE_ALL_GPU] = "all_gpu",
583 [LSC_FENCE_SYSTEM_RELEASE] = "system_release",
584 [LSC_FENCE_SYSTEM_ACQUIRE] = "system_acquire",
585 };
586
587 static const char* const lsc_flush_type[] = {
588 [LSC_FLUSH_TYPE_NONE] = "none",
589 [LSC_FLUSH_TYPE_EVICT] = "evict",
590 [LSC_FLUSH_TYPE_INVALIDATE] = "invalidate",
591 [LSC_FLUSH_TYPE_DISCARD] = "discard",
592 [LSC_FLUSH_TYPE_CLEAN] = "clean",
593 [LSC_FLUSH_TYPE_L3ONLY] = "l3only",
594 [LSC_FLUSH_TYPE_NONE_6] = "none_6",
595 };
596
597 static const char* const lsc_addr_size[] = {
598 [LSC_ADDR_SIZE_A16] = "a16",
599 [LSC_ADDR_SIZE_A32] = "a32",
600 [LSC_ADDR_SIZE_A64] = "a64",
601 };
602
603 static const char* const lsc_backup_fence_routing[] = {
604 [LSC_NORMAL_ROUTING] = "normal_routing",
605 [LSC_ROUTE_TO_LSC] = "route_to_lsc",
606 };
607
608 static const char* const lsc_data_size[] = {
609 [LSC_DATA_SIZE_D8] = "d8",
610 [LSC_DATA_SIZE_D16] = "d16",
611 [LSC_DATA_SIZE_D32] = "d32",
612 [LSC_DATA_SIZE_D64] = "d64",
613 [LSC_DATA_SIZE_D8U32] = "d8u32",
614 [LSC_DATA_SIZE_D16U32] = "d16u32",
615 [LSC_DATA_SIZE_D16BF32] = "d16bf32",
616 };
617
618 static const char* const lsc_vect_size_str[] = {
619 [LSC_VECT_SIZE_V1] = "V1",
620 [LSC_VECT_SIZE_V2] = "V2",
621 [LSC_VECT_SIZE_V3] = "V3",
622 [LSC_VECT_SIZE_V4] = "V4",
623 [LSC_VECT_SIZE_V8] = "V8",
624 [LSC_VECT_SIZE_V16] = "V16",
625 [LSC_VECT_SIZE_V32] = "V32",
626 [LSC_VECT_SIZE_V64] = "V64",
627 };
628
629 static const char* const lsc_cmask_str[] = {
630 [LSC_CMASK_X] = "x",
631 [LSC_CMASK_Y] = "y",
632 [LSC_CMASK_XY] = "xy",
633 [LSC_CMASK_Z] = "z",
634 [LSC_CMASK_XZ] = "xz",
635 [LSC_CMASK_YZ] = "yz",
636 [LSC_CMASK_XYZ] = "xyz",
637 [LSC_CMASK_W] = "w",
638 [LSC_CMASK_XW] = "xw",
639 [LSC_CMASK_YW] = "yw",
640 [LSC_CMASK_XYW] = "xyw",
641 [LSC_CMASK_ZW] = "zw",
642 [LSC_CMASK_XZW] = "xzw",
643 [LSC_CMASK_YZW] = "yzw",
644 [LSC_CMASK_XYZW] = "xyzw",
645 };
646
647 static const char* const lsc_cache_load[] = {
648 [LSC_CACHE_LOAD_L1STATE_L3MOCS] = "L1STATE_L3MOCS",
649 [LSC_CACHE_LOAD_L1UC_L3UC] = "L1UC_L3UC",
650 [LSC_CACHE_LOAD_L1UC_L3C] = "L1UC_L3C",
651 [LSC_CACHE_LOAD_L1C_L3UC] = "L1C_L3UC",
652 [LSC_CACHE_LOAD_L1C_L3C] = "L1C_L3C",
653 [LSC_CACHE_LOAD_L1S_L3UC] = "L1S_L3UC",
654 [LSC_CACHE_LOAD_L1S_L3C] = "L1S_L3C",
655 [LSC_CACHE_LOAD_L1IAR_L3C] = "L1IAR_L3C",
656 };
657
658 static const char* const lsc_cache_store[] = {
659 [LSC_CACHE_STORE_L1STATE_L3MOCS] = "L1STATE_L3MOCS",
660 [LSC_CACHE_STORE_L1UC_L3UC] = "L1UC_L3UC",
661 [LSC_CACHE_STORE_L1UC_L3WB] = "L1UC_L3WB",
662 [LSC_CACHE_STORE_L1WT_L3UC] = "L1WT_L3UC",
663 [LSC_CACHE_STORE_L1WT_L3WB] = "L1WT_L3WB",
664 [LSC_CACHE_STORE_L1S_L3UC] = "L1S_L3UC",
665 [LSC_CACHE_STORE_L1S_L3WB] = "L1S_L3WB",
666 [LSC_CACHE_STORE_L1WB_L3WB] = "L1WB_L3WB",
667 };
668
669 static const char* const xe2_lsc_cache_load[] = {
670 [XE2_LSC_CACHE_LOAD_L1STATE_L3MOCS] = "L1STATE_L3MOCS",
671 [XE2_LSC_CACHE_LOAD_L1UC_L3UC] = "L1UC_L3UC",
672 [XE2_LSC_CACHE_LOAD_L1UC_L3C] = "L1UC_L3C",
673 [XE2_LSC_CACHE_LOAD_L1UC_L3CC] = "L1UC_L3CC",
674 [XE2_LSC_CACHE_LOAD_L1C_L3UC] = "L1C_L3UC",
675 [XE2_LSC_CACHE_LOAD_L1C_L3C] = "L1C_L3C",
676 [XE2_LSC_CACHE_LOAD_L1C_L3CC] = "L1C_L3CC",
677 [XE2_LSC_CACHE_LOAD_L1S_L3UC] = "L1S_L3UC",
678 [XE2_LSC_CACHE_LOAD_L1S_L3C] = "L1S_L3C",
679 [XE2_LSC_CACHE_LOAD_L1IAR_L3IAR] = "L1IAR_L3IAR",
680 };
681
682 static const char* const xe2_lsc_cache_store[] = {
683 [XE2_LSC_CACHE_STORE_L1STATE_L3MOCS] = "L1STATE_L3MOCS",
684 [XE2_LSC_CACHE_STORE_L1UC_L3UC] = "L1UC_L3UC",
685 [XE2_LSC_CACHE_STORE_L1UC_L3WB] = "L1UC_L3WB",
686 [XE2_LSC_CACHE_STORE_L1WT_L3UC] = "L1WT_L3UC",
687 [XE2_LSC_CACHE_STORE_L1WT_L3WB] = "L1WT_L3WB",
688 [XE2_LSC_CACHE_STORE_L1S_L3UC] = "L1S_L3UC",
689 [XE2_LSC_CACHE_STORE_L1S_L3WB] = "L1S_L3WB",
690 [XE2_LSC_CACHE_STORE_L1WB_L3WB] = "L1WB_L3WB",
691 };
692
693 static const char* const dpas_systolic_depth[4] = {
694 [0] = "16",
695 [1] = "2",
696 [2] = "4",
697 [3] = "8"
698 };
699
700 static int column;
701
702 static int
string(FILE * file,const char * string)703 string(FILE *file, const char *string)
704 {
705 fputs(string, file);
706 column += strlen(string);
707 return 0;
708 }
709
710 static int
711 format(FILE *f, const char *format, ...) PRINTFLIKE(2, 3);
712
713 static int
format(FILE * f,const char * format,...)714 format(FILE *f, const char *format, ...)
715 {
716 char buf[1024];
717 va_list args;
718 va_start(args, format);
719
720 vsnprintf(buf, sizeof(buf) - 1, format, args);
721 va_end(args);
722 string(f, buf);
723 return 0;
724 }
725
726 static int
newline(FILE * f)727 newline(FILE *f)
728 {
729 putc('\n', f);
730 column = 0;
731 return 0;
732 }
733
734 static int
pad(FILE * f,int c)735 pad(FILE *f, int c)
736 {
737 do
738 string(f, " ");
739 while (column < c);
740 return 0;
741 }
742
743 static int
control(FILE * file,const char * name,const char * const ctrl[],unsigned id,int * space)744 control(FILE *file, const char *name, const char *const ctrl[],
745 unsigned id, int *space)
746 {
747 if (!ctrl[id]) {
748 fprintf(file, "*** invalid %s value %d ", name, id);
749 return 1;
750 }
751 if (ctrl[id][0]) {
752 if (space && *space)
753 string(file, " ");
754 string(file, ctrl[id]);
755 if (space)
756 *space = 1;
757 }
758 return 0;
759 }
760
761 static int
print_opcode(FILE * file,const struct brw_isa_info * isa,enum opcode id)762 print_opcode(FILE *file, const struct brw_isa_info *isa,
763 enum opcode id)
764 {
765 const struct opcode_desc *desc = brw_opcode_desc(isa, id);
766 if (!desc) {
767 format(file, "*** invalid opcode value %d ", id);
768 return 1;
769 }
770 string(file, desc->name);
771 return 0;
772 }
773
774 static int
reg(FILE * file,unsigned _reg_file,unsigned _reg_nr)775 reg(FILE *file, unsigned _reg_file, unsigned _reg_nr)
776 {
777 int err = 0;
778
779 if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
780 switch (_reg_nr & 0xf0) {
781 case BRW_ARF_NULL:
782 string(file, "null");
783 break;
784 case BRW_ARF_ADDRESS:
785 format(file, "a%d", _reg_nr & 0x0f);
786 break;
787 case BRW_ARF_ACCUMULATOR:
788 format(file, "acc%d", _reg_nr & 0x0f);
789 break;
790 case BRW_ARF_FLAG:
791 format(file, "f%d", _reg_nr & 0x0f);
792 break;
793 case BRW_ARF_MASK:
794 format(file, "mask%d", _reg_nr & 0x0f);
795 break;
796 case BRW_ARF_MASK_STACK:
797 format(file, "ms%d", _reg_nr & 0x0f);
798 break;
799 case BRW_ARF_MASK_STACK_DEPTH:
800 format(file, "msd%d", _reg_nr & 0x0f);
801 break;
802 case BRW_ARF_STATE:
803 format(file, "sr%d", _reg_nr & 0x0f);
804 break;
805 case BRW_ARF_CONTROL:
806 format(file, "cr%d", _reg_nr & 0x0f);
807 break;
808 case BRW_ARF_NOTIFICATION_COUNT:
809 format(file, "n%d", _reg_nr & 0x0f);
810 break;
811 case BRW_ARF_IP:
812 string(file, "ip");
813 return -1;
814 break;
815 case BRW_ARF_TDR:
816 format(file, "tdr0");
817 return -1;
818 case BRW_ARF_TIMESTAMP:
819 format(file, "tm%d", _reg_nr & 0x0f);
820 break;
821 default:
822 format(file, "ARF%d", _reg_nr);
823 break;
824 }
825 } else {
826 err |= control(file, "src reg file", reg_file, _reg_file, NULL);
827 format(file, "%d", _reg_nr);
828 }
829 return err;
830 }
831
832 static int
dest(FILE * file,const struct brw_isa_info * isa,const brw_inst * inst)833 dest(FILE *file, const struct brw_isa_info *isa, const brw_inst *inst)
834 {
835 const struct intel_device_info *devinfo = isa->devinfo;
836 enum brw_reg_type type = brw_inst_dst_type(devinfo, inst);
837 unsigned elem_size = brw_reg_type_to_size(type);
838 int err = 0;
839
840 if (is_split_send(devinfo, brw_inst_opcode(isa, inst))) {
841 /* These are fixed for split sends */
842 type = BRW_REGISTER_TYPE_UD;
843 elem_size = 4;
844 if (devinfo->ver >= 12) {
845 err |= reg(file, brw_inst_send_dst_reg_file(devinfo, inst),
846 brw_inst_dst_da_reg_nr(devinfo, inst));
847 string(file, brw_reg_type_to_letters(type));
848 } else if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
849 err |= reg(file, brw_inst_send_dst_reg_file(devinfo, inst),
850 brw_inst_dst_da_reg_nr(devinfo, inst));
851 unsigned subreg_nr = brw_inst_dst_da16_subreg_nr(devinfo, inst);
852 if (subreg_nr)
853 format(file, ".%u", subreg_nr);
854 string(file, brw_reg_type_to_letters(type));
855 } else {
856 string(file, "g[a0");
857 if (brw_inst_dst_ia_subreg_nr(devinfo, inst))
858 format(file, ".%"PRIu64, brw_inst_dst_ia_subreg_nr(devinfo, inst) /
859 elem_size);
860 if (brw_inst_send_dst_ia16_addr_imm(devinfo, inst))
861 format(file, " %d", brw_inst_send_dst_ia16_addr_imm(devinfo, inst));
862 string(file, "]<");
863 string(file, brw_reg_type_to_letters(type));
864 }
865 } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
866 if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
867 err |= reg(file, brw_inst_dst_reg_file(devinfo, inst),
868 brw_inst_dst_da_reg_nr(devinfo, inst));
869 if (err == -1)
870 return 0;
871 if (brw_inst_dst_da1_subreg_nr(devinfo, inst))
872 format(file, ".%"PRIu64, brw_inst_dst_da1_subreg_nr(devinfo, inst) /
873 elem_size);
874 string(file, "<");
875 err |= control(file, "horiz stride", horiz_stride,
876 brw_inst_dst_hstride(devinfo, inst), NULL);
877 string(file, ">");
878 string(file, brw_reg_type_to_letters(type));
879 } else {
880 string(file, "g[a0");
881 if (brw_inst_dst_ia_subreg_nr(devinfo, inst))
882 format(file, ".%"PRIu64, brw_inst_dst_ia_subreg_nr(devinfo, inst) /
883 elem_size);
884 if (brw_inst_dst_ia1_addr_imm(devinfo, inst))
885 format(file, " %d", brw_inst_dst_ia1_addr_imm(devinfo, inst));
886 string(file, "]<");
887 err |= control(file, "horiz stride", horiz_stride,
888 brw_inst_dst_hstride(devinfo, inst), NULL);
889 string(file, ">");
890 string(file, brw_reg_type_to_letters(type));
891 }
892 } else {
893 if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
894 err |= reg(file, brw_inst_dst_reg_file(devinfo, inst),
895 brw_inst_dst_da_reg_nr(devinfo, inst));
896 if (err == -1)
897 return 0;
898 if (brw_inst_dst_da16_subreg_nr(devinfo, inst))
899 format(file, ".%u", 16 / elem_size);
900 string(file, "<1>");
901 err |= control(file, "writemask", writemask,
902 brw_inst_da16_writemask(devinfo, inst), NULL);
903 string(file, brw_reg_type_to_letters(type));
904 } else {
905 err = 1;
906 string(file, "Indirect align16 address mode not supported");
907 }
908 }
909
910 return 0;
911 }
912
913 static int
dest_3src(FILE * file,const struct intel_device_info * devinfo,const brw_inst * inst)914 dest_3src(FILE *file, const struct intel_device_info *devinfo,
915 const brw_inst *inst)
916 {
917 bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1;
918 int err = 0;
919 uint32_t reg_file;
920 unsigned subreg_nr;
921 enum brw_reg_type type;
922
923 if (devinfo->ver < 10 && is_align1)
924 return 0;
925
926 if (devinfo->ver >= 12)
927 reg_file = brw_inst_3src_a1_dst_reg_file(devinfo, inst);
928 else if (is_align1 && brw_inst_3src_a1_dst_reg_file(devinfo, inst))
929 reg_file = BRW_ARCHITECTURE_REGISTER_FILE;
930 else
931 reg_file = BRW_GENERAL_REGISTER_FILE;
932
933 err |= reg(file, reg_file, brw_inst_3src_dst_reg_nr(devinfo, inst));
934 if (err == -1)
935 return 0;
936
937 if (is_align1) {
938 type = brw_inst_3src_a1_dst_type(devinfo, inst);
939 subreg_nr = brw_inst_3src_a1_dst_subreg_nr(devinfo, inst);
940 } else {
941 type = brw_inst_3src_a16_dst_type(devinfo, inst);
942 subreg_nr = brw_inst_3src_a16_dst_subreg_nr(devinfo, inst) * 4;
943 }
944 subreg_nr /= brw_reg_type_to_size(type);
945
946 if (subreg_nr)
947 format(file, ".%u", subreg_nr);
948 string(file, "<1>");
949
950 if (!is_align1) {
951 err |= control(file, "writemask", writemask,
952 brw_inst_3src_a16_dst_writemask(devinfo, inst), NULL);
953 }
954 string(file, brw_reg_type_to_letters(type));
955
956 return 0;
957 }
958
959 static int
dest_dpas_3src(FILE * file,const struct intel_device_info * devinfo,const brw_inst * inst)960 dest_dpas_3src(FILE *file, const struct intel_device_info *devinfo,
961 const brw_inst *inst)
962 {
963 uint32_t reg_file = brw_inst_dpas_3src_dst_reg_file(devinfo, inst);
964
965 if (reg(file, reg_file, brw_inst_dpas_3src_dst_reg_nr(devinfo, inst)) == -1)
966 return 0;
967
968 enum brw_reg_type type = brw_inst_dpas_3src_dst_type(devinfo, inst);
969 unsigned subreg_nr = brw_inst_dpas_3src_dst_subreg_nr(devinfo, inst);
970
971 if (subreg_nr)
972 format(file, ".%u", subreg_nr);
973 string(file, "<1>");
974
975 string(file, brw_reg_type_to_letters(type));
976
977 return 0;
978 }
979
980 static int
src_align1_region(FILE * file,unsigned _vert_stride,unsigned _width,unsigned _horiz_stride)981 src_align1_region(FILE *file,
982 unsigned _vert_stride, unsigned _width,
983 unsigned _horiz_stride)
984 {
985 int err = 0;
986 string(file, "<");
987 err |= control(file, "vert stride", vert_stride, _vert_stride, NULL);
988 string(file, ",");
989 err |= control(file, "width", width, _width, NULL);
990 string(file, ",");
991 err |= control(file, "horiz_stride", horiz_stride, _horiz_stride, NULL);
992 string(file, ">");
993 return err;
994 }
995
996 static int
src_da1(FILE * file,const struct intel_device_info * devinfo,unsigned opcode,enum brw_reg_type type,unsigned _reg_file,unsigned _vert_stride,unsigned _width,unsigned _horiz_stride,unsigned reg_num,unsigned sub_reg_num,unsigned __abs,unsigned _negate)997 src_da1(FILE *file,
998 const struct intel_device_info *devinfo,
999 unsigned opcode,
1000 enum brw_reg_type type, unsigned _reg_file,
1001 unsigned _vert_stride, unsigned _width, unsigned _horiz_stride,
1002 unsigned reg_num, unsigned sub_reg_num, unsigned __abs,
1003 unsigned _negate)
1004 {
1005 int err = 0;
1006
1007 if (is_logic_instruction(opcode))
1008 err |= control(file, "bitnot", m_bitnot, _negate, NULL);
1009 else
1010 err |= control(file, "negate", m_negate, _negate, NULL);
1011
1012 err |= control(file, "abs", _abs, __abs, NULL);
1013
1014 err |= reg(file, _reg_file, reg_num);
1015 if (err == -1)
1016 return 0;
1017 if (sub_reg_num) {
1018 unsigned elem_size = brw_reg_type_to_size(type);
1019 format(file, ".%d", sub_reg_num / elem_size); /* use formal style like spec */
1020 }
1021 src_align1_region(file, _vert_stride, _width, _horiz_stride);
1022 string(file, brw_reg_type_to_letters(type));
1023 return err;
1024 }
1025
1026 static int
src_ia1(FILE * file,const struct intel_device_info * devinfo,unsigned opcode,enum brw_reg_type type,int _addr_imm,unsigned _addr_subreg_nr,unsigned _negate,unsigned __abs,unsigned _horiz_stride,unsigned _width,unsigned _vert_stride)1027 src_ia1(FILE *file,
1028 const struct intel_device_info *devinfo,
1029 unsigned opcode,
1030 enum brw_reg_type type,
1031 int _addr_imm,
1032 unsigned _addr_subreg_nr,
1033 unsigned _negate,
1034 unsigned __abs,
1035 unsigned _horiz_stride, unsigned _width, unsigned _vert_stride)
1036 {
1037 int err = 0;
1038
1039 if (is_logic_instruction(opcode))
1040 err |= control(file, "bitnot", m_bitnot, _negate, NULL);
1041 else
1042 err |= control(file, "negate", m_negate, _negate, NULL);
1043
1044 err |= control(file, "abs", _abs, __abs, NULL);
1045
1046 string(file, "g[a0");
1047 if (_addr_subreg_nr)
1048 format(file, ".%d", _addr_subreg_nr);
1049 if (_addr_imm)
1050 format(file, " %d", _addr_imm);
1051 string(file, "]");
1052 src_align1_region(file, _vert_stride, _width, _horiz_stride);
1053 string(file, brw_reg_type_to_letters(type));
1054 return err;
1055 }
1056
1057 static int
src_swizzle(FILE * file,unsigned swiz)1058 src_swizzle(FILE *file, unsigned swiz)
1059 {
1060 unsigned x = BRW_GET_SWZ(swiz, BRW_CHANNEL_X);
1061 unsigned y = BRW_GET_SWZ(swiz, BRW_CHANNEL_Y);
1062 unsigned z = BRW_GET_SWZ(swiz, BRW_CHANNEL_Z);
1063 unsigned w = BRW_GET_SWZ(swiz, BRW_CHANNEL_W);
1064 int err = 0;
1065
1066 if (x == y && x == z && x == w) {
1067 string(file, ".");
1068 err |= control(file, "channel select", chan_sel, x, NULL);
1069 } else if (swiz != BRW_SWIZZLE_XYZW) {
1070 string(file, ".");
1071 err |= control(file, "channel select", chan_sel, x, NULL);
1072 err |= control(file, "channel select", chan_sel, y, NULL);
1073 err |= control(file, "channel select", chan_sel, z, NULL);
1074 err |= control(file, "channel select", chan_sel, w, NULL);
1075 }
1076 return err;
1077 }
1078
1079 static int
src_da16(FILE * file,const struct intel_device_info * devinfo,unsigned opcode,enum brw_reg_type type,unsigned _reg_file,unsigned _vert_stride,unsigned _reg_nr,unsigned _subreg_nr,unsigned __abs,unsigned _negate,unsigned swz_x,unsigned swz_y,unsigned swz_z,unsigned swz_w)1080 src_da16(FILE *file,
1081 const struct intel_device_info *devinfo,
1082 unsigned opcode,
1083 enum brw_reg_type type,
1084 unsigned _reg_file,
1085 unsigned _vert_stride,
1086 unsigned _reg_nr,
1087 unsigned _subreg_nr,
1088 unsigned __abs,
1089 unsigned _negate,
1090 unsigned swz_x, unsigned swz_y, unsigned swz_z, unsigned swz_w)
1091 {
1092 int err = 0;
1093
1094 if (is_logic_instruction(opcode))
1095 err |= control(file, "bitnot", m_bitnot, _negate, NULL);
1096 else
1097 err |= control(file, "negate", m_negate, _negate, NULL);
1098
1099 err |= control(file, "abs", _abs, __abs, NULL);
1100
1101 err |= reg(file, _reg_file, _reg_nr);
1102 if (err == -1)
1103 return 0;
1104 if (_subreg_nr) {
1105 unsigned elem_size = brw_reg_type_to_size(type);
1106
1107 /* bit4 for subreg number byte addressing. Make this same meaning as
1108 in da1 case, so output looks consistent. */
1109 format(file, ".%d", 16 / elem_size);
1110 }
1111 string(file, "<");
1112 err |= control(file, "vert stride", vert_stride, _vert_stride, NULL);
1113 string(file, ">");
1114 err |= src_swizzle(file, BRW_SWIZZLE4(swz_x, swz_y, swz_z, swz_w));
1115 string(file, brw_reg_type_to_letters(type));
1116 return err;
1117 }
1118
1119 static enum brw_vertical_stride
vstride_from_align1_3src_vstride(const struct intel_device_info * devinfo,enum gfx10_align1_3src_vertical_stride vstride)1120 vstride_from_align1_3src_vstride(const struct intel_device_info *devinfo,
1121 enum gfx10_align1_3src_vertical_stride vstride)
1122 {
1123 switch (vstride) {
1124 case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_0: return BRW_VERTICAL_STRIDE_0;
1125 case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_2:
1126 if (devinfo->ver >= 12)
1127 return BRW_VERTICAL_STRIDE_1;
1128 else
1129 return BRW_VERTICAL_STRIDE_2;
1130 case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_4: return BRW_VERTICAL_STRIDE_4;
1131 case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_8: return BRW_VERTICAL_STRIDE_8;
1132 default:
1133 unreachable("not reached");
1134 }
1135 }
1136
1137 static enum brw_horizontal_stride
hstride_from_align1_3src_hstride(enum gfx10_align1_3src_src_horizontal_stride hstride)1138 hstride_from_align1_3src_hstride(enum gfx10_align1_3src_src_horizontal_stride hstride)
1139 {
1140 switch (hstride) {
1141 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_0: return BRW_HORIZONTAL_STRIDE_0;
1142 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_1: return BRW_HORIZONTAL_STRIDE_1;
1143 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_2: return BRW_HORIZONTAL_STRIDE_2;
1144 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_4: return BRW_HORIZONTAL_STRIDE_4;
1145 default:
1146 unreachable("not reached");
1147 }
1148 }
1149
1150 static enum brw_vertical_stride
vstride_from_align1_3src_hstride(enum gfx10_align1_3src_src_horizontal_stride hstride)1151 vstride_from_align1_3src_hstride(enum gfx10_align1_3src_src_horizontal_stride hstride)
1152 {
1153 switch (hstride) {
1154 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_0: return BRW_VERTICAL_STRIDE_0;
1155 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_1: return BRW_VERTICAL_STRIDE_1;
1156 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_2: return BRW_VERTICAL_STRIDE_2;
1157 case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_4: return BRW_VERTICAL_STRIDE_4;
1158 default:
1159 unreachable("not reached");
1160 }
1161 }
1162
1163 /* From "GFX10 Regioning Rules for Align1 Ternary Operations" in the
1164 * "Register Region Restrictions" documentation
1165 */
1166 static enum brw_width
implied_width(enum brw_vertical_stride _vert_stride,enum brw_horizontal_stride _horiz_stride)1167 implied_width(enum brw_vertical_stride _vert_stride,
1168 enum brw_horizontal_stride _horiz_stride)
1169 {
1170 /* "1. Width is 1 when Vertical and Horizontal Strides are both zero." */
1171 if (_vert_stride == BRW_VERTICAL_STRIDE_0 &&
1172 _horiz_stride == BRW_HORIZONTAL_STRIDE_0) {
1173 return BRW_WIDTH_1;
1174
1175 /* "2. Width is equal to vertical stride when Horizontal Stride is zero." */
1176 } else if (_horiz_stride == BRW_HORIZONTAL_STRIDE_0) {
1177 switch (_vert_stride) {
1178 case BRW_VERTICAL_STRIDE_1: return BRW_WIDTH_1;
1179 case BRW_VERTICAL_STRIDE_2: return BRW_WIDTH_2;
1180 case BRW_VERTICAL_STRIDE_4: return BRW_WIDTH_4;
1181 case BRW_VERTICAL_STRIDE_8: return BRW_WIDTH_8;
1182 case BRW_VERTICAL_STRIDE_0:
1183 default:
1184 unreachable("not reached");
1185 }
1186
1187 } else {
1188 /* FINISHME: Implement these: */
1189
1190 /* "3. Width is equal to Vertical Stride/Horizontal Stride when both
1191 * Strides are non-zero.
1192 *
1193 * 4. Vertical Stride must not be zero if Horizontal Stride is non-zero.
1194 * This implies Vertical Stride is always greater than Horizontal
1195 * Stride."
1196 *
1197 * Given these statements and the knowledge that the stride and width
1198 * values are encoded in logarithmic form, we can perform the division
1199 * by just subtracting.
1200 */
1201 return _vert_stride - _horiz_stride;
1202 }
1203 }
1204
1205 static int
src0_3src(FILE * file,const struct intel_device_info * devinfo,const brw_inst * inst)1206 src0_3src(FILE *file, const struct intel_device_info *devinfo,
1207 const brw_inst *inst)
1208 {
1209 int err = 0;
1210 unsigned reg_nr, subreg_nr;
1211 enum brw_reg_file _file;
1212 enum brw_reg_type type;
1213 enum brw_vertical_stride _vert_stride;
1214 enum brw_width _width;
1215 enum brw_horizontal_stride _horiz_stride;
1216 bool is_scalar_region;
1217 bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1;
1218
1219 if (devinfo->ver < 10 && is_align1)
1220 return 0;
1221
1222 if (is_align1) {
1223 if (devinfo->ver >= 12 && !brw_inst_3src_a1_src0_is_imm(devinfo, inst)) {
1224 _file = brw_inst_3src_a1_src0_reg_file(devinfo, inst);
1225 } else if (brw_inst_3src_a1_src0_reg_file(devinfo, inst) ==
1226 BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE) {
1227 _file = BRW_GENERAL_REGISTER_FILE;
1228 } else if (brw_inst_3src_a1_src0_type(devinfo, inst) ==
1229 BRW_REGISTER_TYPE_NF) {
1230 _file = BRW_ARCHITECTURE_REGISTER_FILE;
1231 } else {
1232 _file = BRW_IMMEDIATE_VALUE;
1233 uint16_t imm_val = brw_inst_3src_a1_src0_imm(devinfo, inst);
1234 enum brw_reg_type type = brw_inst_3src_a1_src0_type(devinfo, inst);
1235
1236 if (type == BRW_REGISTER_TYPE_W) {
1237 format(file, "%dW", imm_val);
1238 } else if (type == BRW_REGISTER_TYPE_UW) {
1239 format(file, "0x%04xUW", imm_val);
1240 } else if (type == BRW_REGISTER_TYPE_HF) {
1241 format(file, "0x%04xHF", imm_val);
1242 }
1243 return 0;
1244 }
1245
1246 reg_nr = brw_inst_3src_src0_reg_nr(devinfo, inst);
1247 subreg_nr = brw_inst_3src_a1_src0_subreg_nr(devinfo, inst);
1248 type = brw_inst_3src_a1_src0_type(devinfo, inst);
1249 _vert_stride = vstride_from_align1_3src_vstride(
1250 devinfo, brw_inst_3src_a1_src0_vstride(devinfo, inst));
1251 _horiz_stride = hstride_from_align1_3src_hstride(
1252 brw_inst_3src_a1_src0_hstride(devinfo, inst));
1253 _width = implied_width(_vert_stride, _horiz_stride);
1254 } else {
1255 _file = BRW_GENERAL_REGISTER_FILE;
1256 reg_nr = brw_inst_3src_src0_reg_nr(devinfo, inst);
1257 subreg_nr = brw_inst_3src_a16_src0_subreg_nr(devinfo, inst) * 4;
1258 type = brw_inst_3src_a16_src_type(devinfo, inst);
1259
1260 if (brw_inst_3src_a16_src0_rep_ctrl(devinfo, inst)) {
1261 _vert_stride = BRW_VERTICAL_STRIDE_0;
1262 _width = BRW_WIDTH_1;
1263 _horiz_stride = BRW_HORIZONTAL_STRIDE_0;
1264 } else {
1265 _vert_stride = BRW_VERTICAL_STRIDE_4;
1266 _width = BRW_WIDTH_4;
1267 _horiz_stride = BRW_HORIZONTAL_STRIDE_1;
1268 }
1269 }
1270 is_scalar_region = _vert_stride == BRW_VERTICAL_STRIDE_0 &&
1271 _width == BRW_WIDTH_1 &&
1272 _horiz_stride == BRW_HORIZONTAL_STRIDE_0;
1273
1274 subreg_nr /= brw_reg_type_to_size(type);
1275
1276 err |= control(file, "negate", m_negate,
1277 brw_inst_3src_src0_negate(devinfo, inst), NULL);
1278 err |= control(file, "abs", _abs, brw_inst_3src_src0_abs(devinfo, inst), NULL);
1279
1280 err |= reg(file, _file, reg_nr);
1281 if (err == -1)
1282 return 0;
1283 if (subreg_nr || is_scalar_region)
1284 format(file, ".%d", subreg_nr);
1285 src_align1_region(file, _vert_stride, _width, _horiz_stride);
1286 if (!is_scalar_region && !is_align1)
1287 err |= src_swizzle(file, brw_inst_3src_a16_src0_swizzle(devinfo, inst));
1288 string(file, brw_reg_type_to_letters(type));
1289 return err;
1290 }
1291
1292 static int
src1_3src(FILE * file,const struct intel_device_info * devinfo,const brw_inst * inst)1293 src1_3src(FILE *file, const struct intel_device_info *devinfo,
1294 const brw_inst *inst)
1295 {
1296 int err = 0;
1297 unsigned reg_nr, subreg_nr;
1298 enum brw_reg_file _file;
1299 enum brw_reg_type type;
1300 enum brw_vertical_stride _vert_stride;
1301 enum brw_width _width;
1302 enum brw_horizontal_stride _horiz_stride;
1303 bool is_scalar_region;
1304 bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1;
1305
1306 if (devinfo->ver < 10 && is_align1)
1307 return 0;
1308
1309 if (is_align1) {
1310 if (devinfo->ver >= 12) {
1311 _file = brw_inst_3src_a1_src1_reg_file(devinfo, inst);
1312 } else if (brw_inst_3src_a1_src1_reg_file(devinfo, inst) ==
1313 BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE) {
1314 _file = BRW_GENERAL_REGISTER_FILE;
1315 } else {
1316 _file = BRW_ARCHITECTURE_REGISTER_FILE;
1317 }
1318
1319 reg_nr = brw_inst_3src_src1_reg_nr(devinfo, inst);
1320 subreg_nr = brw_inst_3src_a1_src1_subreg_nr(devinfo, inst);
1321 type = brw_inst_3src_a1_src1_type(devinfo, inst);
1322
1323 _vert_stride = vstride_from_align1_3src_vstride(
1324 devinfo, brw_inst_3src_a1_src1_vstride(devinfo, inst));
1325 _horiz_stride = hstride_from_align1_3src_hstride(
1326 brw_inst_3src_a1_src1_hstride(devinfo, inst));
1327 _width = implied_width(_vert_stride, _horiz_stride);
1328 } else {
1329 _file = BRW_GENERAL_REGISTER_FILE;
1330 reg_nr = brw_inst_3src_src1_reg_nr(devinfo, inst);
1331 subreg_nr = brw_inst_3src_a16_src1_subreg_nr(devinfo, inst) * 4;
1332 type = brw_inst_3src_a16_src_type(devinfo, inst);
1333
1334 if (brw_inst_3src_a16_src1_rep_ctrl(devinfo, inst)) {
1335 _vert_stride = BRW_VERTICAL_STRIDE_0;
1336 _width = BRW_WIDTH_1;
1337 _horiz_stride = BRW_HORIZONTAL_STRIDE_0;
1338 } else {
1339 _vert_stride = BRW_VERTICAL_STRIDE_4;
1340 _width = BRW_WIDTH_4;
1341 _horiz_stride = BRW_HORIZONTAL_STRIDE_1;
1342 }
1343 }
1344 is_scalar_region = _vert_stride == BRW_VERTICAL_STRIDE_0 &&
1345 _width == BRW_WIDTH_1 &&
1346 _horiz_stride == BRW_HORIZONTAL_STRIDE_0;
1347
1348 subreg_nr /= brw_reg_type_to_size(type);
1349
1350 err |= control(file, "negate", m_negate,
1351 brw_inst_3src_src1_negate(devinfo, inst), NULL);
1352 err |= control(file, "abs", _abs, brw_inst_3src_src1_abs(devinfo, inst), NULL);
1353
1354 err |= reg(file, _file, reg_nr);
1355 if (err == -1)
1356 return 0;
1357 if (subreg_nr || is_scalar_region)
1358 format(file, ".%d", subreg_nr);
1359 src_align1_region(file, _vert_stride, _width, _horiz_stride);
1360 if (!is_scalar_region && !is_align1)
1361 err |= src_swizzle(file, brw_inst_3src_a16_src1_swizzle(devinfo, inst));
1362 string(file, brw_reg_type_to_letters(type));
1363 return err;
1364 }
1365
1366 static int
src2_3src(FILE * file,const struct intel_device_info * devinfo,const brw_inst * inst)1367 src2_3src(FILE *file, const struct intel_device_info *devinfo,
1368 const brw_inst *inst)
1369 {
1370 int err = 0;
1371 unsigned reg_nr, subreg_nr;
1372 enum brw_reg_file _file;
1373 enum brw_reg_type type;
1374 enum brw_vertical_stride _vert_stride;
1375 enum brw_width _width;
1376 enum brw_horizontal_stride _horiz_stride;
1377 bool is_scalar_region;
1378 bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1;
1379
1380 if (devinfo->ver < 10 && is_align1)
1381 return 0;
1382
1383 if (is_align1) {
1384 if (devinfo->ver >= 12 && !brw_inst_3src_a1_src2_is_imm(devinfo, inst)) {
1385 _file = brw_inst_3src_a1_src2_reg_file(devinfo, inst);
1386 } else if (brw_inst_3src_a1_src2_reg_file(devinfo, inst) ==
1387 BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE) {
1388 _file = BRW_GENERAL_REGISTER_FILE;
1389 } else {
1390 _file = BRW_IMMEDIATE_VALUE;
1391 uint16_t imm_val = brw_inst_3src_a1_src2_imm(devinfo, inst);
1392 enum brw_reg_type type = brw_inst_3src_a1_src2_type(devinfo, inst);
1393
1394 if (type == BRW_REGISTER_TYPE_W) {
1395 format(file, "%dW", imm_val);
1396 } else if (type == BRW_REGISTER_TYPE_UW) {
1397 format(file, "0x%04xUW", imm_val);
1398 } else if (type == BRW_REGISTER_TYPE_HF) {
1399 format(file, "0x%04xHF", imm_val);
1400 }
1401 return 0;
1402 }
1403
1404 reg_nr = brw_inst_3src_src2_reg_nr(devinfo, inst);
1405 subreg_nr = brw_inst_3src_a1_src2_subreg_nr(devinfo, inst);
1406 type = brw_inst_3src_a1_src2_type(devinfo, inst);
1407 /* FINISHME: No vertical stride on src2. Is using the hstride in place
1408 * correct? Doesn't seem like it, since there's hstride=1 but
1409 * no vstride=1.
1410 */
1411 _vert_stride = vstride_from_align1_3src_hstride(
1412 brw_inst_3src_a1_src2_hstride(devinfo, inst));
1413 _horiz_stride = hstride_from_align1_3src_hstride(
1414 brw_inst_3src_a1_src2_hstride(devinfo, inst));
1415 _width = implied_width(_vert_stride, _horiz_stride);
1416 } else {
1417 _file = BRW_GENERAL_REGISTER_FILE;
1418 reg_nr = brw_inst_3src_src2_reg_nr(devinfo, inst);
1419 subreg_nr = brw_inst_3src_a16_src2_subreg_nr(devinfo, inst) * 4;
1420 type = brw_inst_3src_a16_src_type(devinfo, inst);
1421
1422 if (brw_inst_3src_a16_src2_rep_ctrl(devinfo, inst)) {
1423 _vert_stride = BRW_VERTICAL_STRIDE_0;
1424 _width = BRW_WIDTH_1;
1425 _horiz_stride = BRW_HORIZONTAL_STRIDE_0;
1426 } else {
1427 _vert_stride = BRW_VERTICAL_STRIDE_4;
1428 _width = BRW_WIDTH_4;
1429 _horiz_stride = BRW_HORIZONTAL_STRIDE_1;
1430 }
1431 }
1432 is_scalar_region = _vert_stride == BRW_VERTICAL_STRIDE_0 &&
1433 _width == BRW_WIDTH_1 &&
1434 _horiz_stride == BRW_HORIZONTAL_STRIDE_0;
1435
1436 subreg_nr /= brw_reg_type_to_size(type);
1437
1438 err |= control(file, "negate", m_negate,
1439 brw_inst_3src_src2_negate(devinfo, inst), NULL);
1440 err |= control(file, "abs", _abs, brw_inst_3src_src2_abs(devinfo, inst), NULL);
1441
1442 err |= reg(file, _file, reg_nr);
1443 if (err == -1)
1444 return 0;
1445 if (subreg_nr || is_scalar_region)
1446 format(file, ".%d", subreg_nr);
1447 src_align1_region(file, _vert_stride, _width, _horiz_stride);
1448 if (!is_scalar_region && !is_align1)
1449 err |= src_swizzle(file, brw_inst_3src_a16_src2_swizzle(devinfo, inst));
1450 string(file, brw_reg_type_to_letters(type));
1451 return err;
1452 }
1453
1454 static int
src0_dpas_3src(FILE * file,const struct intel_device_info * devinfo,const brw_inst * inst)1455 src0_dpas_3src(FILE *file, const struct intel_device_info *devinfo,
1456 const brw_inst *inst)
1457 {
1458 uint32_t reg_file = brw_inst_dpas_3src_src0_reg_file(devinfo, inst);
1459
1460 if (reg(file, reg_file, brw_inst_dpas_3src_src0_reg_nr(devinfo, inst)) == -1)
1461 return 0;
1462
1463 unsigned subreg_nr = brw_inst_dpas_3src_src0_subreg_nr(devinfo, inst);
1464 enum brw_reg_type type = brw_inst_dpas_3src_src0_type(devinfo, inst);
1465
1466 if (subreg_nr)
1467 format(file, ".%d", subreg_nr);
1468 src_align1_region(file, 1, 1, 0);
1469
1470 string(file, brw_reg_type_to_letters(type));
1471
1472 return 0;
1473 }
1474
1475 static int
src1_dpas_3src(FILE * file,const struct intel_device_info * devinfo,const brw_inst * inst)1476 src1_dpas_3src(FILE *file, const struct intel_device_info *devinfo,
1477 const brw_inst *inst)
1478 {
1479 uint32_t reg_file = brw_inst_dpas_3src_src1_reg_file(devinfo, inst);
1480
1481 if (reg(file, reg_file, brw_inst_dpas_3src_src1_reg_nr(devinfo, inst)) == -1)
1482 return 0;
1483
1484 unsigned subreg_nr = brw_inst_dpas_3src_src1_subreg_nr(devinfo, inst);
1485 enum brw_reg_type type = brw_inst_dpas_3src_src1_type(devinfo, inst);
1486
1487 if (subreg_nr)
1488 format(file, ".%d", subreg_nr);
1489 src_align1_region(file, 1, 1, 0);
1490
1491 string(file, brw_reg_type_to_letters(type));
1492
1493 return 0;
1494 }
1495
1496 static int
src2_dpas_3src(FILE * file,const struct intel_device_info * devinfo,const brw_inst * inst)1497 src2_dpas_3src(FILE *file, const struct intel_device_info *devinfo,
1498 const brw_inst *inst)
1499 {
1500 uint32_t reg_file = brw_inst_dpas_3src_src2_reg_file(devinfo, inst);
1501
1502 if (reg(file, reg_file, brw_inst_dpas_3src_src2_reg_nr(devinfo, inst)) == -1)
1503 return 0;
1504
1505 unsigned subreg_nr = brw_inst_dpas_3src_src2_subreg_nr(devinfo, inst);
1506 enum brw_reg_type type = brw_inst_dpas_3src_src2_type(devinfo, inst);
1507
1508 if (subreg_nr)
1509 format(file, ".%d", subreg_nr);
1510 src_align1_region(file, 1, 1, 0);
1511
1512 string(file, brw_reg_type_to_letters(type));
1513
1514 return 0;
1515 }
1516
1517 static int
imm(FILE * file,const struct brw_isa_info * isa,enum brw_reg_type type,const brw_inst * inst)1518 imm(FILE *file, const struct brw_isa_info *isa, enum brw_reg_type type,
1519 const brw_inst *inst)
1520 {
1521 const struct intel_device_info *devinfo = isa->devinfo;
1522
1523 switch (type) {
1524 case BRW_REGISTER_TYPE_UQ:
1525 format(file, "0x%016"PRIx64"UQ", brw_inst_imm_uq(devinfo, inst));
1526 break;
1527 case BRW_REGISTER_TYPE_Q:
1528 format(file, "0x%016"PRIx64"Q", brw_inst_imm_uq(devinfo, inst));
1529 break;
1530 case BRW_REGISTER_TYPE_UD:
1531 format(file, "0x%08xUD", brw_inst_imm_ud(devinfo, inst));
1532 break;
1533 case BRW_REGISTER_TYPE_D:
1534 format(file, "%dD", brw_inst_imm_d(devinfo, inst));
1535 break;
1536 case BRW_REGISTER_TYPE_UW:
1537 format(file, "0x%04xUW", (uint16_t) brw_inst_imm_ud(devinfo, inst));
1538 break;
1539 case BRW_REGISTER_TYPE_W:
1540 format(file, "%dW", (int16_t) brw_inst_imm_d(devinfo, inst));
1541 break;
1542 case BRW_REGISTER_TYPE_UV:
1543 format(file, "0x%08xUV", brw_inst_imm_ud(devinfo, inst));
1544 break;
1545 case BRW_REGISTER_TYPE_VF:
1546 format(file, "0x%"PRIx64"VF", brw_inst_bits(inst, 127, 96));
1547 pad(file, 48);
1548 format(file, "/* [%-gF, %-gF, %-gF, %-gF]VF */",
1549 brw_vf_to_float(brw_inst_imm_ud(devinfo, inst)),
1550 brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 8),
1551 brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 16),
1552 brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 24));
1553 break;
1554 case BRW_REGISTER_TYPE_V:
1555 format(file, "0x%08xV", brw_inst_imm_ud(devinfo, inst));
1556 break;
1557 case BRW_REGISTER_TYPE_F:
1558 /* The DIM instruction's src0 uses an F type but contains a
1559 * 64-bit immediate
1560 */
1561 format(file, "0x%"PRIx64"F", brw_inst_bits(inst, 127, 96));
1562 pad(file, 48);
1563 format(file, " /* %-gF */", brw_inst_imm_f(devinfo, inst));
1564 break;
1565 case BRW_REGISTER_TYPE_DF:
1566 format(file, "0x%016"PRIx64"DF", brw_inst_imm_uq(devinfo, inst));
1567 pad(file, 48);
1568 format(file, "/* %-gDF */", brw_inst_imm_df(devinfo, inst));
1569 break;
1570 case BRW_REGISTER_TYPE_HF:
1571 format(file, "0x%04xHF",
1572 (uint16_t) brw_inst_imm_ud(devinfo, inst));
1573 pad(file, 48);
1574 format(file, "/* %-gHF */",
1575 _mesa_half_to_float((uint16_t) brw_inst_imm_ud(devinfo, inst)));
1576 break;
1577 case BRW_REGISTER_TYPE_NF:
1578 case BRW_REGISTER_TYPE_UB:
1579 case BRW_REGISTER_TYPE_B:
1580 format(file, "*** invalid immediate type %d ", type);
1581 }
1582 return 0;
1583 }
1584
1585 static int
src_sends_da(FILE * file,const struct intel_device_info * devinfo,enum brw_reg_type type,enum brw_reg_file _reg_file,unsigned _reg_nr,unsigned _reg_subnr)1586 src_sends_da(FILE *file,
1587 const struct intel_device_info *devinfo,
1588 enum brw_reg_type type,
1589 enum brw_reg_file _reg_file,
1590 unsigned _reg_nr,
1591 unsigned _reg_subnr)
1592 {
1593 int err = 0;
1594
1595 err |= reg(file, _reg_file, _reg_nr);
1596 if (err == -1)
1597 return 0;
1598 if (_reg_subnr)
1599 format(file, ".1");
1600 string(file, brw_reg_type_to_letters(type));
1601
1602 return err;
1603 }
1604
1605 static int
src_sends_ia(FILE * file,const struct intel_device_info * devinfo,enum brw_reg_type type,int _addr_imm,unsigned _addr_subreg_nr)1606 src_sends_ia(FILE *file,
1607 const struct intel_device_info *devinfo,
1608 enum brw_reg_type type,
1609 int _addr_imm,
1610 unsigned _addr_subreg_nr)
1611 {
1612 string(file, "g[a0");
1613 if (_addr_subreg_nr)
1614 format(file, ".1");
1615 if (_addr_imm)
1616 format(file, " %d", _addr_imm);
1617 string(file, "]");
1618 string(file, brw_reg_type_to_letters(type));
1619
1620 return 0;
1621 }
1622
1623 static int
src_send_desc_ia(FILE * file,const struct intel_device_info * devinfo,unsigned _addr_subreg_nr)1624 src_send_desc_ia(FILE *file,
1625 const struct intel_device_info *devinfo,
1626 unsigned _addr_subreg_nr)
1627 {
1628 string(file, "a0");
1629 if (_addr_subreg_nr)
1630 format(file, ".%d", _addr_subreg_nr);
1631 format(file, "<0>UD");
1632
1633 return 0;
1634 }
1635
1636 static int
src0(FILE * file,const struct brw_isa_info * isa,const brw_inst * inst)1637 src0(FILE *file, const struct brw_isa_info *isa, const brw_inst *inst)
1638 {
1639 const struct intel_device_info *devinfo = isa->devinfo;
1640
1641 if (is_split_send(devinfo, brw_inst_opcode(isa, inst))) {
1642 if (devinfo->ver >= 12) {
1643 return src_sends_da(file,
1644 devinfo,
1645 BRW_REGISTER_TYPE_UD,
1646 brw_inst_send_src0_reg_file(devinfo, inst),
1647 brw_inst_src0_da_reg_nr(devinfo, inst),
1648 0);
1649 } else if (brw_inst_send_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
1650 return src_sends_da(file,
1651 devinfo,
1652 BRW_REGISTER_TYPE_UD,
1653 BRW_GENERAL_REGISTER_FILE,
1654 brw_inst_src0_da_reg_nr(devinfo, inst),
1655 brw_inst_src0_da16_subreg_nr(devinfo, inst));
1656 } else {
1657 return src_sends_ia(file,
1658 devinfo,
1659 BRW_REGISTER_TYPE_UD,
1660 brw_inst_send_src0_ia16_addr_imm(devinfo, inst),
1661 brw_inst_src0_ia_subreg_nr(devinfo, inst));
1662 }
1663 } else if (brw_inst_src0_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
1664 return imm(file, isa, brw_inst_src0_type(devinfo, inst), inst);
1665 } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
1666 if (brw_inst_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
1667 return src_da1(file,
1668 devinfo,
1669 brw_inst_opcode(isa, inst),
1670 brw_inst_src0_type(devinfo, inst),
1671 brw_inst_src0_reg_file(devinfo, inst),
1672 brw_inst_src0_vstride(devinfo, inst),
1673 brw_inst_src0_width(devinfo, inst),
1674 brw_inst_src0_hstride(devinfo, inst),
1675 brw_inst_src0_da_reg_nr(devinfo, inst),
1676 brw_inst_src0_da1_subreg_nr(devinfo, inst),
1677 brw_inst_src0_abs(devinfo, inst),
1678 brw_inst_src0_negate(devinfo, inst));
1679 } else {
1680 return src_ia1(file,
1681 devinfo,
1682 brw_inst_opcode(isa, inst),
1683 brw_inst_src0_type(devinfo, inst),
1684 brw_inst_src0_ia1_addr_imm(devinfo, inst),
1685 brw_inst_src0_ia_subreg_nr(devinfo, inst),
1686 brw_inst_src0_negate(devinfo, inst),
1687 brw_inst_src0_abs(devinfo, inst),
1688 brw_inst_src0_hstride(devinfo, inst),
1689 brw_inst_src0_width(devinfo, inst),
1690 brw_inst_src0_vstride(devinfo, inst));
1691 }
1692 } else {
1693 if (brw_inst_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
1694 return src_da16(file,
1695 devinfo,
1696 brw_inst_opcode(isa, inst),
1697 brw_inst_src0_type(devinfo, inst),
1698 brw_inst_src0_reg_file(devinfo, inst),
1699 brw_inst_src0_vstride(devinfo, inst),
1700 brw_inst_src0_da_reg_nr(devinfo, inst),
1701 brw_inst_src0_da16_subreg_nr(devinfo, inst),
1702 brw_inst_src0_abs(devinfo, inst),
1703 brw_inst_src0_negate(devinfo, inst),
1704 brw_inst_src0_da16_swiz_x(devinfo, inst),
1705 brw_inst_src0_da16_swiz_y(devinfo, inst),
1706 brw_inst_src0_da16_swiz_z(devinfo, inst),
1707 brw_inst_src0_da16_swiz_w(devinfo, inst));
1708 } else {
1709 string(file, "Indirect align16 address mode not supported");
1710 return 1;
1711 }
1712 }
1713 }
1714
1715 static int
src1(FILE * file,const struct brw_isa_info * isa,const brw_inst * inst)1716 src1(FILE *file, const struct brw_isa_info *isa, const brw_inst *inst)
1717 {
1718 const struct intel_device_info *devinfo = isa->devinfo;
1719
1720 if (is_split_send(devinfo, brw_inst_opcode(isa, inst))) {
1721 return src_sends_da(file,
1722 devinfo,
1723 BRW_REGISTER_TYPE_UD,
1724 brw_inst_send_src1_reg_file(devinfo, inst),
1725 brw_inst_send_src1_reg_nr(devinfo, inst),
1726 0 /* subreg_nr */);
1727 } else if (brw_inst_src1_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
1728 return imm(file, isa, brw_inst_src1_type(devinfo, inst), inst);
1729 } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
1730 if (brw_inst_src1_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
1731 return src_da1(file,
1732 devinfo,
1733 brw_inst_opcode(isa, inst),
1734 brw_inst_src1_type(devinfo, inst),
1735 brw_inst_src1_reg_file(devinfo, inst),
1736 brw_inst_src1_vstride(devinfo, inst),
1737 brw_inst_src1_width(devinfo, inst),
1738 brw_inst_src1_hstride(devinfo, inst),
1739 brw_inst_src1_da_reg_nr(devinfo, inst),
1740 brw_inst_src1_da1_subreg_nr(devinfo, inst),
1741 brw_inst_src1_abs(devinfo, inst),
1742 brw_inst_src1_negate(devinfo, inst));
1743 } else {
1744 return src_ia1(file,
1745 devinfo,
1746 brw_inst_opcode(isa, inst),
1747 brw_inst_src1_type(devinfo, inst),
1748 brw_inst_src1_ia1_addr_imm(devinfo, inst),
1749 brw_inst_src1_ia_subreg_nr(devinfo, inst),
1750 brw_inst_src1_negate(devinfo, inst),
1751 brw_inst_src1_abs(devinfo, inst),
1752 brw_inst_src1_hstride(devinfo, inst),
1753 brw_inst_src1_width(devinfo, inst),
1754 brw_inst_src1_vstride(devinfo, inst));
1755 }
1756 } else {
1757 if (brw_inst_src1_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
1758 return src_da16(file,
1759 devinfo,
1760 brw_inst_opcode(isa, inst),
1761 brw_inst_src1_type(devinfo, inst),
1762 brw_inst_src1_reg_file(devinfo, inst),
1763 brw_inst_src1_vstride(devinfo, inst),
1764 brw_inst_src1_da_reg_nr(devinfo, inst),
1765 brw_inst_src1_da16_subreg_nr(devinfo, inst),
1766 brw_inst_src1_abs(devinfo, inst),
1767 brw_inst_src1_negate(devinfo, inst),
1768 brw_inst_src1_da16_swiz_x(devinfo, inst),
1769 brw_inst_src1_da16_swiz_y(devinfo, inst),
1770 brw_inst_src1_da16_swiz_z(devinfo, inst),
1771 brw_inst_src1_da16_swiz_w(devinfo, inst));
1772 } else {
1773 string(file, "Indirect align16 address mode not supported");
1774 return 1;
1775 }
1776 }
1777 }
1778
1779 static int
qtr_ctrl(FILE * file,const struct intel_device_info * devinfo,const brw_inst * inst)1780 qtr_ctrl(FILE *file, const struct intel_device_info *devinfo,
1781 const brw_inst *inst)
1782 {
1783 int qtr_ctl = brw_inst_qtr_control(devinfo, inst);
1784 int exec_size = 1 << brw_inst_exec_size(devinfo, inst);
1785 const unsigned nib_ctl = devinfo->ver >= 20 ? 0 :
1786 brw_inst_nib_control(devinfo, inst);
1787
1788 if (exec_size < 8 || nib_ctl) {
1789 format(file, " %dN", qtr_ctl * 2 + nib_ctl + 1);
1790 } else if (exec_size == 8) {
1791 switch (qtr_ctl) {
1792 case 0:
1793 string(file, " 1Q");
1794 break;
1795 case 1:
1796 string(file, " 2Q");
1797 break;
1798 case 2:
1799 string(file, " 3Q");
1800 break;
1801 case 3:
1802 string(file, " 4Q");
1803 break;
1804 }
1805 } else if (exec_size == 16) {
1806 if (qtr_ctl < 2)
1807 string(file, " 1H");
1808 else
1809 string(file, " 2H");
1810 }
1811 return 0;
1812 }
1813
1814 static bool
inst_has_type(const struct brw_isa_info * isa,const brw_inst * inst,enum brw_reg_type type)1815 inst_has_type(const struct brw_isa_info *isa,
1816 const brw_inst *inst,
1817 enum brw_reg_type type)
1818 {
1819 const struct intel_device_info *devinfo = isa->devinfo;
1820 const unsigned num_sources = brw_num_sources_from_inst(isa, inst);
1821
1822 if (brw_inst_dst_type(devinfo, inst) == type)
1823 return true;
1824
1825 if (num_sources >= 3) {
1826 if (brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1)
1827 return brw_inst_3src_a1_src0_type(devinfo, inst) == type ||
1828 brw_inst_3src_a1_src1_type(devinfo, inst) == type ||
1829 brw_inst_3src_a1_src2_type(devinfo, inst) == type;
1830 else
1831 return brw_inst_3src_a16_src_type(devinfo, inst) == type;
1832 } else if (num_sources == 2) {
1833 return brw_inst_src0_type(devinfo, inst) == type ||
1834 brw_inst_src1_type(devinfo, inst) == type;
1835 } else {
1836 return brw_inst_src0_type(devinfo, inst) == type;
1837 }
1838 }
1839
1840 static int
swsb(FILE * file,const struct brw_isa_info * isa,const brw_inst * inst)1841 swsb(FILE *file, const struct brw_isa_info *isa, const brw_inst *inst)
1842 {
1843 const struct intel_device_info *devinfo = isa->devinfo;
1844 const enum opcode opcode = brw_inst_opcode(isa, inst);
1845 const uint32_t x = brw_inst_swsb(devinfo, inst);
1846 const bool is_unordered =
1847 opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC ||
1848 opcode == BRW_OPCODE_MATH || opcode == BRW_OPCODE_DPAS ||
1849 (devinfo->has_64bit_float_via_math_pipe &&
1850 inst_has_type(isa, inst, BRW_REGISTER_TYPE_DF));
1851 const struct tgl_swsb swsb = tgl_swsb_decode(devinfo, is_unordered, x);
1852 if (swsb.regdist)
1853 format(file, " %s@%d",
1854 (swsb.pipe == TGL_PIPE_FLOAT ? "F" :
1855 swsb.pipe == TGL_PIPE_INT ? "I" :
1856 swsb.pipe == TGL_PIPE_LONG ? "L" :
1857 swsb.pipe == TGL_PIPE_ALL ? "A" : "" ),
1858 swsb.regdist);
1859 if (swsb.mode)
1860 format(file, " $%d%s", swsb.sbid,
1861 (swsb.mode & TGL_SBID_SET ? "" :
1862 swsb.mode & TGL_SBID_DST ? ".dst" : ".src"));
1863 return 0;
1864 }
1865
1866 #ifdef DEBUG
1867 static __attribute__((__unused__)) int
brw_disassemble_imm(const struct brw_isa_info * isa,uint32_t dw3,uint32_t dw2,uint32_t dw1,uint32_t dw0)1868 brw_disassemble_imm(const struct brw_isa_info *isa,
1869 uint32_t dw3, uint32_t dw2, uint32_t dw1, uint32_t dw0)
1870 {
1871 brw_inst inst;
1872 inst.data[0] = (((uint64_t) dw1) << 32) | ((uint64_t) dw0);
1873 inst.data[1] = (((uint64_t) dw3) << 32) | ((uint64_t) dw2);
1874 return brw_disassemble_inst(stderr, isa, &inst, false, 0, NULL);
1875 }
1876 #endif
1877
1878 static void
write_label(FILE * file,const struct intel_device_info * devinfo,const struct brw_label * root_label,int offset,int jump)1879 write_label(FILE *file, const struct intel_device_info *devinfo,
1880 const struct brw_label *root_label,
1881 int offset, int jump)
1882 {
1883 if (root_label != NULL) {
1884 int to_bytes_scale = sizeof(brw_inst) / brw_jump_scale(devinfo);
1885 const struct brw_label *label =
1886 brw_find_label(root_label, offset + jump * to_bytes_scale);
1887 if (label != NULL) {
1888 format(file, " LABEL%d", label->number);
1889 }
1890 }
1891 }
1892
1893 static void
lsc_disassemble_ex_desc(const struct intel_device_info * devinfo,uint32_t imm_desc,uint32_t imm_ex_desc,FILE * file)1894 lsc_disassemble_ex_desc(const struct intel_device_info *devinfo,
1895 uint32_t imm_desc,
1896 uint32_t imm_ex_desc,
1897 FILE *file)
1898 {
1899 const unsigned addr_type = lsc_msg_desc_addr_type(devinfo, imm_desc);
1900 switch (addr_type) {
1901 case LSC_ADDR_SURFTYPE_FLAT:
1902 format(file, " base_offset %u ",
1903 lsc_flat_ex_desc_base_offset(devinfo, imm_ex_desc));
1904 break;
1905 case LSC_ADDR_SURFTYPE_BSS:
1906 case LSC_ADDR_SURFTYPE_SS:
1907 format(file, " surface_state_index %u ",
1908 lsc_bss_ex_desc_index(devinfo, imm_ex_desc));
1909 break;
1910 case LSC_ADDR_SURFTYPE_BTI:
1911 format(file, " BTI %u ",
1912 lsc_bti_ex_desc_index(devinfo, imm_ex_desc));
1913 format(file, " base_offset %u ",
1914 lsc_bti_ex_desc_base_offset(devinfo, imm_ex_desc));
1915 break;
1916 default:
1917 format(file, "unsupported address surface type %d", addr_type);
1918 break;
1919 }
1920 }
1921
1922 static inline bool
brw_sfid_is_lsc(unsigned sfid)1923 brw_sfid_is_lsc(unsigned sfid)
1924 {
1925 switch (sfid) {
1926 case GFX12_SFID_UGM:
1927 case GFX12_SFID_SLM:
1928 case GFX12_SFID_TGM:
1929 return true;
1930 default:
1931 break;
1932 }
1933
1934 return false;
1935 }
1936
1937 int
brw_disassemble_inst(FILE * file,const struct brw_isa_info * isa,const brw_inst * inst,bool is_compacted,int offset,const struct brw_label * root_label)1938 brw_disassemble_inst(FILE *file, const struct brw_isa_info *isa,
1939 const brw_inst *inst, bool is_compacted,
1940 int offset, const struct brw_label *root_label)
1941 {
1942 const struct intel_device_info *devinfo = isa->devinfo;
1943
1944 int err = 0;
1945 int space = 0;
1946
1947 const enum opcode opcode = brw_inst_opcode(isa, inst);
1948 const struct opcode_desc *desc = brw_opcode_desc(isa, opcode);
1949
1950 if (brw_inst_pred_control(devinfo, inst)) {
1951 string(file, "(");
1952 err |= control(file, "predicate inverse", pred_inv,
1953 brw_inst_pred_inv(devinfo, inst), NULL);
1954 format(file, "f%"PRIu64".%"PRIu64,
1955 brw_inst_flag_reg_nr(devinfo, inst),
1956 brw_inst_flag_subreg_nr(devinfo, inst));
1957 if (devinfo->ver >= 20) {
1958 err |= control(file, "predicate control", xe2_pred_ctrl,
1959 brw_inst_pred_control(devinfo, inst), NULL);
1960 } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
1961 err |= control(file, "predicate control align1", pred_ctrl_align1,
1962 brw_inst_pred_control(devinfo, inst), NULL);
1963 } else {
1964 err |= control(file, "predicate control align16", pred_ctrl_align16,
1965 brw_inst_pred_control(devinfo, inst), NULL);
1966 }
1967 string(file, ") ");
1968 }
1969
1970 err |= print_opcode(file, isa, opcode);
1971
1972 if (!is_send(opcode))
1973 err |= control(file, "saturate", saturate, brw_inst_saturate(devinfo, inst),
1974 NULL);
1975
1976 err |= control(file, "debug control", debug_ctrl,
1977 brw_inst_debug_control(devinfo, inst), NULL);
1978
1979 if (opcode == BRW_OPCODE_MATH) {
1980 string(file, " ");
1981 err |= control(file, "function", math_function,
1982 brw_inst_math_function(devinfo, inst), NULL);
1983
1984 } else if (opcode == BRW_OPCODE_SYNC) {
1985 string(file, " ");
1986 err |= control(file, "function", sync_function,
1987 brw_inst_cond_modifier(devinfo, inst), NULL);
1988
1989 } else if (opcode == BRW_OPCODE_DPAS) {
1990 string(file, ".");
1991
1992 err |= control(file, "systolic depth", dpas_systolic_depth,
1993 brw_inst_dpas_3src_sdepth(devinfo, inst), NULL);
1994
1995 const unsigned rcount = brw_inst_dpas_3src_rcount(devinfo, inst) + 1;
1996
1997 format(file, "x%d", rcount);
1998 } else if (!is_send(opcode) &&
1999 (devinfo->ver < 12 ||
2000 brw_inst_src0_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE ||
2001 type_sz(brw_inst_src0_type(devinfo, inst)) < 8)) {
2002 err |= control(file, "conditional modifier", conditional_modifier,
2003 brw_inst_cond_modifier(devinfo, inst), NULL);
2004
2005 /* If we're using the conditional modifier, print which flags reg is
2006 * used for it. Note that on gfx6+, the embedded-condition SEL and
2007 * control flow doesn't update flags.
2008 */
2009 if (brw_inst_cond_modifier(devinfo, inst) &&
2010 (opcode != BRW_OPCODE_SEL &&
2011 opcode != BRW_OPCODE_CSEL &&
2012 opcode != BRW_OPCODE_IF &&
2013 opcode != BRW_OPCODE_WHILE)) {
2014 format(file, ".f%"PRIu64".%"PRIu64,
2015 brw_inst_flag_reg_nr(devinfo, inst),
2016 brw_inst_flag_subreg_nr(devinfo, inst));
2017 }
2018 }
2019
2020 if (opcode != BRW_OPCODE_NOP) {
2021 string(file, "(");
2022 err |= control(file, "execution size", exec_size,
2023 brw_inst_exec_size(devinfo, inst), NULL);
2024 string(file, ")");
2025 }
2026
2027 if (brw_has_uip(devinfo, opcode)) {
2028 /* Instructions that have UIP also have JIP. */
2029 pad(file, 16);
2030 string(file, "JIP: ");
2031 write_label(file, devinfo, root_label, offset, brw_inst_jip(devinfo, inst));
2032
2033 pad(file, 38);
2034 string(file, "UIP: ");
2035 write_label(file, devinfo, root_label, offset, brw_inst_uip(devinfo, inst));
2036 } else if (brw_has_jip(devinfo, opcode)) {
2037 int jip = brw_inst_jip(devinfo, inst);
2038
2039 pad(file, 16);
2040 string(file, "JIP: ");
2041 write_label(file, devinfo, root_label, offset, jip);
2042 } else if (opcode == BRW_OPCODE_JMPI) {
2043 pad(file, 16);
2044 err |= src1(file, isa, inst);
2045 } else if (opcode == BRW_OPCODE_DPAS) {
2046 pad(file, 16);
2047 err |= dest_dpas_3src(file, devinfo, inst);
2048
2049 pad(file, 32);
2050 err |= src0_dpas_3src(file, devinfo, inst);
2051
2052 pad(file, 48);
2053 err |= src1_dpas_3src(file, devinfo, inst);
2054
2055 pad(file, 64);
2056 err |= src2_dpas_3src(file, devinfo, inst);
2057
2058 } else if (desc && desc->nsrc == 3) {
2059 pad(file, 16);
2060 err |= dest_3src(file, devinfo, inst);
2061
2062 pad(file, 32);
2063 err |= src0_3src(file, devinfo, inst);
2064
2065 pad(file, 48);
2066 err |= src1_3src(file, devinfo, inst);
2067
2068 pad(file, 64);
2069 err |= src2_3src(file, devinfo, inst);
2070 } else if (desc) {
2071 if (desc->ndst > 0) {
2072 pad(file, 16);
2073 err |= dest(file, isa, inst);
2074 }
2075
2076 if (desc->nsrc > 0) {
2077 pad(file, 32);
2078 err |= src0(file, isa, inst);
2079 }
2080
2081 if (desc->nsrc > 1) {
2082 pad(file, 48);
2083 err |= src1(file, isa, inst);
2084 }
2085 }
2086
2087 if (is_send(opcode)) {
2088 enum brw_message_target sfid = brw_inst_sfid(devinfo, inst);
2089
2090 bool has_imm_desc = false, has_imm_ex_desc = false;
2091 uint32_t imm_desc = 0, imm_ex_desc = 0;
2092 if (is_split_send(devinfo, opcode)) {
2093 pad(file, 64);
2094 if (brw_inst_send_sel_reg32_desc(devinfo, inst)) {
2095 /* show the indirect descriptor source */
2096 err |= src_send_desc_ia(file, devinfo, 0);
2097 } else {
2098 has_imm_desc = true;
2099 imm_desc = brw_inst_send_desc(devinfo, inst);
2100 fprintf(file, "0x%08"PRIx32, imm_desc);
2101 }
2102
2103 pad(file, 80);
2104 if (brw_inst_send_sel_reg32_ex_desc(devinfo, inst)) {
2105 /* show the indirect descriptor source */
2106 err |= src_send_desc_ia(file, devinfo,
2107 brw_inst_send_ex_desc_ia_subreg_nr(devinfo, inst));
2108 } else {
2109 has_imm_ex_desc = true;
2110 imm_ex_desc = brw_inst_sends_ex_desc(devinfo, inst);
2111 fprintf(file, "0x%08"PRIx32, imm_ex_desc);
2112 }
2113 } else {
2114 if (brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE) {
2115 /* show the indirect descriptor source */
2116 pad(file, 48);
2117 err |= src1(file, isa, inst);
2118 pad(file, 64);
2119 } else {
2120 has_imm_desc = true;
2121 imm_desc = brw_inst_send_desc(devinfo, inst);
2122 pad(file, 48);
2123 }
2124
2125 /* Print message descriptor as immediate source */
2126 fprintf(file, "0x%08"PRIx64, inst->data[1] >> 32);
2127 }
2128
2129 newline(file);
2130 pad(file, 16);
2131 space = 0;
2132
2133 fprintf(file, " ");
2134 err |= control(file, "SFID", gfx6_sfid, sfid, &space);
2135 string(file, " MsgDesc:");
2136
2137 if (!has_imm_desc) {
2138 format(file, " indirect");
2139 } else {
2140 bool unsupported = false;
2141 switch (sfid) {
2142 case BRW_SFID_SAMPLER:
2143 if (devinfo->ver >= 20) {
2144 err |= control(file, "sampler message", xe2_sampler_msg_type,
2145 brw_sampler_desc_msg_type(devinfo, imm_desc),
2146 &space);
2147 err |= control(file, "sampler simd mode", xe2_sampler_simd_mode,
2148 brw_sampler_desc_simd_mode(devinfo, imm_desc),
2149 &space);
2150 if (brw_sampler_desc_return_format(devinfo, imm_desc)) {
2151 string(file, " HP");
2152 }
2153 format(file, " Surface = %u Sampler = %u",
2154 brw_sampler_desc_binding_table_index(devinfo, imm_desc),
2155 brw_sampler_desc_sampler(devinfo, imm_desc));
2156 } else {
2157 err |= control(file, "sampler message", gfx5_sampler_msg_type,
2158 brw_sampler_desc_msg_type(devinfo, imm_desc),
2159 &space);
2160 err |= control(file, "sampler simd mode", gfx5_sampler_simd_mode,
2161 brw_sampler_desc_simd_mode(devinfo, imm_desc),
2162 &space);
2163 if (brw_sampler_desc_return_format(devinfo, imm_desc)) {
2164 string(file, " HP");
2165 }
2166 format(file, " Surface = %u Sampler = %u",
2167 brw_sampler_desc_binding_table_index(devinfo, imm_desc),
2168 brw_sampler_desc_sampler(devinfo, imm_desc));
2169 }
2170 break;
2171 case GFX6_SFID_DATAPORT_SAMPLER_CACHE:
2172 case GFX6_SFID_DATAPORT_CONSTANT_CACHE:
2173 format(file, " (bti %u, msg_ctrl %u, msg_type %u)",
2174 brw_dp_desc_binding_table_index(devinfo, imm_desc),
2175 brw_dp_desc_msg_control(devinfo, imm_desc),
2176 brw_dp_desc_msg_type(devinfo, imm_desc));
2177 break;
2178
2179 case GFX6_SFID_DATAPORT_RENDER_CACHE: {
2180 /* aka BRW_SFID_DATAPORT_WRITE on Gfx4-5 */
2181 unsigned msg_type = brw_fb_desc_msg_type(devinfo, imm_desc);
2182
2183 err |= control(file, "DP rc message type",
2184 dp_rc_msg_type(devinfo), msg_type, &space);
2185
2186 bool is_rt_write = msg_type ==
2187 GFX6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE;
2188
2189 if (is_rt_write) {
2190 err |= control(file, "RT message type", m_rt_write_subtype,
2191 brw_inst_rt_message_type(devinfo, inst), &space);
2192 if (brw_inst_rt_slot_group(devinfo, inst))
2193 string(file, " Hi");
2194 if (brw_fb_write_desc_last_render_target(devinfo, imm_desc))
2195 string(file, " LastRT");
2196 if (devinfo->ver >= 10 &&
2197 brw_fb_write_desc_coarse_write(devinfo, imm_desc))
2198 string(file, " CoarseWrite");
2199 } else {
2200 format(file, " MsgCtrl = 0x%u",
2201 brw_fb_desc_msg_control(devinfo, imm_desc));
2202 }
2203
2204 format(file, " Surface = %u",
2205 brw_fb_desc_binding_table_index(devinfo, imm_desc));
2206 break;
2207 }
2208
2209 case BRW_SFID_URB: {
2210 if (devinfo->ver >= 20) {
2211 format(file, " (");
2212 const enum lsc_opcode op = lsc_msg_desc_opcode(devinfo, imm_desc);
2213 err |= control(file, "operation", lsc_operation,
2214 op, &space);
2215 format(file, ",");
2216 err |= control(file, "addr_size", lsc_addr_size,
2217 lsc_msg_desc_addr_size(devinfo, imm_desc),
2218 &space);
2219
2220 format(file, ",");
2221 err |= control(file, "data_size", lsc_data_size,
2222 lsc_msg_desc_data_size(devinfo, imm_desc),
2223 &space);
2224 format(file, ",");
2225 if (lsc_opcode_has_cmask(op)) {
2226 err |= control(file, "component_mask",
2227 lsc_cmask_str,
2228 lsc_msg_desc_cmask(devinfo, imm_desc),
2229 &space);
2230 } else {
2231 err |= control(file, "vector_size",
2232 lsc_vect_size_str,
2233 lsc_msg_desc_vect_size(devinfo, imm_desc),
2234 &space);
2235 if (lsc_msg_desc_transpose(devinfo, imm_desc))
2236 format(file, ", transpose");
2237 }
2238 switch(op) {
2239 case LSC_OP_LOAD_CMASK:
2240 case LSC_OP_LOAD:
2241 format(file, ",");
2242 err |= control(file, "cache_load",
2243 lsc_cache_load,
2244 lsc_msg_desc_cache_ctrl(devinfo, imm_desc),
2245 &space);
2246 break;
2247 default:
2248 format(file, ",");
2249 err |= control(file, "cache_store",
2250 lsc_cache_store,
2251 lsc_msg_desc_cache_ctrl(devinfo, imm_desc),
2252 &space);
2253 break;
2254 }
2255
2256 format(file, " dst_len = %u,", lsc_msg_desc_dest_len(devinfo, imm_desc));
2257 format(file, " src0_len = %u,", lsc_msg_desc_src0_len(devinfo, imm_desc));
2258 format(file, " src1_len = %d", brw_message_ex_desc_ex_mlen(devinfo, imm_ex_desc));
2259 err |= control(file, "address_type", lsc_addr_surface_type,
2260 lsc_msg_desc_addr_type(devinfo, imm_desc), &space);
2261 format(file, " )");
2262 } else {
2263 unsigned urb_opcode = brw_inst_urb_opcode(devinfo, inst);
2264
2265 format(file, " offset %"PRIu64, brw_inst_urb_global_offset(devinfo, inst));
2266
2267 space = 1;
2268
2269 err |= control(file, "urb opcode",
2270 gfx7_urb_opcode, urb_opcode, &space);
2271
2272 if (brw_inst_urb_per_slot_offset(devinfo, inst)) {
2273 string(file, " per-slot");
2274 }
2275
2276 if (urb_opcode == GFX8_URB_OPCODE_SIMD8_WRITE ||
2277 urb_opcode == GFX8_URB_OPCODE_SIMD8_READ) {
2278 if (brw_inst_urb_channel_mask_present(devinfo, inst))
2279 string(file, " masked");
2280 } else if (urb_opcode != GFX125_URB_OPCODE_FENCE) {
2281 err |= control(file, "urb swizzle", urb_swizzle,
2282 brw_inst_urb_swizzle_control(devinfo, inst),
2283 &space);
2284 }
2285 }
2286 break;
2287 }
2288 case BRW_SFID_THREAD_SPAWNER:
2289 break;
2290
2291 case BRW_SFID_MESSAGE_GATEWAY:
2292 format(file, " (%s)",
2293 gfx7_gateway_subfuncid[brw_inst_gateway_subfuncid(devinfo, inst)]);
2294 break;
2295
2296 case GFX12_SFID_SLM:
2297 case GFX12_SFID_TGM:
2298 case GFX12_SFID_UGM: {
2299 assert(devinfo->has_lsc);
2300 format(file, " (");
2301 const enum lsc_opcode op = lsc_msg_desc_opcode(devinfo, imm_desc);
2302 err |= control(file, "operation", lsc_operation,
2303 op, &space);
2304 format(file, ",");
2305 err |= control(file, "addr_size", lsc_addr_size,
2306 lsc_msg_desc_addr_size(devinfo, imm_desc),
2307 &space);
2308
2309 if (op == LSC_OP_FENCE) {
2310 format(file, ",");
2311 err |= control(file, "scope", lsc_fence_scope,
2312 lsc_fence_msg_desc_scope(devinfo, imm_desc),
2313 &space);
2314 format(file, ",");
2315 err |= control(file, "flush_type", lsc_flush_type,
2316 lsc_fence_msg_desc_flush_type(devinfo, imm_desc),
2317 &space);
2318 format(file, ",");
2319 err |= control(file, "backup_mode_fence_routing",
2320 lsc_backup_fence_routing,
2321 lsc_fence_msg_desc_backup_routing(devinfo, imm_desc),
2322 &space);
2323 } else {
2324 format(file, ",");
2325 err |= control(file, "data_size", lsc_data_size,
2326 lsc_msg_desc_data_size(devinfo, imm_desc),
2327 &space);
2328 format(file, ",");
2329 if (lsc_opcode_has_cmask(op)) {
2330 err |= control(file, "component_mask",
2331 lsc_cmask_str,
2332 lsc_msg_desc_cmask(devinfo, imm_desc),
2333 &space);
2334 } else {
2335 err |= control(file, "vector_size",
2336 lsc_vect_size_str,
2337 lsc_msg_desc_vect_size(devinfo, imm_desc),
2338 &space);
2339 if (lsc_msg_desc_transpose(devinfo, imm_desc))
2340 format(file, ", transpose");
2341 }
2342 switch(op) {
2343 case LSC_OP_LOAD_CMASK:
2344 case LSC_OP_LOAD:
2345 format(file, ",");
2346 err |= control(file, "cache_load",
2347 devinfo->ver >= 20 ?
2348 xe2_lsc_cache_load :
2349 lsc_cache_load,
2350 lsc_msg_desc_cache_ctrl(devinfo, imm_desc),
2351 &space);
2352 break;
2353 default:
2354 format(file, ",");
2355 err |= control(file, "cache_store",
2356 devinfo->ver >= 20 ?
2357 xe2_lsc_cache_store :
2358 lsc_cache_store,
2359 lsc_msg_desc_cache_ctrl(devinfo, imm_desc),
2360 &space);
2361 break;
2362 }
2363 }
2364 format(file, " dst_len = %u,", lsc_msg_desc_dest_len(devinfo, imm_desc));
2365 format(file, " src0_len = %u,", lsc_msg_desc_src0_len(devinfo, imm_desc));
2366
2367 if (!brw_inst_send_sel_reg32_ex_desc(devinfo, inst))
2368 format(file, " src1_len = %d",
2369 brw_message_ex_desc_ex_mlen(devinfo, imm_ex_desc));
2370
2371 err |= control(file, "address_type", lsc_addr_surface_type,
2372 lsc_msg_desc_addr_type(devinfo, imm_desc), &space);
2373 format(file, " )");
2374 break;
2375 }
2376
2377 case GFX7_SFID_DATAPORT_DATA_CACHE:
2378 format(file, " (");
2379 space = 0;
2380
2381 err |= control(file, "DP DC0 message type",
2382 dp_dc0_msg_type_gfx7,
2383 brw_dp_desc_msg_type(devinfo, imm_desc), &space);
2384
2385 format(file, ", bti %u, ",
2386 brw_dp_desc_binding_table_index(devinfo, imm_desc));
2387
2388 switch (brw_inst_dp_msg_type(devinfo, inst)) {
2389 case GFX7_DATAPORT_DC_UNTYPED_ATOMIC_OP:
2390 control(file, "atomic op", aop,
2391 brw_dp_desc_msg_control(devinfo, imm_desc) & 0xf,
2392 &space);
2393 break;
2394 case GFX7_DATAPORT_DC_OWORD_BLOCK_READ:
2395 case GFX7_DATAPORT_DC_OWORD_BLOCK_WRITE: {
2396 unsigned msg_ctrl = brw_dp_desc_msg_control(devinfo, imm_desc);
2397 assert(dp_oword_block_rw[msg_ctrl & 7]);
2398 format(file, "owords = %s, aligned = %d",
2399 dp_oword_block_rw[msg_ctrl & 7], (msg_ctrl >> 3) & 3);
2400 break;
2401 }
2402 default:
2403 format(file, "%u",
2404 brw_dp_desc_msg_control(devinfo, imm_desc));
2405 }
2406 format(file, ")");
2407 break;
2408
2409 case HSW_SFID_DATAPORT_DATA_CACHE_1: {
2410 format(file, " (");
2411 space = 0;
2412
2413 unsigned msg_ctrl = brw_dp_desc_msg_control(devinfo, imm_desc);
2414
2415 err |= control(file, "DP DC1 message type",
2416 dp_dc1_msg_type_hsw,
2417 brw_dp_desc_msg_type(devinfo, imm_desc), &space);
2418
2419 format(file, ", Surface = %u, ",
2420 brw_dp_desc_binding_table_index(devinfo, imm_desc));
2421
2422 switch (brw_inst_dp_msg_type(devinfo, inst)) {
2423 case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP:
2424 case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP:
2425 case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP:
2426 format(file, "SIMD%d,", (msg_ctrl & (1 << 4)) ? 8 : 16);
2427 FALLTHROUGH;
2428 case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2:
2429 case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2:
2430 case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2:
2431 case GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_OP:
2432 case GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_INT_OP:
2433 control(file, "atomic op", aop, msg_ctrl & 0xf, &space);
2434 break;
2435 case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ:
2436 case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE:
2437 case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ:
2438 case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE:
2439 case GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_WRITE:
2440 case GFX8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_READ: {
2441 static const char *simd_modes[] = { "4x2", "16", "8" };
2442 format(file, "SIMD%s, Mask = 0x%x",
2443 simd_modes[msg_ctrl >> 4], msg_ctrl & 0xf);
2444 break;
2445 }
2446 case GFX9_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_FLOAT_OP:
2447 case GFX9_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_FLOAT_OP:
2448 case GFX12_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_HALF_FLOAT_OP:
2449 format(file, "SIMD%d,", (msg_ctrl & (1 << 4)) ? 8 : 16);
2450 control(file, "atomic float op", aop_float, msg_ctrl & 0xf,
2451 &space);
2452 break;
2453 case GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_WRITE:
2454 case GFX9_DATAPORT_DC_PORT1_A64_OWORD_BLOCK_READ:
2455 assert(dp_oword_block_rw[msg_ctrl & 7]);
2456 format(file, "owords = %s, aligned = %d",
2457 dp_oword_block_rw[msg_ctrl & 7], (msg_ctrl >> 3) & 3);
2458 break;
2459 default:
2460 format(file, "0x%x", msg_ctrl);
2461 }
2462 format(file, ")");
2463 break;
2464 }
2465
2466 case GFX7_SFID_PIXEL_INTERPOLATOR:
2467 format(file, " (%s, %s, 0x%02"PRIx64")",
2468 brw_inst_pi_nopersp(devinfo, inst) ? "linear" : "persp",
2469 pixel_interpolator_msg_types[brw_inst_pi_message_type(devinfo, inst)],
2470 brw_inst_pi_message_data(devinfo, inst));
2471 break;
2472
2473 case GEN_RT_SFID_RAY_TRACE_ACCELERATOR:
2474 if (devinfo->has_ray_tracing) {
2475 format(file, " SIMD%d,",
2476 brw_rt_trace_ray_desc_exec_size(devinfo, imm_desc));
2477 } else {
2478 unsupported = true;
2479 }
2480 break;
2481
2482 default:
2483 unsupported = true;
2484 break;
2485 }
2486
2487 if (unsupported)
2488 format(file, "unsupported shared function ID %d", sfid);
2489
2490 if (space)
2491 string(file, " ");
2492 }
2493 if (devinfo->verx10 >= 125 &&
2494 brw_inst_send_sel_reg32_ex_desc(devinfo, inst) &&
2495 brw_inst_send_ex_bso(devinfo, inst)) {
2496 format(file, " src1_len = %u",
2497 (unsigned) brw_inst_send_src1_len(devinfo, inst));
2498
2499 format(file, " ex_bso");
2500 }
2501 if (brw_sfid_is_lsc(sfid) ||
2502 (sfid == BRW_SFID_URB && devinfo->ver >= 20)) {
2503 lsc_disassemble_ex_desc(devinfo, imm_desc, imm_ex_desc, file);
2504 } else {
2505 if (has_imm_desc)
2506 format(file, " mlen %u", brw_message_desc_mlen(devinfo, imm_desc));
2507 if (has_imm_ex_desc) {
2508 format(file, " ex_mlen %u",
2509 brw_message_ex_desc_ex_mlen(devinfo, imm_ex_desc));
2510 }
2511 if (has_imm_desc)
2512 format(file, " rlen %u", brw_message_desc_rlen(devinfo, imm_desc));
2513 }
2514 }
2515 pad(file, 64);
2516 if (opcode != BRW_OPCODE_NOP) {
2517 string(file, "{");
2518 space = 1;
2519 err |= control(file, "access mode", access_mode,
2520 brw_inst_access_mode(devinfo, inst), &space);
2521 err |= control(file, "write enable control", wectrl,
2522 brw_inst_mask_control(devinfo, inst), &space);
2523
2524 if (devinfo->ver < 12) {
2525 err |= control(file, "dependency control", dep_ctrl,
2526 ((brw_inst_no_dd_check(devinfo, inst) << 1) |
2527 brw_inst_no_dd_clear(devinfo, inst)), &space);
2528 }
2529
2530 err |= qtr_ctrl(file, devinfo, inst);
2531
2532 if (devinfo->ver >= 12)
2533 err |= swsb(file, isa, inst);
2534
2535 err |= control(file, "compaction", cmpt_ctrl, is_compacted, &space);
2536 err |= control(file, "thread control", thread_ctrl,
2537 (devinfo->ver >= 12 ? brw_inst_atomic_control(devinfo, inst) :
2538 brw_inst_thread_control(devinfo, inst)),
2539 &space);
2540 if (has_branch_ctrl(devinfo, opcode)) {
2541 err |= control(file, "branch ctrl", branch_ctrl,
2542 brw_inst_branch_control(devinfo, inst), &space);
2543 } else if (devinfo->ver < 20) {
2544 err |= control(file, "acc write control", accwr,
2545 brw_inst_acc_wr_control(devinfo, inst), &space);
2546 }
2547 if (is_send(opcode))
2548 err |= control(file, "end of thread", end_of_thread,
2549 brw_inst_eot(devinfo, inst), &space);
2550 if (space)
2551 string(file, " ");
2552 string(file, "}");
2553 }
2554 string(file, ";");
2555 newline(file);
2556 return err;
2557 }
2558
2559 int
brw_disassemble_find_end(const struct brw_isa_info * isa,const void * assembly,int start)2560 brw_disassemble_find_end(const struct brw_isa_info *isa,
2561 const void *assembly, int start)
2562 {
2563 const struct intel_device_info *devinfo = isa->devinfo;
2564 int offset = start;
2565
2566 /* This loop exits when send-with-EOT or when opcode is 0 */
2567 while (true) {
2568 const brw_inst *insn = assembly + offset;
2569
2570 if (brw_inst_cmpt_control(devinfo, insn)) {
2571 offset += 8;
2572 } else {
2573 offset += 16;
2574 }
2575
2576 /* Simplistic, but efficient way to terminate disasm */
2577 uint32_t opcode = brw_inst_opcode(isa, insn);
2578 if (opcode == 0 || (is_send(opcode) && brw_inst_eot(devinfo, insn))) {
2579 break;
2580 }
2581 }
2582
2583 return offset;
2584 }
2585
2586 void
brw_disassemble_with_errors(const struct brw_isa_info * isa,const void * assembly,int start,FILE * out)2587 brw_disassemble_with_errors(const struct brw_isa_info *isa,
2588 const void *assembly, int start, FILE *out)
2589 {
2590 int end = brw_disassemble_find_end(isa, assembly, start);
2591
2592 /* Make a dummy disasm structure that brw_validate_instructions
2593 * can work from.
2594 */
2595 struct disasm_info *disasm_info = disasm_initialize(isa, NULL);
2596 disasm_new_inst_group(disasm_info, start);
2597 disasm_new_inst_group(disasm_info, end);
2598
2599 brw_validate_instructions(isa, assembly, start, end, disasm_info);
2600
2601 void *mem_ctx = ralloc_context(NULL);
2602 const struct brw_label *root_label =
2603 brw_label_assembly(isa, assembly, start, end, mem_ctx);
2604
2605 foreach_list_typed(struct inst_group, group, link,
2606 &disasm_info->group_list) {
2607 struct exec_node *next_node = exec_node_get_next(&group->link);
2608 if (exec_node_is_tail_sentinel(next_node))
2609 break;
2610
2611 struct inst_group *next =
2612 exec_node_data(struct inst_group, next_node, link);
2613
2614 int start_offset = group->offset;
2615 int end_offset = next->offset;
2616
2617 brw_disassemble(isa, assembly, start_offset, end_offset,
2618 root_label, out);
2619
2620 if (group->error) {
2621 fputs(group->error, out);
2622 }
2623 }
2624
2625 ralloc_free(mem_ctx);
2626 ralloc_free(disasm_info);
2627 }
2628