• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2008 Keith Packard
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdarg.h>
26 
27 #include "brw_eu_defines.h"
28 #include "brw_inst.h"
29 #include "brw_shader.h"
30 #include "brw_reg.h"
31 #include "brw_inst.h"
32 #include "brw_eu.h"
33 #include "util/half_float.h"
34 
35 static bool
has_jip(const struct gen_device_info * devinfo,enum opcode opcode)36 has_jip(const struct gen_device_info *devinfo, enum opcode opcode)
37 {
38    if (devinfo->gen < 6)
39       return false;
40 
41    return opcode == BRW_OPCODE_IF ||
42           opcode == BRW_OPCODE_ELSE ||
43           opcode == BRW_OPCODE_ENDIF ||
44           opcode == BRW_OPCODE_WHILE ||
45           opcode == BRW_OPCODE_BREAK ||
46           opcode == BRW_OPCODE_CONTINUE ||
47           opcode == BRW_OPCODE_HALT;
48 }
49 
50 static bool
has_uip(const struct gen_device_info * devinfo,enum opcode opcode)51 has_uip(const struct gen_device_info *devinfo, enum opcode opcode)
52 {
53    if (devinfo->gen < 6)
54       return false;
55 
56    return (devinfo->gen >= 7 && opcode == BRW_OPCODE_IF) ||
57           (devinfo->gen >= 8 && opcode == BRW_OPCODE_ELSE) ||
58           opcode == BRW_OPCODE_BREAK ||
59           opcode == BRW_OPCODE_CONTINUE ||
60           opcode == BRW_OPCODE_HALT;
61 }
62 
63 static bool
has_branch_ctrl(const struct gen_device_info * devinfo,enum opcode opcode)64 has_branch_ctrl(const struct gen_device_info *devinfo, enum opcode opcode)
65 {
66    if (devinfo->gen < 8)
67       return false;
68 
69    return opcode == BRW_OPCODE_IF ||
70           opcode == BRW_OPCODE_ELSE;
71           /* opcode == BRW_OPCODE_GOTO; */
72 }
73 
74 static bool
is_logic_instruction(unsigned opcode)75 is_logic_instruction(unsigned opcode)
76 {
77    return opcode == BRW_OPCODE_AND ||
78           opcode == BRW_OPCODE_NOT ||
79           opcode == BRW_OPCODE_OR ||
80           opcode == BRW_OPCODE_XOR;
81 }
82 
83 const char *const conditional_modifier[16] = {
84    [BRW_CONDITIONAL_NONE] = "",
85    [BRW_CONDITIONAL_Z]    = ".z",
86    [BRW_CONDITIONAL_NZ]   = ".nz",
87    [BRW_CONDITIONAL_G]    = ".g",
88    [BRW_CONDITIONAL_GE]   = ".ge",
89    [BRW_CONDITIONAL_L]    = ".l",
90    [BRW_CONDITIONAL_LE]   = ".le",
91    [BRW_CONDITIONAL_R]    = ".r",
92    [BRW_CONDITIONAL_O]    = ".o",
93    [BRW_CONDITIONAL_U]    = ".u",
94 };
95 
96 static const char *const m_negate[2] = {
97    [0] = "",
98    [1] = "-",
99 };
100 
101 static const char *const _abs[2] = {
102    [0] = "",
103    [1] = "(abs)",
104 };
105 
106 static const char *const m_bitnot[2] = { "", "~" };
107 
108 static const char *const vert_stride[16] = {
109    [0] = "0",
110    [1] = "1",
111    [2] = "2",
112    [3] = "4",
113    [4] = "8",
114    [5] = "16",
115    [6] = "32",
116    [15] = "VxH",
117 };
118 
119 static const char *const width[8] = {
120    [0] = "1",
121    [1] = "2",
122    [2] = "4",
123    [3] = "8",
124    [4] = "16",
125 };
126 
127 static const char *const horiz_stride[4] = {
128    [0] = "0",
129    [1] = "1",
130    [2] = "2",
131    [3] = "4"
132 };
133 
134 static const char *const chan_sel[4] = {
135    [0] = "x",
136    [1] = "y",
137    [2] = "z",
138    [3] = "w",
139 };
140 
141 static const char *const debug_ctrl[2] = {
142    [0] = "",
143    [1] = ".breakpoint"
144 };
145 
146 static const char *const saturate[2] = {
147    [0] = "",
148    [1] = ".sat"
149 };
150 
151 static const char *const cmpt_ctrl[2] = {
152    [0] = "",
153    [1] = "compacted"
154 };
155 
156 static const char *const accwr[2] = {
157    [0] = "",
158    [1] = "AccWrEnable"
159 };
160 
161 static const char *const branch_ctrl[2] = {
162    [0] = "",
163    [1] = "BranchCtrl"
164 };
165 
166 static const char *const wectrl[2] = {
167    [0] = "",
168    [1] = "WE_all"
169 };
170 
171 static const char *const exec_size[8] = {
172    [0] = "1",
173    [1] = "2",
174    [2] = "4",
175    [3] = "8",
176    [4] = "16",
177    [5] = "32"
178 };
179 
180 static const char *const pred_inv[2] = {
181    [0] = "+",
182    [1] = "-"
183 };
184 
185 const char *const pred_ctrl_align16[16] = {
186    [1] = "",
187    [2] = ".x",
188    [3] = ".y",
189    [4] = ".z",
190    [5] = ".w",
191    [6] = ".any4h",
192    [7] = ".all4h",
193 };
194 
195 static const char *const pred_ctrl_align1[16] = {
196    [BRW_PREDICATE_NORMAL]        = "",
197    [BRW_PREDICATE_ALIGN1_ANYV]   = ".anyv",
198    [BRW_PREDICATE_ALIGN1_ALLV]   = ".allv",
199    [BRW_PREDICATE_ALIGN1_ANY2H]  = ".any2h",
200    [BRW_PREDICATE_ALIGN1_ALL2H]  = ".all2h",
201    [BRW_PREDICATE_ALIGN1_ANY4H]  = ".any4h",
202    [BRW_PREDICATE_ALIGN1_ALL4H]  = ".all4h",
203    [BRW_PREDICATE_ALIGN1_ANY8H]  = ".any8h",
204    [BRW_PREDICATE_ALIGN1_ALL8H]  = ".all8h",
205    [BRW_PREDICATE_ALIGN1_ANY16H] = ".any16h",
206    [BRW_PREDICATE_ALIGN1_ALL16H] = ".all16h",
207    [BRW_PREDICATE_ALIGN1_ANY32H] = ".any32h",
208    [BRW_PREDICATE_ALIGN1_ALL32H] = ".all32h",
209 };
210 
211 static const char *const thread_ctrl[4] = {
212    [BRW_THREAD_NORMAL] = "",
213    [BRW_THREAD_ATOMIC] = "atomic",
214    [BRW_THREAD_SWITCH] = "switch",
215 };
216 
217 static const char *const compr_ctrl[4] = {
218    [0] = "",
219    [1] = "sechalf",
220    [2] = "compr",
221    [3] = "compr4",
222 };
223 
224 static const char *const dep_ctrl[4] = {
225    [0] = "",
226    [1] = "NoDDClr",
227    [2] = "NoDDChk",
228    [3] = "NoDDClr,NoDDChk",
229 };
230 
231 static const char *const mask_ctrl[4] = {
232    [0] = "",
233    [1] = "nomask",
234 };
235 
236 static const char *const access_mode[2] = {
237    [0] = "align1",
238    [1] = "align16",
239 };
240 
241 static const char *const reg_file[4] = {
242    [0] = "A",
243    [1] = "g",
244    [2] = "m",
245    [3] = "imm",
246 };
247 
248 static const char *const writemask[16] = {
249    [0x0] = ".",
250    [0x1] = ".x",
251    [0x2] = ".y",
252    [0x3] = ".xy",
253    [0x4] = ".z",
254    [0x5] = ".xz",
255    [0x6] = ".yz",
256    [0x7] = ".xyz",
257    [0x8] = ".w",
258    [0x9] = ".xw",
259    [0xa] = ".yw",
260    [0xb] = ".xyw",
261    [0xc] = ".zw",
262    [0xd] = ".xzw",
263    [0xe] = ".yzw",
264    [0xf] = "",
265 };
266 
267 static const char *const end_of_thread[2] = {
268    [0] = "",
269    [1] = "EOT"
270 };
271 
272 /* SFIDs on Gen4-5 */
273 static const char *const gen4_sfid[16] = {
274    [BRW_SFID_NULL]            = "null",
275    [BRW_SFID_MATH]            = "math",
276    [BRW_SFID_SAMPLER]         = "sampler",
277    [BRW_SFID_MESSAGE_GATEWAY] = "gateway",
278    [BRW_SFID_DATAPORT_READ]   = "read",
279    [BRW_SFID_DATAPORT_WRITE]  = "write",
280    [BRW_SFID_URB]             = "urb",
281    [BRW_SFID_THREAD_SPAWNER]  = "thread_spawner",
282    [BRW_SFID_VME]             = "vme",
283 };
284 
285 static const char *const gen6_sfid[16] = {
286    [BRW_SFID_NULL]                     = "null",
287    [BRW_SFID_MATH]                     = "math",
288    [BRW_SFID_SAMPLER]                  = "sampler",
289    [BRW_SFID_MESSAGE_GATEWAY]          = "gateway",
290    [BRW_SFID_URB]                      = "urb",
291    [BRW_SFID_THREAD_SPAWNER]           = "thread_spawner",
292    [GEN6_SFID_DATAPORT_SAMPLER_CACHE]  = "sampler",
293    [GEN6_SFID_DATAPORT_RENDER_CACHE]   = "render",
294    [GEN6_SFID_DATAPORT_CONSTANT_CACHE] = "const",
295    [GEN7_SFID_DATAPORT_DATA_CACHE]     = "data",
296    [GEN7_SFID_PIXEL_INTERPOLATOR]      = "pixel interp",
297    [HSW_SFID_DATAPORT_DATA_CACHE_1]    = "dp data 1",
298    [HSW_SFID_CRE]                      = "cre",
299 };
300 
301 static const char *const gen7_gateway_subfuncid[8] = {
302    [BRW_MESSAGE_GATEWAY_SFID_OPEN_GATEWAY] = "open",
303    [BRW_MESSAGE_GATEWAY_SFID_CLOSE_GATEWAY] = "close",
304    [BRW_MESSAGE_GATEWAY_SFID_FORWARD_MSG] = "forward msg",
305    [BRW_MESSAGE_GATEWAY_SFID_GET_TIMESTAMP] = "get timestamp",
306    [BRW_MESSAGE_GATEWAY_SFID_BARRIER_MSG] = "barrier msg",
307    [BRW_MESSAGE_GATEWAY_SFID_UPDATE_GATEWAY_STATE] = "update state",
308    [BRW_MESSAGE_GATEWAY_SFID_MMIO_READ_WRITE] = "mmio read/write",
309 };
310 
311 static const char *const gen4_dp_read_port_msg_type[4] = {
312    [0b00] = "OWord Block Read",
313    [0b01] = "OWord Dual Block Read",
314    [0b10] = "Media Block Read",
315    [0b11] = "DWord Scattered Read",
316 };
317 
318 static const char *const g45_dp_read_port_msg_type[8] = {
319    [0b000] = "OWord Block Read",
320    [0b010] = "OWord Dual Block Read",
321    [0b100] = "Media Block Read",
322    [0b110] = "DWord Scattered Read",
323    [0b001] = "Render Target UNORM Read",
324    [0b011] = "AVC Loop Filter Read",
325 };
326 
327 static const char *const dp_write_port_msg_type[8] = {
328    [0b000] = "OWord block write",
329    [0b001] = "OWord dual block write",
330    [0b010] = "media block write",
331    [0b011] = "DWord scattered write",
332    [0b100] = "RT write",
333    [0b101] = "streamed VB write",
334    [0b110] = "RT UNORM write", /* G45+ */
335    [0b111] = "flush render cache",
336 };
337 
338 static const char *const dp_rc_msg_type_gen6[16] = {
339    [BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ] = "OWORD block read",
340    [GEN6_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ] = "RT UNORM read",
341    [GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ] = "OWORD dual block read",
342    [GEN6_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ] = "media block read",
343    [GEN6_DATAPORT_READ_MESSAGE_OWORD_UNALIGN_BLOCK_READ] =
344       "OWORD unaligned block read",
345    [GEN6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ] = "DWORD scattered read",
346    [GEN6_DATAPORT_WRITE_MESSAGE_DWORD_ATOMIC_WRITE] = "DWORD atomic write",
347    [GEN6_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE] = "OWORD block write",
348    [GEN6_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE] =
349       "OWORD dual block write",
350    [GEN6_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE] = "media block write",
351    [GEN6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE] =
352       "DWORD scattered write",
353    [GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE] = "RT write",
354    [GEN6_DATAPORT_WRITE_MESSAGE_STREAMED_VB_WRITE] = "streamed VB write",
355    [GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_UNORM_WRITE] = "RT UNORM write",
356 };
357 
358 static const char *const dp_rc_msg_type_gen7[16] = {
359    [GEN7_DATAPORT_RC_MEDIA_BLOCK_READ] = "media block read",
360    [GEN7_DATAPORT_RC_TYPED_SURFACE_READ] = "typed surface read",
361    [GEN7_DATAPORT_RC_TYPED_ATOMIC_OP] = "typed atomic op",
362    [GEN7_DATAPORT_RC_MEMORY_FENCE] = "memory fence",
363    [GEN7_DATAPORT_RC_MEDIA_BLOCK_WRITE] = "media block write",
364    [GEN7_DATAPORT_RC_RENDER_TARGET_WRITE] = "RT write",
365    [GEN7_DATAPORT_RC_TYPED_SURFACE_WRITE] = "typed surface write"
366 };
367 
368 static const char *const dp_rc_msg_type_gen9[16] = {
369    [GEN9_DATAPORT_RC_RENDER_TARGET_WRITE] = "RT write",
370    [GEN9_DATAPORT_RC_RENDER_TARGET_READ] = "RT read"
371 };
372 
373 static const char *const *
dp_rc_msg_type(const struct gen_device_info * devinfo)374 dp_rc_msg_type(const struct gen_device_info *devinfo)
375 {
376    return (devinfo->gen >= 9 ? dp_rc_msg_type_gen9 :
377            devinfo->gen >= 7 ? dp_rc_msg_type_gen7 :
378            devinfo->gen >= 6 ? dp_rc_msg_type_gen6 :
379            dp_write_port_msg_type);
380 }
381 
382 static const char *const m_rt_write_subtype[] = {
383    [0b000] = "SIMD16",
384    [0b001] = "SIMD16/RepData",
385    [0b010] = "SIMD8/DualSrcLow",
386    [0b011] = "SIMD8/DualSrcHigh",
387    [0b100] = "SIMD8",
388    [0b101] = "SIMD8/ImageWrite",   /* Gen6+ */
389    [0b111] = "SIMD16/RepData-111", /* no idea how this is different than 1 */
390 };
391 
392 static const char *const dp_dc0_msg_type_gen7[16] = {
393    [GEN7_DATAPORT_DC_OWORD_BLOCK_READ] = "DC OWORD block read",
394    [GEN7_DATAPORT_DC_UNALIGNED_OWORD_BLOCK_READ] =
395       "DC unaligned OWORD block read",
396    [GEN7_DATAPORT_DC_OWORD_DUAL_BLOCK_READ] = "DC OWORD dual block read",
397    [GEN7_DATAPORT_DC_DWORD_SCATTERED_READ] = "DC DWORD scattered read",
398    [GEN7_DATAPORT_DC_BYTE_SCATTERED_READ] = "DC byte scattered read",
399    [GEN7_DATAPORT_DC_UNTYPED_SURFACE_READ] = "DC untyped surface read",
400    [GEN7_DATAPORT_DC_UNTYPED_ATOMIC_OP] = "DC untyped atomic",
401    [GEN7_DATAPORT_DC_MEMORY_FENCE] = "DC mfence",
402    [GEN7_DATAPORT_DC_OWORD_BLOCK_WRITE] = "DC OWORD block write",
403    [GEN7_DATAPORT_DC_OWORD_DUAL_BLOCK_WRITE] = "DC OWORD dual block write",
404    [GEN7_DATAPORT_DC_DWORD_SCATTERED_WRITE] = "DC DWORD scatterd write",
405    [GEN7_DATAPORT_DC_BYTE_SCATTERED_WRITE] = "DC byte scattered write",
406    [GEN7_DATAPORT_DC_UNTYPED_SURFACE_WRITE] = "DC untyped surface write",
407 };
408 
409 static const char *const dp_dc1_msg_type_hsw[16] = {
410    [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ] = "untyped surface read",
411    [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP] = "DC untyped atomic op",
412    [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2] =
413       "DC untyped 4x2 atomic op",
414    [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_READ] = "DC media block read",
415    [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ] = "DC typed surface read",
416    [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP] = "DC typed atomic",
417    [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2] = "DC typed 4x2 atomic op",
418    [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE] = "DC untyped surface write",
419    [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_WRITE] = "DC media block write",
420    [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP] = "DC atomic counter op",
421    [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2] =
422       "DC 4x2 atomic counter op",
423    [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE] = "DC typed surface write",
424 };
425 
426 static const char *const aop[16] = {
427    [BRW_AOP_AND]    = "and",
428    [BRW_AOP_OR]     = "or",
429    [BRW_AOP_XOR]    = "xor",
430    [BRW_AOP_MOV]    = "mov",
431    [BRW_AOP_INC]    = "inc",
432    [BRW_AOP_DEC]    = "dec",
433    [BRW_AOP_ADD]    = "add",
434    [BRW_AOP_SUB]    = "sub",
435    [BRW_AOP_REVSUB] = "revsub",
436    [BRW_AOP_IMAX]   = "imax",
437    [BRW_AOP_IMIN]   = "imin",
438    [BRW_AOP_UMAX]   = "umax",
439    [BRW_AOP_UMIN]   = "umin",
440    [BRW_AOP_CMPWR]  = "cmpwr",
441    [BRW_AOP_PREDEC] = "predec",
442 };
443 
444 static const char * const pixel_interpolator_msg_types[4] = {
445     [GEN7_PIXEL_INTERPOLATOR_LOC_SHARED_OFFSET] = "per_message_offset",
446     [GEN7_PIXEL_INTERPOLATOR_LOC_SAMPLE] = "sample_position",
447     [GEN7_PIXEL_INTERPOLATOR_LOC_CENTROID] = "centroid",
448     [GEN7_PIXEL_INTERPOLATOR_LOC_PER_SLOT_OFFSET] = "per_slot_offset",
449 };
450 
451 static const char *const math_function[16] = {
452    [BRW_MATH_FUNCTION_INV]    = "inv",
453    [BRW_MATH_FUNCTION_LOG]    = "log",
454    [BRW_MATH_FUNCTION_EXP]    = "exp",
455    [BRW_MATH_FUNCTION_SQRT]   = "sqrt",
456    [BRW_MATH_FUNCTION_RSQ]    = "rsq",
457    [BRW_MATH_FUNCTION_SIN]    = "sin",
458    [BRW_MATH_FUNCTION_COS]    = "cos",
459    [BRW_MATH_FUNCTION_SINCOS] = "sincos",
460    [BRW_MATH_FUNCTION_FDIV]   = "fdiv",
461    [BRW_MATH_FUNCTION_POW]    = "pow",
462    [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod",
463    [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT]  = "intdiv",
464    [BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intmod",
465    [GEN8_MATH_FUNCTION_INVM]  = "invm",
466    [GEN8_MATH_FUNCTION_RSQRTM] = "rsqrtm",
467 };
468 
469 static const char *const math_saturate[2] = {
470    [0] = "",
471    [1] = "sat"
472 };
473 
474 static const char *const math_signed[2] = {
475    [0] = "",
476    [1] = "signed"
477 };
478 
479 static const char *const math_scalar[2] = {
480    [0] = "",
481    [1] = "scalar"
482 };
483 
484 static const char *const math_precision[2] = {
485    [0] = "",
486    [1] = "partial_precision"
487 };
488 
489 static const char *const gen5_urb_opcode[] = {
490    [0] = "urb_write",
491    [1] = "ff_sync",
492 };
493 
494 static const char *const gen7_urb_opcode[] = {
495    [BRW_URB_OPCODE_WRITE_HWORD] = "write HWord",
496    [BRW_URB_OPCODE_WRITE_OWORD] = "write OWord",
497    [BRW_URB_OPCODE_READ_HWORD] = "read HWord",
498    [BRW_URB_OPCODE_READ_OWORD] = "read OWord",
499    [GEN7_URB_OPCODE_ATOMIC_MOV] = "atomic mov",  /* Gen7+ */
500    [GEN7_URB_OPCODE_ATOMIC_INC] = "atomic inc",  /* Gen7+ */
501    [GEN8_URB_OPCODE_ATOMIC_ADD] = "atomic add",  /* Gen8+ */
502    [GEN8_URB_OPCODE_SIMD8_WRITE] = "SIMD8 write", /* Gen8+ */
503    [GEN8_URB_OPCODE_SIMD8_READ] = "SIMD8 read",  /* Gen8+ */
504    /* [9-15] - reserved */
505 };
506 
507 static const char *const urb_swizzle[4] = {
508    [BRW_URB_SWIZZLE_NONE]       = "",
509    [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave",
510    [BRW_URB_SWIZZLE_TRANSPOSE]  = "transpose",
511 };
512 
513 static const char *const urb_allocate[2] = {
514    [0] = "",
515    [1] = "allocate"
516 };
517 
518 static const char *const urb_used[2] = {
519    [0] = "",
520    [1] = "used"
521 };
522 
523 static const char *const urb_complete[2] = {
524    [0] = "",
525    [1] = "complete"
526 };
527 
528 static const char *const gen5_sampler_msg_type[] = {
529    [GEN5_SAMPLER_MESSAGE_SAMPLE]              = "sample",
530    [GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS]         = "sample_b",
531    [GEN5_SAMPLER_MESSAGE_SAMPLE_LOD]          = "sample_l",
532    [GEN5_SAMPLER_MESSAGE_SAMPLE_COMPARE]      = "sample_c",
533    [GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS]       = "sample_d",
534    [GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE] = "sample_b_c",
535    [GEN5_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE]  = "sample_l_c",
536    [GEN5_SAMPLER_MESSAGE_SAMPLE_LD]           = "ld",
537    [GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4]      = "gather4",
538    [GEN5_SAMPLER_MESSAGE_LOD]                 = "lod",
539    [GEN5_SAMPLER_MESSAGE_SAMPLE_RESINFO]      = "resinfo",
540    [GEN6_SAMPLER_MESSAGE_SAMPLE_SAMPLEINFO]   = "sampleinfo",
541    [GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_C]    = "gather4_c",
542    [GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO]   = "gather4_po",
543    [GEN7_SAMPLER_MESSAGE_SAMPLE_GATHER4_PO_C] = "gather4_po_c",
544    [HSW_SAMPLER_MESSAGE_SAMPLE_DERIV_COMPARE] = "sample_d_c",
545    [GEN9_SAMPLER_MESSAGE_SAMPLE_LZ]           = "sample_lz",
546    [GEN9_SAMPLER_MESSAGE_SAMPLE_C_LZ]         = "sample_c_lz",
547    [GEN9_SAMPLER_MESSAGE_SAMPLE_LD_LZ]        = "ld_lz",
548    [GEN9_SAMPLER_MESSAGE_SAMPLE_LD2DMS_W]     = "ld2dms_w",
549    [GEN7_SAMPLER_MESSAGE_SAMPLE_LD_MCS]       = "ld_mcs",
550    [GEN7_SAMPLER_MESSAGE_SAMPLE_LD2DMS]       = "ld2dms",
551    [GEN7_SAMPLER_MESSAGE_SAMPLE_LD2DSS]       = "ld2dss",
552 };
553 
554 static const char *const gen5_sampler_simd_mode[4] = {
555    [BRW_SAMPLER_SIMD_MODE_SIMD4X2]   = "SIMD4x2",
556    [BRW_SAMPLER_SIMD_MODE_SIMD8]     = "SIMD8",
557    [BRW_SAMPLER_SIMD_MODE_SIMD16]    = "SIMD16",
558    [BRW_SAMPLER_SIMD_MODE_SIMD32_64] = "SIMD32/64",
559 };
560 
561 static const char *const sampler_target_format[4] = {
562    [0] = "F",
563    [2] = "UD",
564    [3] = "D"
565 };
566 
567 
568 static int column;
569 
570 static int
string(FILE * file,const char * string)571 string(FILE *file, const char *string)
572 {
573    fputs(string, file);
574    column += strlen(string);
575    return 0;
576 }
577 
578 static int
579 format(FILE *f, const char *format, ...) PRINTFLIKE(2, 3);
580 
581 static int
format(FILE * f,const char * format,...)582 format(FILE *f, const char *format, ...)
583 {
584    char buf[1024];
585    va_list args;
586    va_start(args, format);
587 
588    vsnprintf(buf, sizeof(buf) - 1, format, args);
589    va_end(args);
590    string(f, buf);
591    return 0;
592 }
593 
594 static int
newline(FILE * f)595 newline(FILE *f)
596 {
597    putc('\n', f);
598    column = 0;
599    return 0;
600 }
601 
602 static int
pad(FILE * f,int c)603 pad(FILE *f, int c)
604 {
605    do
606       string(f, " ");
607    while (column < c);
608    return 0;
609 }
610 
611 static int
control(FILE * file,const char * name,const char * const ctrl[],unsigned id,int * space)612 control(FILE *file, const char *name, const char *const ctrl[],
613         unsigned id, int *space)
614 {
615    if (!ctrl[id]) {
616       fprintf(file, "*** invalid %s value %d ", name, id);
617       return 1;
618    }
619    if (ctrl[id][0]) {
620       if (space && *space)
621          string(file, " ");
622       string(file, ctrl[id]);
623       if (space)
624          *space = 1;
625    }
626    return 0;
627 }
628 
629 static int
print_opcode(FILE * file,const struct gen_device_info * devinfo,enum opcode id)630 print_opcode(FILE *file, const struct gen_device_info *devinfo,
631              enum opcode id)
632 {
633    const struct opcode_desc *desc = brw_opcode_desc(devinfo, id);
634    if (!desc) {
635       format(file, "*** invalid opcode value %d ", id);
636       return 1;
637    }
638    string(file, desc->name);
639    return 0;
640 }
641 
642 static int
reg(FILE * file,unsigned _reg_file,unsigned _reg_nr)643 reg(FILE *file, unsigned _reg_file, unsigned _reg_nr)
644 {
645    int err = 0;
646 
647    /* Clear the Compr4 instruction compression bit. */
648    if (_reg_file == BRW_MESSAGE_REGISTER_FILE)
649       _reg_nr &= ~BRW_MRF_COMPR4;
650 
651    if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
652       switch (_reg_nr & 0xf0) {
653       case BRW_ARF_NULL:
654          string(file, "null");
655          break;
656       case BRW_ARF_ADDRESS:
657          format(file, "a%d", _reg_nr & 0x0f);
658          break;
659       case BRW_ARF_ACCUMULATOR:
660          format(file, "acc%d", _reg_nr & 0x0f);
661          break;
662       case BRW_ARF_FLAG:
663          format(file, "f%d", _reg_nr & 0x0f);
664          break;
665       case BRW_ARF_MASK:
666          format(file, "mask%d", _reg_nr & 0x0f);
667          break;
668       case BRW_ARF_MASK_STACK:
669          format(file, "msd%d", _reg_nr & 0x0f);
670          break;
671       case BRW_ARF_STATE:
672          format(file, "sr%d", _reg_nr & 0x0f);
673          break;
674       case BRW_ARF_CONTROL:
675          format(file, "cr%d", _reg_nr & 0x0f);
676          break;
677       case BRW_ARF_NOTIFICATION_COUNT:
678          format(file, "n%d", _reg_nr & 0x0f);
679          break;
680       case BRW_ARF_IP:
681          string(file, "ip");
682          return -1;
683          break;
684       case BRW_ARF_TDR:
685          format(file, "tdr0");
686          return -1;
687       case BRW_ARF_TIMESTAMP:
688          format(file, "tm%d", _reg_nr & 0x0f);
689          break;
690       default:
691          format(file, "ARF%d", _reg_nr);
692          break;
693       }
694    } else {
695       err |= control(file, "src reg file", reg_file, _reg_file, NULL);
696       format(file, "%d", _reg_nr);
697    }
698    return err;
699 }
700 
701 static int
dest(FILE * file,const struct gen_device_info * devinfo,const brw_inst * inst)702 dest(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst)
703 {
704    enum brw_reg_type type = brw_inst_dst_type(devinfo, inst);
705    unsigned elem_size = brw_reg_type_to_size(type);
706    int err = 0;
707 
708    if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
709       if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
710          err |= reg(file, brw_inst_dst_reg_file(devinfo, inst),
711                     brw_inst_dst_da_reg_nr(devinfo, inst));
712          if (err == -1)
713             return 0;
714          if (brw_inst_dst_da1_subreg_nr(devinfo, inst))
715             format(file, ".%"PRIu64, brw_inst_dst_da1_subreg_nr(devinfo, inst) /
716                    elem_size);
717          string(file, "<");
718          err |= control(file, "horiz stride", horiz_stride,
719                         brw_inst_dst_hstride(devinfo, inst), NULL);
720          string(file, ">");
721          string(file, brw_reg_type_to_letters(type));
722       } else {
723          string(file, "g[a0");
724          if (brw_inst_dst_ia_subreg_nr(devinfo, inst))
725             format(file, ".%"PRIu64, brw_inst_dst_ia_subreg_nr(devinfo, inst) /
726                    elem_size);
727          if (brw_inst_dst_ia1_addr_imm(devinfo, inst))
728             format(file, " %d", brw_inst_dst_ia1_addr_imm(devinfo, inst));
729          string(file, "]<");
730          err |= control(file, "horiz stride", horiz_stride,
731                         brw_inst_dst_hstride(devinfo, inst), NULL);
732          string(file, ">");
733          string(file, brw_reg_type_to_letters(type));
734       }
735    } else {
736       if (brw_inst_dst_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
737          err |= reg(file, brw_inst_dst_reg_file(devinfo, inst),
738                     brw_inst_dst_da_reg_nr(devinfo, inst));
739          if (err == -1)
740             return 0;
741          if (brw_inst_dst_da16_subreg_nr(devinfo, inst))
742             format(file, ".%u", 16 / elem_size);
743          string(file, "<1>");
744          err |= control(file, "writemask", writemask,
745                         brw_inst_da16_writemask(devinfo, inst), NULL);
746          string(file, brw_reg_type_to_letters(type));
747       } else {
748          err = 1;
749          string(file, "Indirect align16 address mode not supported");
750       }
751    }
752 
753    return 0;
754 }
755 
756 static int
dest_3src(FILE * file,const struct gen_device_info * devinfo,const brw_inst * inst)757 dest_3src(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst)
758 {
759    bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1;
760    int err = 0;
761    uint32_t reg_file;
762    unsigned subreg_nr;
763    enum brw_reg_type type;
764 
765    if (is_align1 && brw_inst_3src_a1_dst_reg_file(devinfo, inst))
766       reg_file = BRW_ARCHITECTURE_REGISTER_FILE;
767    else if (devinfo->gen == 6 && brw_inst_3src_a16_dst_reg_file(devinfo, inst))
768       reg_file = BRW_MESSAGE_REGISTER_FILE;
769    else
770       reg_file = BRW_GENERAL_REGISTER_FILE;
771 
772    err |= reg(file, reg_file, brw_inst_3src_dst_reg_nr(devinfo, inst));
773    if (err == -1)
774       return 0;
775 
776    if (is_align1) {
777       type = brw_inst_3src_a1_dst_type(devinfo, inst);
778       subreg_nr = brw_inst_3src_a1_dst_subreg_nr(devinfo, inst);
779    } else {
780       type = brw_inst_3src_a16_dst_type(devinfo, inst);
781       subreg_nr = brw_inst_3src_a16_dst_subreg_nr(devinfo, inst) * 4;
782    }
783    subreg_nr /= brw_reg_type_to_size(type);
784 
785    if (subreg_nr)
786       format(file, ".%u", subreg_nr);
787    string(file, "<1>");
788 
789    if (!is_align1) {
790       err |= control(file, "writemask", writemask,
791                      brw_inst_3src_a16_dst_writemask(devinfo, inst), NULL);
792    }
793    string(file, brw_reg_type_to_letters(type));
794 
795    return 0;
796 }
797 
798 static int
src_align1_region(FILE * file,unsigned _vert_stride,unsigned _width,unsigned _horiz_stride)799 src_align1_region(FILE *file,
800                   unsigned _vert_stride, unsigned _width,
801                   unsigned _horiz_stride)
802 {
803    int err = 0;
804    string(file, "<");
805    err |= control(file, "vert stride", vert_stride, _vert_stride, NULL);
806    string(file, ",");
807    err |= control(file, "width", width, _width, NULL);
808    string(file, ",");
809    err |= control(file, "horiz_stride", horiz_stride, _horiz_stride, NULL);
810    string(file, ">");
811    return err;
812 }
813 
814 static int
src_da1(FILE * file,const struct gen_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)815 src_da1(FILE *file,
816         const struct gen_device_info *devinfo,
817         unsigned opcode,
818         enum brw_reg_type type, unsigned _reg_file,
819         unsigned _vert_stride, unsigned _width, unsigned _horiz_stride,
820         unsigned reg_num, unsigned sub_reg_num, unsigned __abs,
821         unsigned _negate)
822 {
823    int err = 0;
824 
825    if (devinfo->gen >= 8 && is_logic_instruction(opcode))
826       err |= control(file, "bitnot", m_bitnot, _negate, NULL);
827    else
828       err |= control(file, "negate", m_negate, _negate, NULL);
829 
830    err |= control(file, "abs", _abs, __abs, NULL);
831 
832    err |= reg(file, _reg_file, reg_num);
833    if (err == -1)
834       return 0;
835    if (sub_reg_num) {
836       unsigned elem_size = brw_reg_type_to_size(type);
837       format(file, ".%d", sub_reg_num / elem_size);   /* use formal style like spec */
838    }
839    src_align1_region(file, _vert_stride, _width, _horiz_stride);
840    string(file, brw_reg_type_to_letters(type));
841    return err;
842 }
843 
844 static int
src_ia1(FILE * file,const struct gen_device_info * devinfo,unsigned opcode,enum brw_reg_type type,unsigned _reg_file,int _addr_imm,unsigned _addr_subreg_nr,unsigned _negate,unsigned __abs,unsigned _horiz_stride,unsigned _width,unsigned _vert_stride)845 src_ia1(FILE *file,
846         const struct gen_device_info *devinfo,
847         unsigned opcode,
848         enum brw_reg_type type,
849         unsigned _reg_file,
850         int _addr_imm,
851         unsigned _addr_subreg_nr,
852         unsigned _negate,
853         unsigned __abs,
854         unsigned _horiz_stride, unsigned _width, unsigned _vert_stride)
855 {
856    int err = 0;
857 
858    if (devinfo->gen >= 8 && is_logic_instruction(opcode))
859       err |= control(file, "bitnot", m_bitnot, _negate, NULL);
860    else
861       err |= control(file, "negate", m_negate, _negate, NULL);
862 
863    err |= control(file, "abs", _abs, __abs, NULL);
864 
865    string(file, "g[a0");
866    if (_addr_subreg_nr)
867       format(file, ".%d", _addr_subreg_nr);
868    if (_addr_imm)
869       format(file, " %d", _addr_imm);
870    string(file, "]");
871    src_align1_region(file, _vert_stride, _width, _horiz_stride);
872    string(file, brw_reg_type_to_letters(type));
873    return err;
874 }
875 
876 static int
src_swizzle(FILE * file,unsigned swiz)877 src_swizzle(FILE *file, unsigned swiz)
878 {
879    unsigned x = BRW_GET_SWZ(swiz, BRW_CHANNEL_X);
880    unsigned y = BRW_GET_SWZ(swiz, BRW_CHANNEL_Y);
881    unsigned z = BRW_GET_SWZ(swiz, BRW_CHANNEL_Z);
882    unsigned w = BRW_GET_SWZ(swiz, BRW_CHANNEL_W);
883    int err = 0;
884 
885    if (x == y && x == z && x == w) {
886       string(file, ".");
887       err |= control(file, "channel select", chan_sel, x, NULL);
888    } else if (swiz != BRW_SWIZZLE_XYZW) {
889       string(file, ".");
890       err |= control(file, "channel select", chan_sel, x, NULL);
891       err |= control(file, "channel select", chan_sel, y, NULL);
892       err |= control(file, "channel select", chan_sel, z, NULL);
893       err |= control(file, "channel select", chan_sel, w, NULL);
894    }
895    return err;
896 }
897 
898 static int
src_da16(FILE * file,const struct gen_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)899 src_da16(FILE *file,
900          const struct gen_device_info *devinfo,
901          unsigned opcode,
902          enum brw_reg_type type,
903          unsigned _reg_file,
904          unsigned _vert_stride,
905          unsigned _reg_nr,
906          unsigned _subreg_nr,
907          unsigned __abs,
908          unsigned _negate,
909          unsigned swz_x, unsigned swz_y, unsigned swz_z, unsigned swz_w)
910 {
911    int err = 0;
912 
913    if (devinfo->gen >= 8 && is_logic_instruction(opcode))
914       err |= control(file, "bitnot", m_bitnot, _negate, NULL);
915    else
916       err |= control(file, "negate", m_negate, _negate, NULL);
917 
918    err |= control(file, "abs", _abs, __abs, NULL);
919 
920    err |= reg(file, _reg_file, _reg_nr);
921    if (err == -1)
922       return 0;
923    if (_subreg_nr) {
924       unsigned elem_size = brw_reg_type_to_size(type);
925 
926       /* bit4 for subreg number byte addressing. Make this same meaning as
927          in da1 case, so output looks consistent. */
928       format(file, ".%d", 16 / elem_size);
929    }
930    string(file, "<");
931    err |= control(file, "vert stride", vert_stride, _vert_stride, NULL);
932    string(file, ">");
933    err |= src_swizzle(file, BRW_SWIZZLE4(swz_x, swz_y, swz_z, swz_w));
934    string(file, brw_reg_type_to_letters(type));
935    return err;
936 }
937 
938 static enum brw_vertical_stride
vstride_from_align1_3src_vstride(enum gen10_align1_3src_vertical_stride vstride)939 vstride_from_align1_3src_vstride(enum gen10_align1_3src_vertical_stride vstride)
940 {
941    switch (vstride) {
942    case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_0: return BRW_VERTICAL_STRIDE_0;
943    case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_2: return BRW_VERTICAL_STRIDE_2;
944    case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_4: return BRW_VERTICAL_STRIDE_4;
945    case BRW_ALIGN1_3SRC_VERTICAL_STRIDE_8: return BRW_VERTICAL_STRIDE_8;
946    default:
947       unreachable("not reached");
948    }
949 }
950 
951 static enum brw_horizontal_stride
hstride_from_align1_3src_hstride(enum gen10_align1_3src_src_horizontal_stride hstride)952 hstride_from_align1_3src_hstride(enum gen10_align1_3src_src_horizontal_stride hstride)
953 {
954    switch (hstride) {
955    case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_0: return BRW_HORIZONTAL_STRIDE_0;
956    case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_1: return BRW_HORIZONTAL_STRIDE_1;
957    case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_2: return BRW_HORIZONTAL_STRIDE_2;
958    case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_4: return BRW_HORIZONTAL_STRIDE_4;
959    default:
960       unreachable("not reached");
961    }
962 }
963 
964 static enum brw_vertical_stride
vstride_from_align1_3src_hstride(enum gen10_align1_3src_src_horizontal_stride hstride)965 vstride_from_align1_3src_hstride(enum gen10_align1_3src_src_horizontal_stride hstride)
966 {
967    switch (hstride) {
968    case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_0: return BRW_VERTICAL_STRIDE_0;
969    case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_1: return BRW_VERTICAL_STRIDE_1;
970    case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_2: return BRW_VERTICAL_STRIDE_2;
971    case BRW_ALIGN1_3SRC_SRC_HORIZONTAL_STRIDE_4: return BRW_VERTICAL_STRIDE_4;
972    default:
973       unreachable("not reached");
974    }
975 }
976 
977 /* From "GEN10 Regioning Rules for Align1 Ternary Operations" in the
978  * "Register Region Restrictions" documentation
979  */
980 static enum brw_width
implied_width(enum brw_vertical_stride _vert_stride,enum brw_horizontal_stride _horiz_stride)981 implied_width(enum brw_vertical_stride _vert_stride,
982               enum brw_horizontal_stride _horiz_stride)
983 {
984    /* "1. Width is 1 when Vertical and Horizontal Strides are both zero." */
985    if (_vert_stride == BRW_VERTICAL_STRIDE_0 &&
986        _horiz_stride == BRW_HORIZONTAL_STRIDE_0) {
987       return BRW_WIDTH_1;
988 
989    /* "2. Width is equal to vertical stride when Horizontal Stride is zero." */
990    } else if (_horiz_stride == BRW_HORIZONTAL_STRIDE_0) {
991       switch (_vert_stride) {
992       case BRW_VERTICAL_STRIDE_2: return BRW_WIDTH_2;
993       case BRW_VERTICAL_STRIDE_4: return BRW_WIDTH_4;
994       case BRW_VERTICAL_STRIDE_8: return BRW_WIDTH_8;
995       case BRW_VERTICAL_STRIDE_0:
996       default:
997          unreachable("not reached");
998       }
999 
1000    } else {
1001       /* FINISHME: Implement these: */
1002 
1003       /* "3. Width is equal to Vertical Stride/Horizontal Stride when both
1004        *     Strides are non-zero.
1005        *
1006        *  4. Vertical Stride must not be zero if Horizontal Stride is non-zero.
1007        *     This implies Vertical Stride is always greater than Horizontal
1008        *     Stride."
1009        *
1010        * Given these statements and the knowledge that the stride and width
1011        * values are encoded in logarithmic form, we can perform the division
1012        * by just subtracting.
1013        */
1014       return _vert_stride - _horiz_stride;
1015    }
1016 }
1017 
1018 static int
src0_3src(FILE * file,const struct gen_device_info * devinfo,const brw_inst * inst)1019 src0_3src(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst)
1020 {
1021    int err = 0;
1022    unsigned reg_nr, subreg_nr;
1023    enum brw_reg_file _file;
1024    enum brw_reg_type type;
1025    enum brw_vertical_stride _vert_stride;
1026    enum brw_width _width;
1027    enum brw_horizontal_stride _horiz_stride;
1028    bool is_scalar_region;
1029    bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1;
1030 
1031    if (is_align1) {
1032       if (brw_inst_3src_a1_src0_reg_file(devinfo, inst) ==
1033           BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE) {
1034          _file = BRW_GENERAL_REGISTER_FILE;
1035          reg_nr = brw_inst_3src_src0_reg_nr(devinfo, inst);
1036          subreg_nr = brw_inst_3src_a1_src0_subreg_nr(devinfo, inst);
1037          type = brw_inst_3src_a1_src0_type(devinfo, inst);
1038       } else {
1039          _file = BRW_IMMEDIATE_VALUE;
1040          uint16_t imm_val = brw_inst_3src_a1_src0_imm(devinfo, inst);
1041          enum brw_reg_type type = brw_inst_3src_a1_src0_type(devinfo, inst);
1042 
1043          if (type == BRW_REGISTER_TYPE_W) {
1044             format(file, "%dW", imm_val);
1045          } else if (type == BRW_REGISTER_TYPE_UW) {
1046             format(file, "0x%04xUW", imm_val);
1047          } else if (type == BRW_REGISTER_TYPE_HF) {
1048             format(file, "%-gF", _mesa_half_to_float(imm_val));
1049          }
1050          return 0;
1051       }
1052 
1053       _vert_stride = vstride_from_align1_3src_vstride(
1054                         brw_inst_3src_a1_src0_vstride(devinfo, inst));
1055       _horiz_stride = hstride_from_align1_3src_hstride(
1056                          brw_inst_3src_a1_src0_hstride(devinfo, inst));
1057       _width = implied_width(_vert_stride, _horiz_stride);
1058    } else {
1059       _file = BRW_GENERAL_REGISTER_FILE;
1060       reg_nr = brw_inst_3src_src0_reg_nr(devinfo, inst);
1061       subreg_nr = brw_inst_3src_a16_src0_subreg_nr(devinfo, inst) * 4;
1062       type = brw_inst_3src_a16_src_type(devinfo, inst);
1063 
1064       if (brw_inst_3src_a16_src0_rep_ctrl(devinfo, inst)) {
1065          _vert_stride = BRW_VERTICAL_STRIDE_0;
1066          _width = BRW_WIDTH_1;
1067          _horiz_stride = BRW_HORIZONTAL_STRIDE_0;
1068       } else {
1069          _vert_stride = BRW_VERTICAL_STRIDE_4;
1070          _width = BRW_WIDTH_4;
1071          _horiz_stride = BRW_HORIZONTAL_STRIDE_1;
1072       }
1073    }
1074    is_scalar_region = _vert_stride == BRW_VERTICAL_STRIDE_0 &&
1075                       _width == BRW_WIDTH_1 &&
1076                       _horiz_stride == BRW_HORIZONTAL_STRIDE_0;
1077 
1078    subreg_nr /= brw_reg_type_to_size(type);
1079 
1080    err |= control(file, "negate", m_negate,
1081                   brw_inst_3src_src0_negate(devinfo, inst), NULL);
1082    err |= control(file, "abs", _abs, brw_inst_3src_src0_abs(devinfo, inst), NULL);
1083 
1084    err |= reg(file, _file, reg_nr);
1085    if (err == -1)
1086       return 0;
1087    if (subreg_nr || is_scalar_region)
1088       format(file, ".%d", subreg_nr);
1089    src_align1_region(file, _vert_stride, _width, _horiz_stride);
1090    if (!is_scalar_region && !is_align1)
1091       err |= src_swizzle(file, brw_inst_3src_a16_src0_swizzle(devinfo, inst));
1092    string(file, brw_reg_type_to_letters(type));
1093    return err;
1094 }
1095 
1096 static int
src1_3src(FILE * file,const struct gen_device_info * devinfo,const brw_inst * inst)1097 src1_3src(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst)
1098 {
1099    int err = 0;
1100    unsigned reg_nr, subreg_nr;
1101    enum brw_reg_file _file;
1102    enum brw_reg_type type;
1103    enum brw_vertical_stride _vert_stride;
1104    enum brw_width _width;
1105    enum brw_horizontal_stride _horiz_stride;
1106    bool is_scalar_region;
1107    bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1;
1108 
1109    if (is_align1) {
1110       if (brw_inst_3src_a1_src1_reg_file(devinfo, inst) ==
1111           BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE) {
1112          _file = BRW_GENERAL_REGISTER_FILE;
1113       } else {
1114          _file = BRW_ARCHITECTURE_REGISTER_FILE;
1115       }
1116 
1117       reg_nr = brw_inst_3src_src1_reg_nr(devinfo, inst);
1118       subreg_nr = brw_inst_3src_a1_src1_subreg_nr(devinfo, inst);
1119       type = brw_inst_3src_a1_src1_type(devinfo, inst);
1120 
1121       _vert_stride = vstride_from_align1_3src_vstride(
1122                         brw_inst_3src_a1_src1_vstride(devinfo, inst));
1123       _horiz_stride = hstride_from_align1_3src_hstride(
1124                          brw_inst_3src_a1_src1_hstride(devinfo, inst));
1125       _width = implied_width(_vert_stride, _horiz_stride);
1126    } else {
1127       _file = BRW_GENERAL_REGISTER_FILE;
1128       reg_nr = brw_inst_3src_src1_reg_nr(devinfo, inst);
1129       subreg_nr = brw_inst_3src_a16_src1_subreg_nr(devinfo, inst) * 4;
1130       type = brw_inst_3src_a16_src_type(devinfo, inst);
1131 
1132       if (brw_inst_3src_a16_src1_rep_ctrl(devinfo, inst)) {
1133          _vert_stride = BRW_VERTICAL_STRIDE_0;
1134          _width = BRW_WIDTH_1;
1135          _horiz_stride = BRW_HORIZONTAL_STRIDE_0;
1136       } else {
1137          _vert_stride = BRW_VERTICAL_STRIDE_4;
1138          _width = BRW_WIDTH_4;
1139          _horiz_stride = BRW_HORIZONTAL_STRIDE_1;
1140       }
1141    }
1142    is_scalar_region = _vert_stride == BRW_VERTICAL_STRIDE_0 &&
1143                       _width == BRW_WIDTH_1 &&
1144                       _horiz_stride == BRW_HORIZONTAL_STRIDE_0;
1145 
1146    subreg_nr /= brw_reg_type_to_size(type);
1147 
1148    err |= control(file, "negate", m_negate,
1149                   brw_inst_3src_src1_negate(devinfo, inst), NULL);
1150    err |= control(file, "abs", _abs, brw_inst_3src_src1_abs(devinfo, inst), NULL);
1151 
1152    err |= reg(file, _file, reg_nr);
1153    if (err == -1)
1154       return 0;
1155    if (subreg_nr || is_scalar_region)
1156       format(file, ".%d", subreg_nr);
1157    src_align1_region(file, _vert_stride, _width, _horiz_stride);
1158    if (!is_scalar_region && !is_align1)
1159       err |= src_swizzle(file, brw_inst_3src_a16_src1_swizzle(devinfo, inst));
1160    string(file, brw_reg_type_to_letters(type));
1161    return err;
1162 }
1163 
1164 static int
src2_3src(FILE * file,const struct gen_device_info * devinfo,const brw_inst * inst)1165 src2_3src(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst)
1166 {
1167    int err = 0;
1168    unsigned reg_nr, subreg_nr;
1169    enum brw_reg_file _file;
1170    enum brw_reg_type type;
1171    enum brw_vertical_stride _vert_stride;
1172    enum brw_width _width;
1173    enum brw_horizontal_stride _horiz_stride;
1174    bool is_scalar_region;
1175    bool is_align1 = brw_inst_3src_access_mode(devinfo, inst) == BRW_ALIGN_1;
1176 
1177    if (is_align1) {
1178       if (brw_inst_3src_a1_src2_reg_file(devinfo, inst) ==
1179           BRW_ALIGN1_3SRC_GENERAL_REGISTER_FILE) {
1180          _file = BRW_GENERAL_REGISTER_FILE;
1181          reg_nr = brw_inst_3src_src2_reg_nr(devinfo, inst);
1182          subreg_nr = brw_inst_3src_a1_src2_subreg_nr(devinfo, inst);
1183          type = brw_inst_3src_a1_src2_type(devinfo, inst);
1184       } else {
1185          _file = BRW_IMMEDIATE_VALUE;
1186          uint16_t imm_val = brw_inst_3src_a1_src2_imm(devinfo, inst);
1187          enum brw_reg_type type = brw_inst_3src_a1_src2_type(devinfo, inst);
1188 
1189          if (type == BRW_REGISTER_TYPE_W) {
1190             format(file, "%dW", imm_val);
1191          } else if (type == BRW_REGISTER_TYPE_UW) {
1192             format(file, "0x%04xUW", imm_val);
1193          } else if (type == BRW_REGISTER_TYPE_HF) {
1194             format(file, "%-gF", _mesa_half_to_float(imm_val));
1195          }
1196          return 0;
1197       }
1198 
1199       /* FINISHME: No vertical stride on src2. Is using the hstride in place
1200        *           correct? Doesn't seem like it, since there's hstride=1 but
1201        *           no vstride=1.
1202        */
1203       _vert_stride = vstride_from_align1_3src_hstride(
1204                         brw_inst_3src_a1_src2_hstride(devinfo, inst));
1205       _horiz_stride = hstride_from_align1_3src_hstride(
1206                          brw_inst_3src_a1_src2_hstride(devinfo, inst));
1207       _width = implied_width(_vert_stride, _horiz_stride);
1208    } else {
1209       _file = BRW_GENERAL_REGISTER_FILE;
1210       reg_nr = brw_inst_3src_src2_reg_nr(devinfo, inst);
1211       subreg_nr = brw_inst_3src_a16_src2_subreg_nr(devinfo, inst) * 4;
1212       type = brw_inst_3src_a16_src_type(devinfo, inst);
1213 
1214       if (brw_inst_3src_a16_src2_rep_ctrl(devinfo, inst)) {
1215          _vert_stride = BRW_VERTICAL_STRIDE_0;
1216          _width = BRW_WIDTH_1;
1217          _horiz_stride = BRW_HORIZONTAL_STRIDE_0;
1218       } else {
1219          _vert_stride = BRW_VERTICAL_STRIDE_4;
1220          _width = BRW_WIDTH_4;
1221          _horiz_stride = BRW_HORIZONTAL_STRIDE_1;
1222       }
1223    }
1224    is_scalar_region = _vert_stride == BRW_VERTICAL_STRIDE_0 &&
1225                       _width == BRW_WIDTH_1 &&
1226                       _horiz_stride == BRW_HORIZONTAL_STRIDE_0;
1227 
1228    subreg_nr /= brw_reg_type_to_size(type);
1229 
1230    err |= control(file, "negate", m_negate,
1231                   brw_inst_3src_src2_negate(devinfo, inst), NULL);
1232    err |= control(file, "abs", _abs, brw_inst_3src_src2_abs(devinfo, inst), NULL);
1233 
1234    err |= reg(file, _file, reg_nr);
1235    if (err == -1)
1236       return 0;
1237    if (subreg_nr || is_scalar_region)
1238       format(file, ".%d", subreg_nr);
1239    src_align1_region(file, _vert_stride, _width, _horiz_stride);
1240    if (!is_scalar_region && !is_align1)
1241       err |= src_swizzle(file, brw_inst_3src_a16_src2_swizzle(devinfo, inst));
1242    string(file, brw_reg_type_to_letters(type));
1243    return err;
1244 }
1245 
1246 static int
imm(FILE * file,const struct gen_device_info * devinfo,enum brw_reg_type type,const brw_inst * inst)1247 imm(FILE *file, const struct gen_device_info *devinfo, enum brw_reg_type type,
1248     const brw_inst *inst)
1249 {
1250    switch (type) {
1251    case BRW_REGISTER_TYPE_UQ:
1252       format(file, "0x%016lxUQ", brw_inst_imm_uq(devinfo, inst));
1253       break;
1254    case BRW_REGISTER_TYPE_Q:
1255       format(file, "%ldQ", brw_inst_imm_uq(devinfo, inst));
1256       break;
1257    case BRW_REGISTER_TYPE_UD:
1258       format(file, "0x%08xUD", brw_inst_imm_ud(devinfo, inst));
1259       break;
1260    case BRW_REGISTER_TYPE_D:
1261       format(file, "%dD", brw_inst_imm_d(devinfo, inst));
1262       break;
1263    case BRW_REGISTER_TYPE_UW:
1264       format(file, "0x%04xUW", (uint16_t) brw_inst_imm_ud(devinfo, inst));
1265       break;
1266    case BRW_REGISTER_TYPE_W:
1267       format(file, "%dW", (int16_t) brw_inst_imm_d(devinfo, inst));
1268       break;
1269    case BRW_REGISTER_TYPE_UV:
1270       format(file, "0x%08xUV", brw_inst_imm_ud(devinfo, inst));
1271       break;
1272    case BRW_REGISTER_TYPE_VF:
1273       format(file, "[%-gF, %-gF, %-gF, %-gF]VF",
1274              brw_vf_to_float(brw_inst_imm_ud(devinfo, inst)),
1275              brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 8),
1276              brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 16),
1277              brw_vf_to_float(brw_inst_imm_ud(devinfo, inst) >> 24));
1278       break;
1279    case BRW_REGISTER_TYPE_V:
1280       format(file, "0x%08xV", brw_inst_imm_ud(devinfo, inst));
1281       break;
1282    case BRW_REGISTER_TYPE_F:
1283       format(file, "%-gF", brw_inst_imm_f(devinfo, inst));
1284       break;
1285    case BRW_REGISTER_TYPE_DF:
1286       format(file, "%-gDF", brw_inst_imm_df(devinfo, inst));
1287       break;
1288    case BRW_REGISTER_TYPE_HF:
1289       string(file, "Half Float IMM");
1290       break;
1291    case BRW_REGISTER_TYPE_UB:
1292    case BRW_REGISTER_TYPE_B:
1293       format(file, "*** invalid immediate type %d ", type);
1294    }
1295    return 0;
1296 }
1297 
1298 static int
src0(FILE * file,const struct gen_device_info * devinfo,const brw_inst * inst)1299 src0(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst)
1300 {
1301    if (brw_inst_src0_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
1302       return imm(file, devinfo, brw_inst_src0_type(devinfo, inst), inst);
1303    } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
1304       if (brw_inst_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
1305          return src_da1(file,
1306                         devinfo,
1307                         brw_inst_opcode(devinfo, inst),
1308                         brw_inst_src0_type(devinfo, inst),
1309                         brw_inst_src0_reg_file(devinfo, inst),
1310                         brw_inst_src0_vstride(devinfo, inst),
1311                         brw_inst_src0_width(devinfo, inst),
1312                         brw_inst_src0_hstride(devinfo, inst),
1313                         brw_inst_src0_da_reg_nr(devinfo, inst),
1314                         brw_inst_src0_da1_subreg_nr(devinfo, inst),
1315                         brw_inst_src0_abs(devinfo, inst),
1316                         brw_inst_src0_negate(devinfo, inst));
1317       } else {
1318          return src_ia1(file,
1319                         devinfo,
1320                         brw_inst_opcode(devinfo, inst),
1321                         brw_inst_src0_type(devinfo, inst),
1322                         brw_inst_src0_reg_file(devinfo, inst),
1323                         brw_inst_src0_ia1_addr_imm(devinfo, inst),
1324                         brw_inst_src0_ia_subreg_nr(devinfo, inst),
1325                         brw_inst_src0_negate(devinfo, inst),
1326                         brw_inst_src0_abs(devinfo, inst),
1327                         brw_inst_src0_hstride(devinfo, inst),
1328                         brw_inst_src0_width(devinfo, inst),
1329                         brw_inst_src0_vstride(devinfo, inst));
1330       }
1331    } else {
1332       if (brw_inst_src0_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
1333          return src_da16(file,
1334                          devinfo,
1335                          brw_inst_opcode(devinfo, inst),
1336                          brw_inst_src0_type(devinfo, inst),
1337                          brw_inst_src0_reg_file(devinfo, inst),
1338                          brw_inst_src0_vstride(devinfo, inst),
1339                          brw_inst_src0_da_reg_nr(devinfo, inst),
1340                          brw_inst_src0_da16_subreg_nr(devinfo, inst),
1341                          brw_inst_src0_abs(devinfo, inst),
1342                          brw_inst_src0_negate(devinfo, inst),
1343                          brw_inst_src0_da16_swiz_x(devinfo, inst),
1344                          brw_inst_src0_da16_swiz_y(devinfo, inst),
1345                          brw_inst_src0_da16_swiz_z(devinfo, inst),
1346                          brw_inst_src0_da16_swiz_w(devinfo, inst));
1347       } else {
1348          string(file, "Indirect align16 address mode not supported");
1349          return 1;
1350       }
1351    }
1352 }
1353 
1354 static int
src1(FILE * file,const struct gen_device_info * devinfo,const brw_inst * inst)1355 src1(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst)
1356 {
1357    if (brw_inst_src1_reg_file(devinfo, inst) == BRW_IMMEDIATE_VALUE) {
1358       return imm(file, devinfo, brw_inst_src1_type(devinfo, inst), inst);
1359    } else if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
1360       if (brw_inst_src1_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
1361          return src_da1(file,
1362                         devinfo,
1363                         brw_inst_opcode(devinfo, inst),
1364                         brw_inst_src1_type(devinfo, inst),
1365                         brw_inst_src1_reg_file(devinfo, inst),
1366                         brw_inst_src1_vstride(devinfo, inst),
1367                         brw_inst_src1_width(devinfo, inst),
1368                         brw_inst_src1_hstride(devinfo, inst),
1369                         brw_inst_src1_da_reg_nr(devinfo, inst),
1370                         brw_inst_src1_da1_subreg_nr(devinfo, inst),
1371                         brw_inst_src1_abs(devinfo, inst),
1372                         brw_inst_src1_negate(devinfo, inst));
1373       } else {
1374          return src_ia1(file,
1375                         devinfo,
1376                         brw_inst_opcode(devinfo, inst),
1377                         brw_inst_src1_type(devinfo, inst),
1378                         brw_inst_src1_reg_file(devinfo, inst),
1379                         brw_inst_src1_ia1_addr_imm(devinfo, inst),
1380                         brw_inst_src1_ia_subreg_nr(devinfo, inst),
1381                         brw_inst_src1_negate(devinfo, inst),
1382                         brw_inst_src1_abs(devinfo, inst),
1383                         brw_inst_src1_hstride(devinfo, inst),
1384                         brw_inst_src1_width(devinfo, inst),
1385                         brw_inst_src1_vstride(devinfo, inst));
1386       }
1387    } else {
1388       if (brw_inst_src1_address_mode(devinfo, inst) == BRW_ADDRESS_DIRECT) {
1389          return src_da16(file,
1390                          devinfo,
1391                          brw_inst_opcode(devinfo, inst),
1392                          brw_inst_src1_type(devinfo, inst),
1393                          brw_inst_src1_reg_file(devinfo, inst),
1394                          brw_inst_src1_vstride(devinfo, inst),
1395                          brw_inst_src1_da_reg_nr(devinfo, inst),
1396                          brw_inst_src1_da16_subreg_nr(devinfo, inst),
1397                          brw_inst_src1_abs(devinfo, inst),
1398                          brw_inst_src1_negate(devinfo, inst),
1399                          brw_inst_src1_da16_swiz_x(devinfo, inst),
1400                          brw_inst_src1_da16_swiz_y(devinfo, inst),
1401                          brw_inst_src1_da16_swiz_z(devinfo, inst),
1402                          brw_inst_src1_da16_swiz_w(devinfo, inst));
1403       } else {
1404          string(file, "Indirect align16 address mode not supported");
1405          return 1;
1406       }
1407    }
1408 }
1409 
1410 static int
qtr_ctrl(FILE * file,const struct gen_device_info * devinfo,const brw_inst * inst)1411 qtr_ctrl(FILE *file, const struct gen_device_info *devinfo, const brw_inst *inst)
1412 {
1413    int qtr_ctl = brw_inst_qtr_control(devinfo, inst);
1414    int exec_size = 1 << brw_inst_exec_size(devinfo, inst);
1415    const unsigned nib_ctl = devinfo->gen < 7 ? 0 :
1416                             brw_inst_nib_control(devinfo, inst);
1417 
1418    if (exec_size < 8 || nib_ctl) {
1419       format(file, " %dN", qtr_ctl * 2 + nib_ctl + 1);
1420    } else if (exec_size == 8) {
1421       switch (qtr_ctl) {
1422       case 0:
1423          string(file, " 1Q");
1424          break;
1425       case 1:
1426          string(file, " 2Q");
1427          break;
1428       case 2:
1429          string(file, " 3Q");
1430          break;
1431       case 3:
1432          string(file, " 4Q");
1433          break;
1434       }
1435    } else if (exec_size == 16) {
1436       if (qtr_ctl < 2)
1437          string(file, " 1H");
1438       else
1439          string(file, " 2H");
1440    }
1441    return 0;
1442 }
1443 
1444 #ifdef DEBUG
1445 static __attribute__((__unused__)) int
brw_disassemble_imm(const struct gen_device_info * devinfo,uint32_t dw3,uint32_t dw2,uint32_t dw1,uint32_t dw0)1446 brw_disassemble_imm(const struct gen_device_info *devinfo,
1447                     uint32_t dw3, uint32_t dw2, uint32_t dw1, uint32_t dw0)
1448 {
1449    brw_inst inst;
1450    inst.data[0] = (((uint64_t) dw1) << 32) | ((uint64_t) dw0);
1451    inst.data[1] = (((uint64_t) dw3) << 32) | ((uint64_t) dw2);
1452    return brw_disassemble_inst(stderr, devinfo, &inst, false);
1453 }
1454 #endif
1455 
1456 int
brw_disassemble_inst(FILE * file,const struct gen_device_info * devinfo,const brw_inst * inst,bool is_compacted)1457 brw_disassemble_inst(FILE *file, const struct gen_device_info *devinfo,
1458                      const brw_inst *inst, bool is_compacted)
1459 {
1460    int err = 0;
1461    int space = 0;
1462 
1463    const enum opcode opcode = brw_inst_opcode(devinfo, inst);
1464    const struct opcode_desc *desc = brw_opcode_desc(devinfo, opcode);
1465 
1466    if (brw_inst_pred_control(devinfo, inst)) {
1467       string(file, "(");
1468       err |= control(file, "predicate inverse", pred_inv,
1469                      brw_inst_pred_inv(devinfo, inst), NULL);
1470       format(file, "f%"PRIu64, devinfo->gen >= 7 ? brw_inst_flag_reg_nr(devinfo, inst) : 0);
1471       if (brw_inst_flag_subreg_nr(devinfo, inst))
1472          format(file, ".%"PRIu64, brw_inst_flag_subreg_nr(devinfo, inst));
1473       if (brw_inst_access_mode(devinfo, inst) == BRW_ALIGN_1) {
1474          err |= control(file, "predicate control align1", pred_ctrl_align1,
1475                         brw_inst_pred_control(devinfo, inst), NULL);
1476       } else {
1477          err |= control(file, "predicate control align16", pred_ctrl_align16,
1478                         brw_inst_pred_control(devinfo, inst), NULL);
1479       }
1480       string(file, ") ");
1481    }
1482 
1483    err |= print_opcode(file, devinfo, opcode);
1484    err |= control(file, "saturate", saturate, brw_inst_saturate(devinfo, inst),
1485                   NULL);
1486 
1487    err |= control(file, "debug control", debug_ctrl,
1488                   brw_inst_debug_control(devinfo, inst), NULL);
1489 
1490    if (opcode == BRW_OPCODE_MATH) {
1491       string(file, " ");
1492       err |= control(file, "function", math_function,
1493                      brw_inst_math_function(devinfo, inst), NULL);
1494    } else if (opcode != BRW_OPCODE_SEND && opcode != BRW_OPCODE_SENDC) {
1495       err |= control(file, "conditional modifier", conditional_modifier,
1496                      brw_inst_cond_modifier(devinfo, inst), NULL);
1497 
1498       /* If we're using the conditional modifier, print which flags reg is
1499        * used for it.  Note that on gen6+, the embedded-condition SEL and
1500        * control flow doesn't update flags.
1501        */
1502       if (brw_inst_cond_modifier(devinfo, inst) &&
1503           (devinfo->gen < 6 || (opcode != BRW_OPCODE_SEL &&
1504                                 opcode != BRW_OPCODE_IF &&
1505                                 opcode != BRW_OPCODE_WHILE))) {
1506          format(file, ".f%"PRIu64,
1507                 devinfo->gen >= 7 ? brw_inst_flag_reg_nr(devinfo, inst) : 0);
1508          if (brw_inst_flag_subreg_nr(devinfo, inst))
1509             format(file, ".%"PRIu64, brw_inst_flag_subreg_nr(devinfo, inst));
1510       }
1511    }
1512 
1513    if (opcode != BRW_OPCODE_NOP && opcode != BRW_OPCODE_NENOP) {
1514       string(file, "(");
1515       err |= control(file, "execution size", exec_size,
1516                      brw_inst_exec_size(devinfo, inst), NULL);
1517       string(file, ")");
1518    }
1519 
1520    if (opcode == BRW_OPCODE_SEND && devinfo->gen < 6)
1521       format(file, " %"PRIu64, brw_inst_base_mrf(devinfo, inst));
1522 
1523    if (has_uip(devinfo, opcode)) {
1524       /* Instructions that have UIP also have JIP. */
1525       pad(file, 16);
1526       format(file, "JIP: %d", brw_inst_jip(devinfo, inst));
1527       pad(file, 32);
1528       format(file, "UIP: %d", brw_inst_uip(devinfo, inst));
1529    } else if (has_jip(devinfo, opcode)) {
1530       pad(file, 16);
1531       if (devinfo->gen >= 7) {
1532          format(file, "JIP: %d", brw_inst_jip(devinfo, inst));
1533       } else {
1534          format(file, "JIP: %d", brw_inst_gen6_jump_count(devinfo, inst));
1535       }
1536    } else if (devinfo->gen < 6 && (opcode == BRW_OPCODE_BREAK ||
1537                                    opcode == BRW_OPCODE_CONTINUE ||
1538                                    opcode == BRW_OPCODE_ELSE)) {
1539       pad(file, 16);
1540       format(file, "Jump: %d", brw_inst_gen4_jump_count(devinfo, inst));
1541       pad(file, 32);
1542       format(file, "Pop: %"PRIu64, brw_inst_gen4_pop_count(devinfo, inst));
1543    } else if (devinfo->gen < 6 && (opcode == BRW_OPCODE_IF ||
1544                                    opcode == BRW_OPCODE_IFF ||
1545                                    opcode == BRW_OPCODE_HALT)) {
1546       pad(file, 16);
1547       format(file, "Jump: %d", brw_inst_gen4_jump_count(devinfo, inst));
1548    } else if (devinfo->gen < 6 && opcode == BRW_OPCODE_ENDIF) {
1549       pad(file, 16);
1550       format(file, "Pop: %"PRIu64, brw_inst_gen4_pop_count(devinfo, inst));
1551    } else if (opcode == BRW_OPCODE_JMPI) {
1552       pad(file, 16);
1553       err |= src1(file, devinfo, inst);
1554    } else if (desc && desc->nsrc == 3) {
1555       pad(file, 16);
1556       err |= dest_3src(file, devinfo, inst);
1557 
1558       pad(file, 32);
1559       err |= src0_3src(file, devinfo, inst);
1560 
1561       pad(file, 48);
1562       err |= src1_3src(file, devinfo, inst);
1563 
1564       pad(file, 64);
1565       err |= src2_3src(file, devinfo, inst);
1566    } else if (desc) {
1567       if (desc->ndst > 0) {
1568          pad(file, 16);
1569          err |= dest(file, devinfo, inst);
1570       }
1571 
1572       if (desc->nsrc > 0) {
1573          pad(file, 32);
1574          err |= src0(file, devinfo, inst);
1575       }
1576 
1577       if (desc->nsrc > 1) {
1578          pad(file, 48);
1579          err |= src1(file, devinfo, inst);
1580       }
1581    }
1582 
1583    if (opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC) {
1584       enum brw_message_target sfid = brw_inst_sfid(devinfo, inst);
1585 
1586       if (brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE) {
1587          /* show the indirect descriptor source */
1588          pad(file, 48);
1589          err |= src1(file, devinfo, inst);
1590       }
1591 
1592       newline(file);
1593       pad(file, 16);
1594       space = 0;
1595 
1596       fprintf(file, "            ");
1597       err |= control(file, "SFID", devinfo->gen >= 6 ? gen6_sfid : gen4_sfid,
1598                      sfid, &space);
1599 
1600 
1601       if (brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE) {
1602          format(file, " indirect");
1603       } else {
1604          switch (sfid) {
1605          case BRW_SFID_MATH:
1606             err |= control(file, "math function", math_function,
1607                            brw_inst_math_msg_function(devinfo, inst), &space);
1608             err |= control(file, "math saturate", math_saturate,
1609                            brw_inst_math_msg_saturate(devinfo, inst), &space);
1610             err |= control(file, "math signed", math_signed,
1611                            brw_inst_math_msg_signed_int(devinfo, inst), &space);
1612             err |= control(file, "math scalar", math_scalar,
1613                            brw_inst_math_msg_data_type(devinfo, inst), &space);
1614             err |= control(file, "math precision", math_precision,
1615                            brw_inst_math_msg_precision(devinfo, inst), &space);
1616             break;
1617          case BRW_SFID_SAMPLER:
1618             if (devinfo->gen >= 5) {
1619                err |= control(file, "sampler message", gen5_sampler_msg_type,
1620                               brw_inst_sampler_msg_type(devinfo, inst), &space);
1621                err |= control(file, "sampler simd mode", gen5_sampler_simd_mode,
1622                               brw_inst_sampler_simd_mode(devinfo, inst), &space);
1623                format(file, " Surface = %"PRIu64" Sampler = %"PRIu64,
1624                       brw_inst_binding_table_index(devinfo, inst),
1625                       brw_inst_sampler(devinfo, inst));
1626             } else {
1627                format(file, " (%"PRIu64", %"PRIu64", %"PRIu64", ",
1628                       brw_inst_binding_table_index(devinfo, inst),
1629                       brw_inst_sampler(devinfo, inst),
1630                       brw_inst_sampler_msg_type(devinfo, inst));
1631                if (!devinfo->is_g4x) {
1632                   err |= control(file, "sampler target format",
1633                                  sampler_target_format,
1634                                  brw_inst_sampler_return_format(devinfo, inst), NULL);
1635                }
1636                string(file, ")");
1637             }
1638             break;
1639          case GEN6_SFID_DATAPORT_SAMPLER_CACHE:
1640          case GEN6_SFID_DATAPORT_CONSTANT_CACHE:
1641             /* aka BRW_SFID_DATAPORT_READ on Gen4-5 */
1642             if (devinfo->gen >= 6) {
1643                format(file, " (%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64")",
1644                       brw_inst_binding_table_index(devinfo, inst),
1645                       brw_inst_dp_msg_control(devinfo, inst),
1646                       brw_inst_dp_msg_type(devinfo, inst),
1647                       devinfo->gen >= 7 ? 0 : brw_inst_dp_write_commit(devinfo, inst));
1648             } else {
1649                bool is_965 = devinfo->gen == 4 && !devinfo->is_g4x;
1650                err |= control(file, "DP read message type",
1651                               is_965 ? gen4_dp_read_port_msg_type :
1652                                        g45_dp_read_port_msg_type,
1653                               brw_inst_dp_read_msg_type(devinfo, inst),
1654                               &space);
1655 
1656                format(file, " MsgCtrl = 0x%"PRIx64,
1657                       brw_inst_dp_read_msg_control(devinfo, inst));
1658 
1659                format(file, " Surface = %"PRIu64, brw_inst_binding_table_index(devinfo, inst));
1660             }
1661             break;
1662 
1663          case GEN6_SFID_DATAPORT_RENDER_CACHE: {
1664             /* aka BRW_SFID_DATAPORT_WRITE on Gen4-5 */
1665             unsigned msg_type = brw_inst_dp_write_msg_type(devinfo, inst);
1666 
1667             err |= control(file, "DP rc message type",
1668                            dp_rc_msg_type(devinfo), msg_type, &space);
1669 
1670             bool is_rt_write = msg_type ==
1671                (devinfo->gen >= 6 ? GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE
1672                                   : BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE);
1673 
1674             if (is_rt_write) {
1675                err |= control(file, "RT message type", m_rt_write_subtype,
1676                               brw_inst_rt_message_type(devinfo, inst), &space);
1677                if (devinfo->gen >= 6 && brw_inst_rt_slot_group(devinfo, inst))
1678                   string(file, " Hi");
1679                if (brw_inst_rt_last(devinfo, inst))
1680                   string(file, " LastRT");
1681                if (devinfo->gen < 7 && brw_inst_dp_write_commit(devinfo, inst))
1682                   string(file, " WriteCommit");
1683             } else {
1684                format(file, " MsgCtrl = 0x%"PRIx64,
1685                       brw_inst_dp_write_msg_control(devinfo, inst));
1686             }
1687 
1688             format(file, " Surface = %"PRIu64, brw_inst_binding_table_index(devinfo, inst));
1689             break;
1690          }
1691 
1692          case BRW_SFID_URB: {
1693             unsigned opcode = brw_inst_urb_opcode(devinfo, inst);
1694 
1695             format(file, " %"PRIu64, brw_inst_urb_global_offset(devinfo, inst));
1696 
1697             space = 1;
1698 
1699             err |= control(file, "urb opcode",
1700                            devinfo->gen >= 7 ? gen7_urb_opcode
1701                                              : gen5_urb_opcode,
1702                            opcode, &space);
1703 
1704             if (devinfo->gen >= 7 &&
1705                 brw_inst_urb_per_slot_offset(devinfo, inst)) {
1706                string(file, " per-slot");
1707             }
1708 
1709             if (opcode == GEN8_URB_OPCODE_SIMD8_WRITE ||
1710                 opcode == GEN8_URB_OPCODE_SIMD8_READ) {
1711                if (brw_inst_urb_channel_mask_present(devinfo, inst))
1712                   string(file, " masked");
1713             } else {
1714                err |= control(file, "urb swizzle", urb_swizzle,
1715                               brw_inst_urb_swizzle_control(devinfo, inst),
1716                               &space);
1717             }
1718 
1719             if (devinfo->gen < 7) {
1720                err |= control(file, "urb allocate", urb_allocate,
1721                               brw_inst_urb_allocate(devinfo, inst), &space);
1722                err |= control(file, "urb used", urb_used,
1723                               brw_inst_urb_used(devinfo, inst), &space);
1724             }
1725             if (devinfo->gen < 8) {
1726                err |= control(file, "urb complete", urb_complete,
1727                               brw_inst_urb_complete(devinfo, inst), &space);
1728             }
1729             break;
1730          }
1731          case BRW_SFID_THREAD_SPAWNER:
1732             break;
1733 
1734          case BRW_SFID_MESSAGE_GATEWAY:
1735             format(file, " (%s)",
1736                    gen7_gateway_subfuncid[brw_inst_gateway_subfuncid(devinfo, inst)]);
1737             break;
1738 
1739          case GEN7_SFID_DATAPORT_DATA_CACHE:
1740             if (devinfo->gen >= 7) {
1741                format(file, " (");
1742 
1743                err |= control(file, "DP DC0 message type",
1744                               dp_dc0_msg_type_gen7,
1745                               brw_inst_dp_msg_type(devinfo, inst), &space);
1746 
1747                format(file, ", %"PRIu64", ", brw_inst_binding_table_index(devinfo, inst));
1748 
1749                switch (brw_inst_dp_msg_type(devinfo, inst)) {
1750                case GEN7_DATAPORT_DC_UNTYPED_ATOMIC_OP:
1751                   control(file, "atomic op", aop,
1752                           brw_inst_imm_ud(devinfo, inst) >> 8 & 0xf, &space);
1753                   break;
1754                default:
1755                   format(file, "%"PRIu64, brw_inst_dp_msg_control(devinfo, inst));
1756                }
1757                format(file, ")");
1758                break;
1759             }
1760             /* FALLTHROUGH */
1761 
1762          case HSW_SFID_DATAPORT_DATA_CACHE_1: {
1763             if (devinfo->gen >= 7) {
1764                format(file, " (");
1765 
1766                unsigned msg_ctrl = brw_inst_dp_msg_control(devinfo, inst);
1767 
1768                err |= control(file, "DP DC1 message type",
1769                               dp_dc1_msg_type_hsw,
1770                               brw_inst_dp_msg_type(devinfo, inst), &space);
1771 
1772                format(file, ", Surface = %"PRIu64", ",
1773                       brw_inst_binding_table_index(devinfo, inst));
1774 
1775                switch (brw_inst_dp_msg_type(devinfo, inst)) {
1776                case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP:
1777                case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP:
1778                case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP:
1779                   format(file, "SIMD%d,", (msg_ctrl & (1 << 4)) ? 8 : 16);
1780                   /* fallthrough */
1781                case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2:
1782                case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2:
1783                case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2:
1784                   control(file, "atomic op", aop, msg_ctrl & 0xf, &space);
1785                   break;
1786                case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ:
1787                case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE:
1788                case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ:
1789                case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE: {
1790                   static const char *simd_modes[] = { "4x2", "16", "8" };
1791                   format(file, "SIMD%s, Mask = 0x%x",
1792                          simd_modes[msg_ctrl >> 4], msg_ctrl & 0xf);
1793                   break;
1794                }
1795                default:
1796                   format(file, "0x%x", msg_ctrl);
1797                }
1798                format(file, ")");
1799                break;
1800             }
1801             /* FALLTHROUGH */
1802          }
1803 
1804          case GEN7_SFID_PIXEL_INTERPOLATOR:
1805             if (devinfo->gen >= 7) {
1806                format(file, " (%s, %s, 0x%02"PRIx64")",
1807                       brw_inst_pi_nopersp(devinfo, inst) ? "linear" : "persp",
1808                       pixel_interpolator_msg_types[brw_inst_pi_message_type(devinfo, inst)],
1809                       brw_inst_pi_message_data(devinfo, inst));
1810                break;
1811             }
1812             /* FALLTHROUGH */
1813 
1814          default:
1815             format(file, "unsupported shared function ID %d", sfid);
1816             break;
1817          }
1818 
1819          if (space)
1820             string(file, " ");
1821          format(file, "mlen %"PRIu64, brw_inst_mlen(devinfo, inst));
1822          format(file, " rlen %"PRIu64, brw_inst_rlen(devinfo, inst));
1823       }
1824    }
1825    pad(file, 64);
1826    if (opcode != BRW_OPCODE_NOP && opcode != BRW_OPCODE_NENOP) {
1827       string(file, "{");
1828       space = 1;
1829       err |= control(file, "access mode", access_mode,
1830                      brw_inst_access_mode(devinfo, inst), &space);
1831       if (devinfo->gen >= 6) {
1832          err |= control(file, "write enable control", wectrl,
1833                         brw_inst_mask_control(devinfo, inst), &space);
1834       } else {
1835          err |= control(file, "mask control", mask_ctrl,
1836                         brw_inst_mask_control(devinfo, inst), &space);
1837       }
1838       err |= control(file, "dependency control", dep_ctrl,
1839                      ((brw_inst_no_dd_check(devinfo, inst) << 1) |
1840                       brw_inst_no_dd_clear(devinfo, inst)), &space);
1841 
1842       if (devinfo->gen >= 6)
1843          err |= qtr_ctrl(file, devinfo, inst);
1844       else {
1845          if (brw_inst_qtr_control(devinfo, inst) == BRW_COMPRESSION_COMPRESSED &&
1846              desc && desc->ndst > 0 &&
1847              brw_inst_dst_reg_file(devinfo, inst) == BRW_MESSAGE_REGISTER_FILE &&
1848              brw_inst_dst_da_reg_nr(devinfo, inst) & BRW_MRF_COMPR4) {
1849             format(file, " compr4");
1850          } else {
1851             err |= control(file, "compression control", compr_ctrl,
1852                            brw_inst_qtr_control(devinfo, inst), &space);
1853          }
1854       }
1855 
1856       err |= control(file, "compaction", cmpt_ctrl, is_compacted, &space);
1857       err |= control(file, "thread control", thread_ctrl,
1858                      brw_inst_thread_control(devinfo, inst), &space);
1859       if (has_branch_ctrl(devinfo, opcode)) {
1860          err |= control(file, "branch ctrl", branch_ctrl,
1861                         brw_inst_branch_control(devinfo, inst), &space);
1862       } else if (devinfo->gen >= 6) {
1863          err |= control(file, "acc write control", accwr,
1864                         brw_inst_acc_wr_control(devinfo, inst), &space);
1865       }
1866       if (opcode == BRW_OPCODE_SEND || opcode == BRW_OPCODE_SENDC)
1867          err |= control(file, "end of thread", end_of_thread,
1868                         brw_inst_eot(devinfo, inst), &space);
1869       if (space)
1870          string(file, " ");
1871       string(file, "}");
1872    }
1873    string(file, ";");
1874    newline(file);
1875    return err;
1876 }
1877