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 <stdlib.h>
25 #include <string.h>
26 #include <getopt.h>
27 #include <unistd.h>
28 #include <stdarg.h>
29 
30 #include "main/mtypes.h"
31 
32 #include "brw_context.h"
33 #include "brw_defines.h"
34 
35 struct {
36     char    *name;
37     int	    nsrc;
38     int	    ndst;
39 } opcode[128] = {
40     [BRW_OPCODE_MOV] = { .name = "mov", .nsrc = 1, .ndst = 1 },
41     [BRW_OPCODE_FRC] = { .name = "frc", .nsrc = 1, .ndst = 1 },
42     [BRW_OPCODE_RNDU] = { .name = "rndu", .nsrc = 1, .ndst = 1 },
43     [BRW_OPCODE_RNDD] = { .name = "rndd", .nsrc = 1, .ndst = 1 },
44     [BRW_OPCODE_RNDE] = { .name = "rnde", .nsrc = 1, .ndst = 1 },
45     [BRW_OPCODE_RNDZ] = { .name = "rndz", .nsrc = 1, .ndst = 1 },
46     [BRW_OPCODE_NOT] = { .name = "not", .nsrc = 1, .ndst = 1 },
47     [BRW_OPCODE_LZD] = { .name = "lzd", .nsrc = 1, .ndst = 1 },
48 
49     [BRW_OPCODE_MUL] = { .name = "mul", .nsrc = 2, .ndst = 1 },
50     [BRW_OPCODE_MAC] = { .name = "mac", .nsrc = 2, .ndst = 1 },
51     [BRW_OPCODE_MACH] = { .name = "mach", .nsrc = 2, .ndst = 1 },
52     [BRW_OPCODE_LINE] = { .name = "line", .nsrc = 2, .ndst = 1 },
53     [BRW_OPCODE_PLN] = { .name = "pln", .nsrc = 2, .ndst = 1 },
54     [BRW_OPCODE_MAD] = { .name = "mad", .nsrc = 3, .ndst = 1 },
55     [BRW_OPCODE_SAD2] = { .name = "sad2", .nsrc = 2, .ndst = 1 },
56     [BRW_OPCODE_SADA2] = { .name = "sada2", .nsrc = 2, .ndst = 1 },
57     [BRW_OPCODE_DP4] = { .name = "dp4", .nsrc = 2, .ndst = 1 },
58     [BRW_OPCODE_DPH] = { .name = "dph", .nsrc = 2, .ndst = 1 },
59     [BRW_OPCODE_DP3] = { .name = "dp3", .nsrc = 2, .ndst = 1 },
60     [BRW_OPCODE_DP2] = { .name = "dp2", .nsrc = 2, .ndst = 1 },
61     [BRW_OPCODE_MATH] = { .name = "math", .nsrc = 2, .ndst = 1 },
62 
63     [BRW_OPCODE_AVG] = { .name = "avg", .nsrc = 2, .ndst = 1 },
64     [BRW_OPCODE_ADD] = { .name = "add", .nsrc = 2, .ndst = 1 },
65     [BRW_OPCODE_SEL] = { .name = "sel", .nsrc = 2, .ndst = 1 },
66     [BRW_OPCODE_AND] = { .name = "and", .nsrc = 2, .ndst = 1 },
67     [BRW_OPCODE_OR] = { .name = "or", .nsrc = 2, .ndst = 1 },
68     [BRW_OPCODE_XOR] = { .name = "xor", .nsrc = 2, .ndst = 1 },
69     [BRW_OPCODE_SHR] = { .name = "shr", .nsrc = 2, .ndst = 1 },
70     [BRW_OPCODE_SHL] = { .name = "shl", .nsrc = 2, .ndst = 1 },
71     [BRW_OPCODE_ASR] = { .name = "asr", .nsrc = 2, .ndst = 1 },
72     [BRW_OPCODE_CMP] = { .name = "cmp", .nsrc = 2, .ndst = 1 },
73     [BRW_OPCODE_CMPN] = { .name = "cmpn", .nsrc = 2, .ndst = 1 },
74 
75     [BRW_OPCODE_SEND] = { .name = "send", .nsrc = 1, .ndst = 1 },
76     [BRW_OPCODE_SENDC] = { .name = "sendc", .nsrc = 1, .ndst = 1 },
77     [BRW_OPCODE_NOP] = { .name = "nop", .nsrc = 0, .ndst = 0 },
78     [BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 0, .ndst = 0 },
79     [BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 },
80     [BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 2, .ndst = 1 },
81     [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 2, .ndst = 0 },
82     [BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 },
83     [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 2, .ndst = 0 },
84     [BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 },
85     [BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 },
86     [BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 },
87     [BRW_OPCODE_PUSH] = { .name = "push", .nsrc = 1, .ndst = 1 },
88     [BRW_OPCODE_MRESTORE] = { .name = "mrest", .nsrc = 1, .ndst = 1 },
89     [BRW_OPCODE_POP] = { .name = "pop", .nsrc = 2, .ndst = 0 },
90     [BRW_OPCODE_WAIT] = { .name = "wait", .nsrc = 1, .ndst = 0 },
91     [BRW_OPCODE_DO] = { .name = "do", .nsrc = 0, .ndst = 0 },
92     [BRW_OPCODE_ENDIF] = { .name = "endif", .nsrc = 2, .ndst = 0 },
93 };
94 
95 char *conditional_modifier[16] = {
96     [BRW_CONDITIONAL_NONE] = "",
97     [BRW_CONDITIONAL_Z] = ".e",
98     [BRW_CONDITIONAL_NZ] = ".ne",
99     [BRW_CONDITIONAL_G] = ".g",
100     [BRW_CONDITIONAL_GE] = ".ge",
101     [BRW_CONDITIONAL_L] = ".l",
102     [BRW_CONDITIONAL_LE] = ".le",
103     [BRW_CONDITIONAL_R] = ".r",
104     [BRW_CONDITIONAL_O] = ".o",
105     [BRW_CONDITIONAL_U] = ".u",
106 };
107 
108 char *negate[2] = {
109     [0] = "",
110     [1] = "-",
111 };
112 
113 char *_abs[2] = {
114     [0] = "",
115     [1] = "(abs)",
116 };
117 
118 char *vert_stride[16] = {
119     [0] = "0",
120     [1] = "1",
121     [2] = "2",
122     [3] = "4",
123     [4] = "8",
124     [5] = "16",
125     [6] = "32",
126     [15] = "VxH",
127 };
128 
129 char *width[8] = {
130     [0] = "1",
131     [1] = "2",
132     [2] = "4",
133     [3] = "8",
134     [4] = "16",
135 };
136 
137 char *horiz_stride[4] = {
138     [0] = "0",
139     [1] = "1",
140     [2] = "2",
141     [3] = "4"
142 };
143 
144 char *chan_sel[4] = {
145     [0] = "x",
146     [1] = "y",
147     [2] = "z",
148     [3] = "w",
149 };
150 
151 char *dest_condmod[16] = {
152 };
153 
154 char *debug_ctrl[2] = {
155     [0] = "",
156     [1] = ".breakpoint"
157 };
158 
159 char *saturate[2] = {
160     [0] = "",
161     [1] = ".sat"
162 };
163 
164 char *accwr[2] = {
165     [0] = "",
166     [1] = "AccWrEnable"
167 };
168 
169 char *wectrl[2] = {
170     [0] = "WE_normal",
171     [1] = "WE_all"
172 };
173 
174 char *exec_size[8] = {
175     [0] = "1",
176     [1] = "2",
177     [2] = "4",
178     [3] = "8",
179     [4] = "16",
180     [5] = "32"
181 };
182 
183 char *pred_inv[2] = {
184     [0] = "+",
185     [1] = "-"
186 };
187 
188 char *pred_ctrl_align16[16] = {
189     [1] = "",
190     [2] = ".x",
191     [3] = ".y",
192     [4] = ".z",
193     [5] = ".w",
194     [6] = ".any4h",
195     [7] = ".all4h",
196 };
197 
198 char *pred_ctrl_align1[16] = {
199     [1] = "",
200     [2] = ".anyv",
201     [3] = ".allv",
202     [4] = ".any2h",
203     [5] = ".all2h",
204     [6] = ".any4h",
205     [7] = ".all4h",
206     [8] = ".any8h",
207     [9] = ".all8h",
208     [10] = ".any16h",
209     [11] = ".all16h",
210 };
211 
212 char *thread_ctrl[4] = {
213     [0] = "",
214     [2] = "switch"
215 };
216 
217 char *compr_ctrl[4] = {
218     [0] = "",
219     [1] = "sechalf",
220     [2] = "compr",
221     [3] = "compr4",
222 };
223 
224 char *dep_ctrl[4] = {
225     [0] = "",
226     [1] = "NoDDClr",
227     [2] = "NoDDChk",
228     [3] = "NoDDClr,NoDDChk",
229 };
230 
231 char *mask_ctrl[4] = {
232     [0] = "",
233     [1] = "nomask",
234 };
235 
236 char *access_mode[2] = {
237     [0] = "align1",
238     [1] = "align16",
239 };
240 
241 char *reg_encoding[8] = {
242     [0] = "UD",
243     [1] = "D",
244     [2] = "UW",
245     [3] = "W",
246     [4] = "UB",
247     [5] = "B",
248     [7] = "F"
249 };
250 
251 int reg_type_size[8] = {
252     [0] = 4,
253     [1] = 4,
254     [2] = 2,
255     [3] = 2,
256     [4] = 1,
257     [5] = 1,
258     [7] = 4
259 };
260 
261 char *imm_encoding[8] = {
262     [0] = "UD",
263     [1] = "D",
264     [2] = "UW",
265     [3] = "W",
266     [5] = "VF",
267     [6] = "V",
268     [7] = "F"
269 };
270 
271 char *reg_file[4] = {
272     [0] = "A",
273     [1] = "g",
274     [2] = "m",
275     [3] = "imm",
276 };
277 
278 char *writemask[16] = {
279     [0x0] = ".",
280     [0x1] = ".x",
281     [0x2] = ".y",
282     [0x3] = ".xy",
283     [0x4] = ".z",
284     [0x5] = ".xz",
285     [0x6] = ".yz",
286     [0x7] = ".xyz",
287     [0x8] = ".w",
288     [0x9] = ".xw",
289     [0xa] = ".yw",
290     [0xb] = ".xyw",
291     [0xc] = ".zw",
292     [0xd] = ".xzw",
293     [0xe] = ".yzw",
294     [0xf] = "",
295 };
296 
297 char *end_of_thread[2] = {
298     [0] = "",
299     [1] = "EOT"
300 };
301 
302 char *target_function[16] = {
303     [BRW_SFID_NULL] = "null",
304     [BRW_SFID_MATH] = "math",
305     [BRW_SFID_SAMPLER] = "sampler",
306     [BRW_SFID_MESSAGE_GATEWAY] = "gateway",
307     [BRW_SFID_DATAPORT_READ] = "read",
308     [BRW_SFID_DATAPORT_WRITE] = "write",
309     [BRW_SFID_URB] = "urb",
310     [BRW_SFID_THREAD_SPAWNER] = "thread_spawner"
311 };
312 
313 char *target_function_gen6[16] = {
314     [BRW_SFID_NULL] = "null",
315     [BRW_SFID_MATH] = "math",
316     [BRW_SFID_SAMPLER] = "sampler",
317     [BRW_SFID_MESSAGE_GATEWAY] = "gateway",
318     [BRW_SFID_URB] = "urb",
319     [BRW_SFID_THREAD_SPAWNER] = "thread_spawner",
320     [GEN6_SFID_DATAPORT_SAMPLER_CACHE] = "sampler",
321     [GEN6_SFID_DATAPORT_RENDER_CACHE] = "render",
322     [GEN6_SFID_DATAPORT_CONSTANT_CACHE] = "const",
323     [GEN7_SFID_DATAPORT_DATA_CACHE] = "data"
324 };
325 
326 char *dp_rc_msg_type_gen6[16] = {
327     [BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ] = "OWORD block read",
328     [GEN6_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ] = "RT UNORM read",
329     [GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ] = "OWORD dual block read",
330     [GEN6_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ] = "media block read",
331     [GEN6_DATAPORT_READ_MESSAGE_OWORD_UNALIGN_BLOCK_READ] = "OWORD unaligned block read",
332     [GEN6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ] = "DWORD scattered read",
333     [GEN6_DATAPORT_WRITE_MESSAGE_DWORD_ATOMIC_WRITE] = "DWORD atomic write",
334     [GEN6_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE] = "OWORD block write",
335     [GEN6_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE] = "OWORD dual block write",
336     [GEN6_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE] = "media block write",
337     [GEN6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE] = "DWORD scattered write",
338     [GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE] = "RT write",
339     [GEN6_DATAPORT_WRITE_MESSAGE_STREAMED_VB_WRITE] = "streamed VB write",
340     [GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_UNORM_WRITE] = "RT UNORMc write",
341 };
342 
343 char *math_function[16] = {
344     [BRW_MATH_FUNCTION_INV] = "inv",
345     [BRW_MATH_FUNCTION_LOG] = "log",
346     [BRW_MATH_FUNCTION_EXP] = "exp",
347     [BRW_MATH_FUNCTION_SQRT] = "sqrt",
348     [BRW_MATH_FUNCTION_RSQ] = "rsq",
349     [BRW_MATH_FUNCTION_SIN] = "sin",
350     [BRW_MATH_FUNCTION_COS] = "cos",
351     [BRW_MATH_FUNCTION_SINCOS] = "sincos",
352     [BRW_MATH_FUNCTION_TAN] = "tan",
353     [BRW_MATH_FUNCTION_POW] = "pow",
354     [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod",
355     [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT] = "intdiv",
356     [BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intmod",
357 };
358 
359 char *math_saturate[2] = {
360     [0] = "",
361     [1] = "sat"
362 };
363 
364 char *math_signed[2] = {
365     [0] = "",
366     [1] = "signed"
367 };
368 
369 char *math_scalar[2] = {
370     [0] = "",
371     [1] = "scalar"
372 };
373 
374 char *math_precision[2] = {
375     [0] = "",
376     [1] = "partial_precision"
377 };
378 
379 char *urb_opcode[2] = {
380     [0] = "urb_write",
381     [1] = "ff_sync",
382 };
383 
384 char *urb_swizzle[4] = {
385     [BRW_URB_SWIZZLE_NONE] = "",
386     [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave",
387     [BRW_URB_SWIZZLE_TRANSPOSE] = "transpose",
388 };
389 
390 char *urb_allocate[2] = {
391     [0] = "",
392     [1] = "allocate"
393 };
394 
395 char *urb_used[2] = {
396     [0] = "",
397     [1] = "used"
398 };
399 
400 char *urb_complete[2] = {
401     [0] = "",
402     [1] = "complete"
403 };
404 
405 char *sampler_target_format[4] = {
406     [0] = "F",
407     [2] = "UD",
408     [3] = "D"
409 };
410 
411 
412 static int column;
413 
string(FILE * file,char * string)414 static int string (FILE *file, char *string)
415 {
416     fputs (string, file);
417     column += strlen (string);
418     return 0;
419 }
420 
format(FILE * f,char * format,...)421 static int format (FILE *f, char *format, ...)
422 {
423     char    buf[1024];
424     va_list	args;
425     va_start (args, format);
426 
427     vsnprintf (buf, sizeof (buf) - 1, format, args);
428     va_end (args);
429     string (f, buf);
430     return 0;
431 }
432 
newline(FILE * f)433 static int newline (FILE *f)
434 {
435     putc ('\n', f);
436     column = 0;
437     return 0;
438 }
439 
pad(FILE * f,int c)440 static int pad (FILE *f, int c)
441 {
442     do
443 	string (f, " ");
444     while (column < c);
445     return 0;
446 }
447 
control(FILE * file,char * name,char * ctrl[],GLuint id,int * space)448 static int control (FILE *file, char *name, char *ctrl[], GLuint id, int *space)
449 {
450     if (!ctrl[id]) {
451 	fprintf (file, "*** invalid %s value %d ",
452 		 name, id);
453 	return 1;
454     }
455     if (ctrl[id][0])
456     {
457 	if (space && *space)
458 	    string (file, " ");
459 	string (file, ctrl[id]);
460 	if (space)
461 	    *space = 1;
462     }
463     return 0;
464 }
465 
print_opcode(FILE * file,int id)466 static int print_opcode (FILE *file, int id)
467 {
468     if (!opcode[id].name) {
469 	format (file, "*** invalid opcode value %d ", id);
470 	return 1;
471     }
472     string (file, opcode[id].name);
473     return 0;
474 }
475 
reg(FILE * file,GLuint _reg_file,GLuint _reg_nr)476 static int reg (FILE *file, GLuint _reg_file, GLuint _reg_nr)
477 {
478     int	err = 0;
479 
480     /* Clear the Compr4 instruction compression bit. */
481     if (_reg_file == BRW_MESSAGE_REGISTER_FILE)
482        _reg_nr &= ~(1 << 7);
483 
484     if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
485 	switch (_reg_nr & 0xf0) {
486 	case BRW_ARF_NULL:
487 	    string (file, "null");
488 	    return -1;
489 	case BRW_ARF_ADDRESS:
490 	    format (file, "a%d", _reg_nr & 0x0f);
491 	    break;
492 	case BRW_ARF_ACCUMULATOR:
493 	    format (file, "acc%d", _reg_nr & 0x0f);
494 	    break;
495 	case BRW_ARF_FLAG:
496 	    format (file, "f%d", _reg_nr & 0x0f);
497 	    break;
498 	case BRW_ARF_MASK:
499 	    format (file, "mask%d", _reg_nr & 0x0f);
500 	    break;
501 	case BRW_ARF_MASK_STACK:
502 	    format (file, "msd%d", _reg_nr & 0x0f);
503 	    break;
504 	case BRW_ARF_STATE:
505 	    format (file, "sr%d", _reg_nr & 0x0f);
506 	    break;
507 	case BRW_ARF_CONTROL:
508 	    format (file, "cr%d", _reg_nr & 0x0f);
509 	    break;
510 	case BRW_ARF_NOTIFICATION_COUNT:
511 	    format (file, "n%d", _reg_nr & 0x0f);
512 	    break;
513 	case BRW_ARF_IP:
514 	    string (file, "ip");
515 	    return -1;
516 	    break;
517 	default:
518 	    format (file, "ARF%d", _reg_nr);
519 	    break;
520 	}
521     } else {
522 	err  |= control (file, "src reg file", reg_file, _reg_file, NULL);
523 	format (file, "%d", _reg_nr);
524     }
525     return err;
526 }
527 
dest(FILE * file,struct brw_instruction * inst)528 static int dest (FILE *file, struct brw_instruction *inst)
529 {
530     int	err = 0;
531 
532     if (inst->header.access_mode == BRW_ALIGN_1)
533     {
534 	if (inst->bits1.da1.dest_address_mode == BRW_ADDRESS_DIRECT)
535 	{
536 	    err |= reg (file, inst->bits1.da1.dest_reg_file, inst->bits1.da1.dest_reg_nr);
537 	    if (err == -1)
538 		return 0;
539 	    if (inst->bits1.da1.dest_subreg_nr)
540 		format (file, ".%d", inst->bits1.da1.dest_subreg_nr /
541 				     reg_type_size[inst->bits1.da1.dest_reg_type]);
542 	    string (file, "<");
543 	    err |= control (file, "horiz stride", horiz_stride, inst->bits1.da1.dest_horiz_stride, NULL);
544 	    string (file, ">");
545 	    err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da1.dest_reg_type, NULL);
546 	}
547 	else
548 	{
549 	    string (file, "g[a0");
550 	    if (inst->bits1.ia1.dest_subreg_nr)
551 		format (file, ".%d", inst->bits1.ia1.dest_subreg_nr /
552 					reg_type_size[inst->bits1.ia1.dest_reg_type]);
553 	    if (inst->bits1.ia1.dest_indirect_offset)
554 		format (file, " %d", inst->bits1.ia1.dest_indirect_offset);
555 	    string (file, "]<");
556 	    err |= control (file, "horiz stride", horiz_stride, inst->bits1.ia1.dest_horiz_stride, NULL);
557 	    string (file, ">");
558 	    err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.ia1.dest_reg_type, NULL);
559 	}
560     }
561     else
562     {
563 	if (inst->bits1.da16.dest_address_mode == BRW_ADDRESS_DIRECT)
564 	{
565 	    err |= reg (file, inst->bits1.da16.dest_reg_file, inst->bits1.da16.dest_reg_nr);
566 	    if (err == -1)
567 		return 0;
568 	    if (inst->bits1.da16.dest_subreg_nr)
569 		format (file, ".%d", inst->bits1.da16.dest_subreg_nr /
570 				     reg_type_size[inst->bits1.da16.dest_reg_type]);
571 	    string (file, "<1>");
572 	    err |= control (file, "writemask", writemask, inst->bits1.da16.dest_writemask, NULL);
573 	    err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da16.dest_reg_type, NULL);
574 	}
575 	else
576 	{
577 	    err = 1;
578 	    string (file, "Indirect align16 address mode not supported");
579 	}
580     }
581 
582     return 0;
583 }
584 
dest_3src(FILE * file,struct brw_instruction * inst)585 static int dest_3src (FILE *file, struct brw_instruction *inst)
586 {
587     int	err = 0;
588     uint32_t reg_file;
589 
590     if (inst->bits1.da3src.dest_reg_file)
591        reg_file = BRW_MESSAGE_REGISTER_FILE;
592     else
593        reg_file = BRW_GENERAL_REGISTER_FILE;
594 
595     err |= reg (file, reg_file, inst->bits1.da3src.dest_reg_nr);
596     if (err == -1)
597        return 0;
598     if (inst->bits1.da3src.dest_subreg_nr)
599        format (file, ".%d", inst->bits1.da3src.dest_subreg_nr);
600     string (file, "<1>");
601     err |= control (file, "writemask", writemask, inst->bits1.da3src.dest_writemask, NULL);
602     err |= control (file, "dest reg encoding", reg_encoding, BRW_REGISTER_TYPE_F, NULL);
603 
604     return 0;
605 }
606 
src_align1_region(FILE * file,GLuint _vert_stride,GLuint _width,GLuint _horiz_stride)607 static int src_align1_region (FILE *file,
608 			      GLuint _vert_stride, GLuint _width, GLuint _horiz_stride)
609 {
610     int err = 0;
611     string (file, "<");
612     err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
613     string (file, ",");
614     err |= control (file, "width", width, _width, NULL);
615     string (file, ",");
616     err |= control (file, "horiz_stride", horiz_stride, _horiz_stride, NULL);
617     string (file, ">");
618     return err;
619 }
620 
src_da1(FILE * file,GLuint type,GLuint _reg_file,GLuint _vert_stride,GLuint _width,GLuint _horiz_stride,GLuint reg_num,GLuint sub_reg_num,GLuint __abs,GLuint _negate)621 static int src_da1 (FILE *file, GLuint type, GLuint _reg_file,
622 		    GLuint _vert_stride, GLuint _width, GLuint _horiz_stride,
623 		    GLuint reg_num, GLuint sub_reg_num, GLuint __abs, GLuint _negate)
624 {
625     int err = 0;
626     err |= control (file, "negate", negate, _negate, NULL);
627     err |= control (file, "abs", _abs, __abs, NULL);
628 
629     err |= reg (file, _reg_file, reg_num);
630     if (err == -1)
631 	return 0;
632     if (sub_reg_num)
633 	format (file, ".%d", sub_reg_num / reg_type_size[type]); /* use formal style like spec */
634     src_align1_region (file, _vert_stride, _width, _horiz_stride);
635     err |= control (file, "src reg encoding", reg_encoding, type, NULL);
636     return err;
637 }
638 
src_ia1(FILE * file,GLuint type,GLuint _reg_file,GLint _addr_imm,GLuint _addr_subreg_nr,GLuint _negate,GLuint __abs,GLuint _addr_mode,GLuint _horiz_stride,GLuint _width,GLuint _vert_stride)639 static int src_ia1 (FILE *file,
640 		    GLuint type,
641 		    GLuint _reg_file,
642 		    GLint _addr_imm,
643 		    GLuint _addr_subreg_nr,
644 		    GLuint _negate,
645 		    GLuint __abs,
646 		    GLuint _addr_mode,
647 		    GLuint _horiz_stride,
648 		    GLuint _width,
649 		    GLuint _vert_stride)
650 {
651     int err = 0;
652     err |= control (file, "negate", negate, _negate, NULL);
653     err |= control (file, "abs", _abs, __abs, NULL);
654 
655     string (file, "g[a0");
656     if (_addr_subreg_nr)
657 	format (file, ".%d", _addr_subreg_nr);
658     if (_addr_imm)
659 	format (file, " %d", _addr_imm);
660     string (file, "]");
661     src_align1_region (file, _vert_stride, _width, _horiz_stride);
662     err |= control (file, "src reg encoding", reg_encoding, type, NULL);
663     return err;
664 }
665 
src_da16(FILE * file,GLuint _reg_type,GLuint _reg_file,GLuint _vert_stride,GLuint _reg_nr,GLuint _subreg_nr,GLuint __abs,GLuint _negate,GLuint swz_x,GLuint swz_y,GLuint swz_z,GLuint swz_w)666 static int src_da16 (FILE *file,
667 		     GLuint _reg_type,
668 		     GLuint _reg_file,
669 		     GLuint _vert_stride,
670 		     GLuint _reg_nr,
671 		     GLuint _subreg_nr,
672 		     GLuint __abs,
673 		     GLuint _negate,
674 		     GLuint swz_x,
675 		     GLuint swz_y,
676 		     GLuint swz_z,
677 		     GLuint swz_w)
678 {
679     int err = 0;
680     err |= control (file, "negate", negate, _negate, NULL);
681     err |= control (file, "abs", _abs, __abs, NULL);
682 
683     err |= reg (file, _reg_file, _reg_nr);
684     if (err == -1)
685 	return 0;
686     if (_subreg_nr)
687 	/* bit4 for subreg number byte addressing. Make this same meaning as
688 	   in da1 case, so output looks consistent. */
689 	format (file, ".%d", 16 / reg_type_size[_reg_type]);
690     string (file, "<");
691     err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
692     string (file, ",4,1>");
693     /*
694      * Three kinds of swizzle display:
695      *  identity - nothing printed
696      *  1->all	 - print the single channel
697      *  1->1     - print the mapping
698      */
699     if (swz_x == BRW_CHANNEL_X &&
700 	swz_y == BRW_CHANNEL_Y &&
701 	swz_z == BRW_CHANNEL_Z &&
702 	swz_w == BRW_CHANNEL_W)
703     {
704 	;
705     }
706     else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w)
707     {
708 	string (file, ".");
709 	err |= control (file, "channel select", chan_sel, swz_x, NULL);
710     }
711     else
712     {
713 	string (file, ".");
714 	err |= control (file, "channel select", chan_sel, swz_x, NULL);
715 	err |= control (file, "channel select", chan_sel, swz_y, NULL);
716 	err |= control (file, "channel select", chan_sel, swz_z, NULL);
717 	err |= control (file, "channel select", chan_sel, swz_w, NULL);
718     }
719     err |= control (file, "src da16 reg type", reg_encoding, _reg_type, NULL);
720     return err;
721 }
722 
src0_3src(FILE * file,struct brw_instruction * inst)723 static int src0_3src (FILE *file, struct brw_instruction *inst)
724 {
725     int err = 0;
726     GLuint swz_x = (inst->bits2.da3src.src0_swizzle >> 0) & 0x3;
727     GLuint swz_y = (inst->bits2.da3src.src0_swizzle >> 2) & 0x3;
728     GLuint swz_z = (inst->bits2.da3src.src0_swizzle >> 4) & 0x3;
729     GLuint swz_w = (inst->bits2.da3src.src0_swizzle >> 6) & 0x3;
730 
731     err |= control (file, "negate", negate, inst->bits1.da3src.src0_negate, NULL);
732     err |= control (file, "abs", _abs, inst->bits1.da3src.src0_abs, NULL);
733 
734     err |= reg (file, BRW_GENERAL_REGISTER_FILE, inst->bits2.da3src.src0_reg_nr);
735     if (err == -1)
736 	return 0;
737     if (inst->bits2.da3src.src0_subreg_nr)
738 	format (file, ".%d", inst->bits2.da3src.src0_subreg_nr);
739     string (file, "<4,1,1>");
740     err |= control (file, "src da16 reg type", reg_encoding,
741 		    BRW_REGISTER_TYPE_F, NULL);
742     /*
743      * Three kinds of swizzle display:
744      *  identity - nothing printed
745      *  1->all	 - print the single channel
746      *  1->1     - print the mapping
747      */
748     if (swz_x == BRW_CHANNEL_X &&
749 	swz_y == BRW_CHANNEL_Y &&
750 	swz_z == BRW_CHANNEL_Z &&
751 	swz_w == BRW_CHANNEL_W)
752     {
753 	;
754     }
755     else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w)
756     {
757 	string (file, ".");
758 	err |= control (file, "channel select", chan_sel, swz_x, NULL);
759     }
760     else
761     {
762 	string (file, ".");
763 	err |= control (file, "channel select", chan_sel, swz_x, NULL);
764 	err |= control (file, "channel select", chan_sel, swz_y, NULL);
765 	err |= control (file, "channel select", chan_sel, swz_z, NULL);
766 	err |= control (file, "channel select", chan_sel, swz_w, NULL);
767     }
768     return err;
769 }
770 
src1_3src(FILE * file,struct brw_instruction * inst)771 static int src1_3src (FILE *file, struct brw_instruction *inst)
772 {
773     int err = 0;
774     GLuint swz_x = (inst->bits2.da3src.src1_swizzle >> 0) & 0x3;
775     GLuint swz_y = (inst->bits2.da3src.src1_swizzle >> 2) & 0x3;
776     GLuint swz_z = (inst->bits2.da3src.src1_swizzle >> 4) & 0x3;
777     GLuint swz_w = (inst->bits2.da3src.src1_swizzle >> 6) & 0x3;
778     GLuint src1_subreg_nr = (inst->bits2.da3src.src1_subreg_nr_low |
779 			     (inst->bits3.da3src.src1_subreg_nr_high << 2));
780 
781     err |= control (file, "negate", negate, inst->bits1.da3src.src1_negate,
782 		    NULL);
783     err |= control (file, "abs", _abs, inst->bits1.da3src.src1_abs, NULL);
784 
785     err |= reg (file, BRW_GENERAL_REGISTER_FILE,
786 		inst->bits3.da3src.src1_reg_nr);
787     if (err == -1)
788 	return 0;
789     if (src1_subreg_nr)
790 	format (file, ".%d", src1_subreg_nr);
791     string (file, "<4,1,1>");
792     err |= control (file, "src da16 reg type", reg_encoding,
793 		    BRW_REGISTER_TYPE_F, NULL);
794     /*
795      * Three kinds of swizzle display:
796      *  identity - nothing printed
797      *  1->all	 - print the single channel
798      *  1->1     - print the mapping
799      */
800     if (swz_x == BRW_CHANNEL_X &&
801 	swz_y == BRW_CHANNEL_Y &&
802 	swz_z == BRW_CHANNEL_Z &&
803 	swz_w == BRW_CHANNEL_W)
804     {
805 	;
806     }
807     else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w)
808     {
809 	string (file, ".");
810 	err |= control (file, "channel select", chan_sel, swz_x, NULL);
811     }
812     else
813     {
814 	string (file, ".");
815 	err |= control (file, "channel select", chan_sel, swz_x, NULL);
816 	err |= control (file, "channel select", chan_sel, swz_y, NULL);
817 	err |= control (file, "channel select", chan_sel, swz_z, NULL);
818 	err |= control (file, "channel select", chan_sel, swz_w, NULL);
819     }
820     return err;
821 }
822 
823 
src2_3src(FILE * file,struct brw_instruction * inst)824 static int src2_3src (FILE *file, struct brw_instruction *inst)
825 {
826     int err = 0;
827     GLuint swz_x = (inst->bits3.da3src.src2_swizzle >> 0) & 0x3;
828     GLuint swz_y = (inst->bits3.da3src.src2_swizzle >> 2) & 0x3;
829     GLuint swz_z = (inst->bits3.da3src.src2_swizzle >> 4) & 0x3;
830     GLuint swz_w = (inst->bits3.da3src.src2_swizzle >> 6) & 0x3;
831 
832     err |= control (file, "negate", negate, inst->bits1.da3src.src2_negate,
833 		    NULL);
834     err |= control (file, "abs", _abs, inst->bits1.da3src.src2_abs, NULL);
835 
836     err |= reg (file, BRW_GENERAL_REGISTER_FILE,
837 		inst->bits3.da3src.src2_reg_nr);
838     if (err == -1)
839 	return 0;
840     if (inst->bits3.da3src.src2_subreg_nr)
841 	format (file, ".%d", inst->bits3.da3src.src2_subreg_nr);
842     string (file, "<4,1,1>");
843     err |= control (file, "src da16 reg type", reg_encoding,
844 		    BRW_REGISTER_TYPE_F, NULL);
845     /*
846      * Three kinds of swizzle display:
847      *  identity - nothing printed
848      *  1->all	 - print the single channel
849      *  1->1     - print the mapping
850      */
851     if (swz_x == BRW_CHANNEL_X &&
852 	swz_y == BRW_CHANNEL_Y &&
853 	swz_z == BRW_CHANNEL_Z &&
854 	swz_w == BRW_CHANNEL_W)
855     {
856 	;
857     }
858     else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w)
859     {
860 	string (file, ".");
861 	err |= control (file, "channel select", chan_sel, swz_x, NULL);
862     }
863     else
864     {
865 	string (file, ".");
866 	err |= control (file, "channel select", chan_sel, swz_x, NULL);
867 	err |= control (file, "channel select", chan_sel, swz_y, NULL);
868 	err |= control (file, "channel select", chan_sel, swz_z, NULL);
869 	err |= control (file, "channel select", chan_sel, swz_w, NULL);
870     }
871     return err;
872 }
873 
imm(FILE * file,GLuint type,struct brw_instruction * inst)874 static int imm (FILE *file, GLuint type, struct brw_instruction *inst) {
875     switch (type) {
876     case BRW_REGISTER_TYPE_UD:
877 	format (file, "0x%08xUD", inst->bits3.ud);
878 	break;
879     case BRW_REGISTER_TYPE_D:
880 	format (file, "%dD", inst->bits3.d);
881 	break;
882     case BRW_REGISTER_TYPE_UW:
883 	format (file, "0x%04xUW", (uint16_t) inst->bits3.ud);
884 	break;
885     case BRW_REGISTER_TYPE_W:
886 	format (file, "%dW", (int16_t) inst->bits3.d);
887 	break;
888     case BRW_REGISTER_TYPE_UB:
889 	format (file, "0x%02xUB", (int8_t) inst->bits3.ud);
890 	break;
891     case BRW_REGISTER_TYPE_VF:
892 	format (file, "Vector Float");
893 	break;
894     case BRW_REGISTER_TYPE_V:
895 	format (file, "0x%08xV", inst->bits3.ud);
896 	break;
897     case BRW_REGISTER_TYPE_F:
898 	format (file, "%-gF", inst->bits3.f);
899     }
900     return 0;
901 }
902 
src0(FILE * file,struct brw_instruction * inst)903 static int src0 (FILE *file, struct brw_instruction *inst)
904 {
905     if (inst->bits1.da1.src0_reg_file == BRW_IMMEDIATE_VALUE)
906 	return imm (file, inst->bits1.da1.src0_reg_type,
907 		    inst);
908     else if (inst->header.access_mode == BRW_ALIGN_1)
909     {
910 	if (inst->bits2.da1.src0_address_mode == BRW_ADDRESS_DIRECT)
911 	{
912 	    return src_da1 (file,
913 			    inst->bits1.da1.src0_reg_type,
914 			    inst->bits1.da1.src0_reg_file,
915 			    inst->bits2.da1.src0_vert_stride,
916 			    inst->bits2.da1.src0_width,
917 			    inst->bits2.da1.src0_horiz_stride,
918 			    inst->bits2.da1.src0_reg_nr,
919 			    inst->bits2.da1.src0_subreg_nr,
920 			    inst->bits2.da1.src0_abs,
921 			    inst->bits2.da1.src0_negate);
922 	}
923 	else
924 	{
925 	    return src_ia1 (file,
926 			    inst->bits1.ia1.src0_reg_type,
927 			    inst->bits1.ia1.src0_reg_file,
928 			    inst->bits2.ia1.src0_indirect_offset,
929 			    inst->bits2.ia1.src0_subreg_nr,
930 			    inst->bits2.ia1.src0_negate,
931 			    inst->bits2.ia1.src0_abs,
932 			    inst->bits2.ia1.src0_address_mode,
933 			    inst->bits2.ia1.src0_horiz_stride,
934 			    inst->bits2.ia1.src0_width,
935 			    inst->bits2.ia1.src0_vert_stride);
936 	}
937     }
938     else
939     {
940 	if (inst->bits2.da16.src0_address_mode == BRW_ADDRESS_DIRECT)
941 	{
942 	    return src_da16 (file,
943 			     inst->bits1.da16.src0_reg_type,
944 			     inst->bits1.da16.src0_reg_file,
945 			     inst->bits2.da16.src0_vert_stride,
946 			     inst->bits2.da16.src0_reg_nr,
947 			     inst->bits2.da16.src0_subreg_nr,
948 			     inst->bits2.da16.src0_abs,
949 			     inst->bits2.da16.src0_negate,
950 			     inst->bits2.da16.src0_swz_x,
951 			     inst->bits2.da16.src0_swz_y,
952 			     inst->bits2.da16.src0_swz_z,
953 			     inst->bits2.da16.src0_swz_w);
954 	}
955 	else
956 	{
957 	    string (file, "Indirect align16 address mode not supported");
958 	    return 1;
959 	}
960     }
961 }
962 
src1(FILE * file,struct brw_instruction * inst)963 static int src1 (FILE *file, struct brw_instruction *inst)
964 {
965     if (inst->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE)
966 	return imm (file, inst->bits1.da1.src1_reg_type,
967 		    inst);
968     else if (inst->header.access_mode == BRW_ALIGN_1)
969     {
970 	if (inst->bits3.da1.src1_address_mode == BRW_ADDRESS_DIRECT)
971 	{
972 	    return src_da1 (file,
973 			    inst->bits1.da1.src1_reg_type,
974 			    inst->bits1.da1.src1_reg_file,
975 			    inst->bits3.da1.src1_vert_stride,
976 			    inst->bits3.da1.src1_width,
977 			    inst->bits3.da1.src1_horiz_stride,
978 			    inst->bits3.da1.src1_reg_nr,
979 			    inst->bits3.da1.src1_subreg_nr,
980 			    inst->bits3.da1.src1_abs,
981 			    inst->bits3.da1.src1_negate);
982 	}
983 	else
984 	{
985 	    return src_ia1 (file,
986 			    inst->bits1.ia1.src1_reg_type,
987 			    inst->bits1.ia1.src1_reg_file,
988 			    inst->bits3.ia1.src1_indirect_offset,
989 			    inst->bits3.ia1.src1_subreg_nr,
990 			    inst->bits3.ia1.src1_negate,
991 			    inst->bits3.ia1.src1_abs,
992 			    inst->bits3.ia1.src1_address_mode,
993 			    inst->bits3.ia1.src1_horiz_stride,
994 			    inst->bits3.ia1.src1_width,
995 			    inst->bits3.ia1.src1_vert_stride);
996 	}
997     }
998     else
999     {
1000 	if (inst->bits3.da16.src1_address_mode == BRW_ADDRESS_DIRECT)
1001 	{
1002 	    return src_da16 (file,
1003 			     inst->bits1.da16.src1_reg_type,
1004 			     inst->bits1.da16.src1_reg_file,
1005 			     inst->bits3.da16.src1_vert_stride,
1006 			     inst->bits3.da16.src1_reg_nr,
1007 			     inst->bits3.da16.src1_subreg_nr,
1008 			     inst->bits3.da16.src1_abs,
1009 			     inst->bits3.da16.src1_negate,
1010 			     inst->bits3.da16.src1_swz_x,
1011 			     inst->bits3.da16.src1_swz_y,
1012 			     inst->bits3.da16.src1_swz_z,
1013 			     inst->bits3.da16.src1_swz_w);
1014 	}
1015 	else
1016 	{
1017 	    string (file, "Indirect align16 address mode not supported");
1018 	    return 1;
1019 	}
1020     }
1021 }
1022 
1023 int esize[6] = {
1024 	[0] = 1,
1025 	[1] = 2,
1026 	[2] = 4,
1027 	[3] = 8,
1028 	[4] = 16,
1029 	[5] = 32,
1030 };
1031 
qtr_ctrl(FILE * file,struct brw_instruction * inst)1032 static int qtr_ctrl(FILE *file, struct brw_instruction *inst)
1033 {
1034     int qtr_ctl = inst->header.compression_control;
1035     int exec_size = esize[inst->header.execution_size];
1036 
1037     if (exec_size == 8) {
1038 	switch (qtr_ctl) {
1039 	case 0:
1040 	    string (file, " 1Q");
1041 	    break;
1042 	case 1:
1043 	    string (file, " 2Q");
1044 	    break;
1045 	case 2:
1046 	    string (file, " 3Q");
1047 	    break;
1048 	case 3:
1049 	    string (file, " 4Q");
1050 	    break;
1051 	}
1052     } else if (exec_size == 16){
1053 	if (qtr_ctl < 2)
1054 	    string (file, " 1H");
1055 	else
1056 	    string (file, " 2H");
1057     }
1058     return 0;
1059 }
1060 
brw_disasm(FILE * file,struct brw_instruction * inst,int gen)1061 int brw_disasm (FILE *file, struct brw_instruction *inst, int gen)
1062 {
1063     int	err = 0;
1064     int space = 0;
1065 
1066     if (inst->header.predicate_control) {
1067 	string (file, "(");
1068 	err |= control (file, "predicate inverse", pred_inv, inst->header.predicate_inverse, NULL);
1069 	string (file, "f0");
1070 	if (inst->bits2.da1.flag_reg_nr)
1071 	    format (file, ".%d", inst->bits2.da1.flag_reg_nr);
1072 	if (inst->header.access_mode == BRW_ALIGN_1)
1073 	    err |= control (file, "predicate control align1", pred_ctrl_align1,
1074 			    inst->header.predicate_control, NULL);
1075 	else
1076 	    err |= control (file, "predicate control align16", pred_ctrl_align16,
1077 			    inst->header.predicate_control, NULL);
1078 	string (file, ") ");
1079     }
1080 
1081     err |= print_opcode (file, inst->header.opcode);
1082     err |= control (file, "saturate", saturate, inst->header.saturate, NULL);
1083     err |= control (file, "debug control", debug_ctrl, inst->header.debug_control, NULL);
1084 
1085     if (inst->header.opcode == BRW_OPCODE_MATH) {
1086 	string (file, " ");
1087 	err |= control (file, "function", math_function,
1088 			inst->header.destreg__conditionalmod, NULL);
1089     } else if (inst->header.opcode != BRW_OPCODE_SEND &&
1090 	       inst->header.opcode != BRW_OPCODE_SENDC)
1091 	err |= control (file, "conditional modifier", conditional_modifier,
1092 			inst->header.destreg__conditionalmod, NULL);
1093 
1094     if (inst->header.opcode != BRW_OPCODE_NOP) {
1095 	string (file, "(");
1096 	err |= control (file, "execution size", exec_size, inst->header.execution_size, NULL);
1097 	string (file, ")");
1098     }
1099 
1100     if (inst->header.opcode == BRW_OPCODE_SEND && gen < 6)
1101 	format (file, " %d", inst->header.destreg__conditionalmod);
1102 
1103     if (opcode[inst->header.opcode].nsrc == 3) {
1104        pad (file, 16);
1105        err |= dest_3src (file, inst);
1106 
1107        pad (file, 32);
1108        err |= src0_3src (file, inst);
1109 
1110        pad (file, 48);
1111        err |= src1_3src (file, inst);
1112 
1113        pad (file, 64);
1114        err |= src2_3src (file, inst);
1115     } else {
1116        if (opcode[inst->header.opcode].ndst > 0) {
1117 	  pad (file, 16);
1118 	  err |= dest (file, inst);
1119        } else if (gen >= 6 && (inst->header.opcode == BRW_OPCODE_IF ||
1120 			       inst->header.opcode == BRW_OPCODE_ELSE ||
1121 			       inst->header.opcode == BRW_OPCODE_ENDIF ||
1122 			       inst->header.opcode == BRW_OPCODE_WHILE)) {
1123 	  format (file, " %d", inst->bits1.branch_gen6.jump_count);
1124        } else if (gen >= 6 && (inst->header.opcode == BRW_OPCODE_BREAK ||
1125 			       inst->header.opcode == BRW_OPCODE_CONTINUE ||
1126 			       inst->header.opcode == BRW_OPCODE_HALT)) {
1127 	  format (file, " %d %d", inst->bits3.break_cont.uip, inst->bits3.break_cont.jip);
1128        } else if (inst->header.opcode == BRW_OPCODE_JMPI) {
1129 	  format (file, " %d", inst->bits3.d);
1130        }
1131 
1132        if (opcode[inst->header.opcode].nsrc > 0) {
1133 	  pad (file, 32);
1134 	  err |= src0 (file, inst);
1135        }
1136        if (opcode[inst->header.opcode].nsrc > 1) {
1137 	  pad (file, 48);
1138 	  err |= src1 (file, inst);
1139        }
1140     }
1141 
1142     if (inst->header.opcode == BRW_OPCODE_SEND ||
1143 	inst->header.opcode == BRW_OPCODE_SENDC) {
1144 	enum brw_message_target target;
1145 
1146 	if (gen >= 6)
1147 	    target = inst->header.destreg__conditionalmod;
1148 	else if (gen == 5)
1149 	    target = inst->bits2.send_gen5.sfid;
1150 	else
1151 	    target = inst->bits3.generic.msg_target;
1152 
1153 	newline (file);
1154 	pad (file, 16);
1155 	space = 0;
1156 
1157 	if (gen >= 6) {
1158 	   err |= control (file, "target function", target_function_gen6,
1159 			   target, &space);
1160 	} else {
1161 	   err |= control (file, "target function", target_function,
1162 			   target, &space);
1163 	}
1164 
1165 	switch (target) {
1166 	case BRW_SFID_MATH:
1167 	    err |= control (file, "math function", math_function,
1168 			    inst->bits3.math.function, &space);
1169 	    err |= control (file, "math saturate", math_saturate,
1170 			    inst->bits3.math.saturate, &space);
1171 	    err |= control (file, "math signed", math_signed,
1172 			    inst->bits3.math.int_type, &space);
1173 	    err |= control (file, "math scalar", math_scalar,
1174 			    inst->bits3.math.data_type, &space);
1175 	    err |= control (file, "math precision", math_precision,
1176 			    inst->bits3.math.precision, &space);
1177 	    break;
1178 	case BRW_SFID_SAMPLER:
1179 	    if (gen >= 7) {
1180 		format (file, " (%d, %d, %d, %d)",
1181 			inst->bits3.sampler_gen7.binding_table_index,
1182 			inst->bits3.sampler_gen7.sampler,
1183 			inst->bits3.sampler_gen7.msg_type,
1184 			inst->bits3.sampler_gen7.simd_mode);
1185 	    } else if (gen >= 5) {
1186 		format (file, " (%d, %d, %d, %d)",
1187 			inst->bits3.sampler_gen5.binding_table_index,
1188 			inst->bits3.sampler_gen5.sampler,
1189 			inst->bits3.sampler_gen5.msg_type,
1190 			inst->bits3.sampler_gen5.simd_mode);
1191 	    } else if (0 /* FINISHME: is_g4x */) {
1192 		format (file, " (%d, %d)",
1193 			inst->bits3.sampler_g4x.binding_table_index,
1194 			inst->bits3.sampler_g4x.sampler);
1195 	    } else {
1196 		format (file, " (%d, %d, ",
1197 			inst->bits3.sampler.binding_table_index,
1198 			inst->bits3.sampler.sampler);
1199 		err |= control (file, "sampler target format",
1200 				sampler_target_format,
1201 				inst->bits3.sampler.return_format, NULL);
1202 		string (file, ")");
1203 	    }
1204 	    break;
1205 	case BRW_SFID_DATAPORT_READ:
1206 	    if (gen >= 6) {
1207 		format (file, " (%d, %d, %d, %d)",
1208 			inst->bits3.gen6_dp.binding_table_index,
1209 			inst->bits3.gen6_dp.msg_control,
1210 			inst->bits3.gen6_dp.msg_type,
1211 			inst->bits3.gen6_dp.send_commit_msg);
1212 	    } else if (gen >= 5 /* FINISHME: || is_g4x */) {
1213 		format (file, " (%d, %d, %d)",
1214 			inst->bits3.dp_read_gen5.binding_table_index,
1215 			inst->bits3.dp_read_gen5.msg_control,
1216 			inst->bits3.dp_read_gen5.msg_type);
1217 	    } else {
1218 		format (file, " (%d, %d, %d)",
1219 			inst->bits3.dp_read.binding_table_index,
1220 			inst->bits3.dp_read.msg_control,
1221 			inst->bits3.dp_read.msg_type);
1222 	    }
1223 	    break;
1224 
1225 	case BRW_SFID_DATAPORT_WRITE:
1226 	    if (gen >= 7) {
1227 		format (file, " (");
1228 
1229 		err |= control (file, "DP rc message type",
1230 				dp_rc_msg_type_gen6,
1231 				inst->bits3.gen7_dp.msg_type, &space);
1232 
1233 		format (file, ", %d, %d, %d)",
1234 			inst->bits3.gen7_dp.binding_table_index,
1235 			inst->bits3.gen7_dp.msg_control,
1236 			inst->bits3.gen7_dp.msg_type);
1237 	    } else if (gen == 6) {
1238 		format (file, " (");
1239 
1240 		err |= control (file, "DP rc message type",
1241 				dp_rc_msg_type_gen6,
1242 				inst->bits3.gen6_dp.msg_type, &space);
1243 
1244 		format (file, ", %d, %d, %d, %d)",
1245 			inst->bits3.gen6_dp.binding_table_index,
1246 			inst->bits3.gen6_dp.msg_control,
1247 			inst->bits3.gen6_dp.msg_type,
1248 			inst->bits3.gen6_dp.send_commit_msg);
1249 	    } else {
1250 		format (file, " (%d, %d, %d, %d)",
1251 			inst->bits3.dp_write.binding_table_index,
1252 			(inst->bits3.dp_write.last_render_target << 3) |
1253 			inst->bits3.dp_write.msg_control,
1254 			inst->bits3.dp_write.msg_type,
1255 			inst->bits3.dp_write.send_commit_msg);
1256 	    }
1257 	    break;
1258 
1259 	case BRW_SFID_URB:
1260 	    if (gen >= 5) {
1261 		format (file, " %d", inst->bits3.urb_gen5.offset);
1262 	    } else {
1263 		format (file, " %d", inst->bits3.urb.offset);
1264 	    }
1265 
1266 	    space = 1;
1267 	    if (gen >= 5) {
1268 		err |= control (file, "urb opcode", urb_opcode,
1269 				inst->bits3.urb_gen5.opcode, &space);
1270 	    }
1271 	    err |= control (file, "urb swizzle", urb_swizzle,
1272 			    inst->bits3.urb.swizzle_control, &space);
1273 	    err |= control (file, "urb allocate", urb_allocate,
1274 			    inst->bits3.urb.allocate, &space);
1275 	    err |= control (file, "urb used", urb_used,
1276 			    inst->bits3.urb.used, &space);
1277 	    err |= control (file, "urb complete", urb_complete,
1278 			    inst->bits3.urb.complete, &space);
1279 	    break;
1280 	case BRW_SFID_THREAD_SPAWNER:
1281 	    break;
1282 	case GEN7_SFID_DATAPORT_DATA_CACHE:
1283 	    format (file, " (%d, %d, %d)",
1284 		    inst->bits3.gen7_dp.binding_table_index,
1285 		    inst->bits3.gen7_dp.msg_control,
1286 		    inst->bits3.gen7_dp.msg_type);
1287 	    break;
1288 
1289 
1290 	default:
1291 	    format (file, "unsupported target %d", target);
1292 	    break;
1293 	}
1294 	if (space)
1295 	    string (file, " ");
1296 	if (gen >= 5) {
1297 	   format (file, "mlen %d",
1298 		   inst->bits3.generic_gen5.msg_length);
1299 	   format (file, " rlen %d",
1300 		   inst->bits3.generic_gen5.response_length);
1301 	} else {
1302 	   format (file, "mlen %d",
1303 		   inst->bits3.generic.msg_length);
1304 	   format (file, " rlen %d",
1305 		   inst->bits3.generic.response_length);
1306 	}
1307     }
1308     pad (file, 64);
1309     if (inst->header.opcode != BRW_OPCODE_NOP) {
1310 	string (file, "{");
1311 	space = 1;
1312 	err |= control(file, "access mode", access_mode, inst->header.access_mode, &space);
1313 	if (gen >= 6)
1314 	    err |= control (file, "write enable control", wectrl, inst->header.mask_control, &space);
1315 	else
1316 	    err |= control (file, "mask control", mask_ctrl, inst->header.mask_control, &space);
1317 	err |= control (file, "dependency control", dep_ctrl, inst->header.dependency_control, &space);
1318 
1319 	if (gen >= 6)
1320 	    err |= qtr_ctrl (file, inst);
1321 	else {
1322 	    if (inst->header.compression_control == BRW_COMPRESSION_COMPRESSED &&
1323 		opcode[inst->header.opcode].ndst > 0 &&
1324 		inst->bits1.da1.dest_reg_file == BRW_MESSAGE_REGISTER_FILE &&
1325 		inst->bits1.da1.dest_reg_nr & (1 << 7)) {
1326 		format (file, " compr4");
1327 	    } else {
1328 		err |= control (file, "compression control", compr_ctrl,
1329 				inst->header.compression_control, &space);
1330 	    }
1331 	}
1332 
1333 	err |= control (file, "thread control", thread_ctrl, inst->header.thread_control, &space);
1334 	if (gen >= 6)
1335 	    err |= control (file, "acc write control", accwr, inst->header.acc_wr_control, &space);
1336 	if (inst->header.opcode == BRW_OPCODE_SEND ||
1337 	    inst->header.opcode == BRW_OPCODE_SENDC)
1338 	    err |= control (file, "end of thread", end_of_thread,
1339 			    inst->bits3.generic.end_of_thread, &space);
1340 	if (space)
1341 	    string (file, " ");
1342 	string (file, "}");
1343     }
1344     string (file, ";");
1345     newline (file);
1346     return err;
1347 }
1348