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