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