• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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