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