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