2 * Copyright © 2008 Keith Packard
3 * Copyright © 2009-2013 Intel Corporation
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting documentation, and
9 * that the name of the copyright holders not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. The copyright holders make no representations
12 * about the suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
31 #include "brw_context.h"
32 #include "brw_defines.h"
33 #include "gen8_instruction.h"
35 static const struct opcode_desc
*m_opcode
= opcode_descs
;
37 static const char *const m_conditional_modifier
[16] = {
38 [BRW_CONDITIONAL_NONE
] = "",
39 [BRW_CONDITIONAL_Z
] = ".e",
40 [BRW_CONDITIONAL_NZ
] = ".ne",
41 [BRW_CONDITIONAL_G
] = ".g",
42 [BRW_CONDITIONAL_GE
] = ".ge",
43 [BRW_CONDITIONAL_L
] = ".l",
44 [BRW_CONDITIONAL_LE
] = ".le",
45 [BRW_CONDITIONAL_O
] = ".o",
46 [BRW_CONDITIONAL_U
] = ".u",
49 static const char *const m_negate
[2] = { "", "-" };
51 static const char *const m_abs
[2] = { "", "(abs)" };
53 static const char *const m_bitnot
[2] = { "", "~" };
55 static const char *const m_vert_stride
[16] = {
65 static const char *const width
[8] = {
73 static const char *const m_horiz_stride
[4] = {
80 static const char *const m_chan_sel
[4] = { "x", "y", "z", "w" };
82 static const char *const m_debug_ctrl
[2] = { "", ".breakpoint" };
84 static const char *const m_saturate
[2] = { "", ".sat" };
86 static const char *const m_accwr
[2] = { "", "AccWrEnable" };
88 static const char *const m_maskctrl
[2] = { "WE_normal", "WE_all" };
90 static const char *const m_exec_size
[8] = {
99 static const char *const m_pred_inv
[2] = { "+", "-" };
101 static const char *const m_pred_ctrl_align16
[16] = {
112 static const char *const m_pred_ctrl_align1
[16] = {
129 static const char *const m_thread_ctrl
[4] = {
135 static const char *const m_dep_clear
[4] = {
140 static const char *const m_dep_check
[4] = {
145 static const char *const m_mask_ctrl
[4] = {
150 static const char *const m_access_mode
[2] = { "align1", "align16" };
152 static const char *const m_reg_encoding
[] = {
153 [BRW_HW_REG_TYPE_UD
] = "UD",
154 [BRW_HW_REG_TYPE_D
] = "D",
155 [BRW_HW_REG_TYPE_UW
] = "UW",
156 [BRW_HW_REG_TYPE_W
] = "W",
157 [BRW_HW_REG_NON_IMM_TYPE_UB
] = "UB",
158 [BRW_HW_REG_NON_IMM_TYPE_B
] = "B",
159 [GEN7_HW_REG_NON_IMM_TYPE_DF
] = "DF",
160 [BRW_HW_REG_TYPE_F
] = "F",
161 [GEN8_HW_REG_TYPE_UQ
] = "UQ",
162 [GEN8_HW_REG_TYPE_Q
] = "Q",
163 [GEN8_HW_REG_NON_IMM_TYPE_HF
] = "HF",
166 static const char *const m_three_source_reg_encoding
[] = {
167 [BRW_3SRC_TYPE_F
] = "F",
168 [BRW_3SRC_TYPE_D
] = "D",
169 [BRW_3SRC_TYPE_UD
] = "UD",
172 static const int reg_type_size
[] = {
173 [BRW_HW_REG_TYPE_UD
] = 4,
174 [BRW_HW_REG_TYPE_D
] = 4,
175 [BRW_HW_REG_TYPE_UW
] = 2,
176 [BRW_HW_REG_TYPE_W
] = 2,
177 [BRW_HW_REG_NON_IMM_TYPE_UB
] = 1,
178 [BRW_HW_REG_NON_IMM_TYPE_B
] = 1,
179 [GEN7_HW_REG_NON_IMM_TYPE_DF
] = 8,
180 [BRW_HW_REG_TYPE_F
] = 4,
181 [GEN8_HW_REG_NON_IMM_TYPE_HF
] = 2,
184 static const char *const m_reg_file
[4] = {
185 [BRW_ARCHITECTURE_REGISTER_FILE
] = "A",
186 [BRW_GENERAL_REGISTER_FILE
] = "g",
187 [BRW_IMMEDIATE_VALUE
] = "imm",
190 static const char *const m_writemask
[16] = {
209 static const char *const m_eot
[2] = { "", "EOT" };
211 static const char *const m_sfid
[16] = {
212 [BRW_SFID_NULL
] = "null",
213 [BRW_SFID_SAMPLER
] = "sampler",
214 [BRW_SFID_MESSAGE_GATEWAY
] = "gateway",
215 [GEN6_SFID_DATAPORT_SAMPLER_CACHE
] = "dp/sampler_cache",
216 [GEN6_SFID_DATAPORT_RENDER_CACHE
] = "dp/render_cache",
217 [BRW_SFID_URB
] = "URB",
218 [BRW_SFID_THREAD_SPAWNER
] = "thread_spawner",
219 [BRW_SFID_VME
] = "vme",
220 [GEN6_SFID_DATAPORT_CONSTANT_CACHE
] = "dp/constant_cache",
221 [GEN7_SFID_DATAPORT_DATA_CACHE
] = "dp/data_cache",
222 [GEN7_SFID_PIXEL_INTERPOLATOR
] = "pi",
223 [HSW_SFID_DATAPORT_DATA_CACHE_1
] = "dp/data_cache:1",
224 [HSW_SFID_CRE
] = "cre",
227 static const char *const dp_dc1_msg_type
[16] = {
228 [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ
] = "untyped surface read",
229 [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP
] = "DC untyped atomic op",
230 [HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2
] = "DC untyped 4x2 atomic op",
231 [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_READ
] = "DC media block read",
232 [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ
] = "DC typed surface read",
233 [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP
] = "DC typed atomic",
234 [HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2
] = "DC typed 4x2 atomic op",
235 [HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE
] = "DC untyped surface write",
236 [HSW_DATAPORT_DC_PORT1_MEDIA_BLOCK_WRITE
] = "DC media block write",
237 [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP
] = "DC atomic counter op",
238 [HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2
] = "DC 4x2 atomic counter op",
239 [HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE
] = "DC typed surface write",
242 static const char * const aop
[16] = {
243 [BRW_AOP_AND
] = "and",
245 [BRW_AOP_XOR
] = "xor",
246 [BRW_AOP_MOV
] = "mov",
247 [BRW_AOP_INC
] = "inc",
248 [BRW_AOP_DEC
] = "dec",
249 [BRW_AOP_ADD
] = "add",
250 [BRW_AOP_SUB
] = "sub",
251 [BRW_AOP_REVSUB
] = "revsub",
252 [BRW_AOP_IMAX
] = "imax",
253 [BRW_AOP_IMIN
] = "imin",
254 [BRW_AOP_UMAX
] = "umax",
255 [BRW_AOP_UMIN
] = "umin",
256 [BRW_AOP_CMPWR
] = "cmpwr",
257 [BRW_AOP_PREDEC
] = "predec",
260 static const char *const m_math_function
[16] = {
261 [BRW_MATH_FUNCTION_INV
] = "inv",
262 [BRW_MATH_FUNCTION_LOG
] = "log",
263 [BRW_MATH_FUNCTION_EXP
] = "exp",
264 [BRW_MATH_FUNCTION_SQRT
] = "sqrt",
265 [BRW_MATH_FUNCTION_RSQ
] = "rsq",
266 [BRW_MATH_FUNCTION_SIN
] = "sin",
267 [BRW_MATH_FUNCTION_COS
] = "cos",
268 [BRW_MATH_FUNCTION_FDIV
] = "fdiv",
269 [BRW_MATH_FUNCTION_POW
] = "pow",
270 [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER
] = "intdivmod",
271 [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT
] = "intdiv",
272 [BRW_MATH_FUNCTION_INT_DIV_REMAINDER
] = "intmod",
273 [GEN8_MATH_FUNCTION_INVM
] = "invm",
274 [GEN8_MATH_FUNCTION_RSQRTM
] = "rsqrtm",
277 static const char *const m_urb_opcode
[16] = {
287 /* [9-15] - reserved */
290 static const char *const m_urb_interleave
[2] = { "", "interleaved" };
292 static const char *const m_rt_opcode
[] = {
306 string(FILE *file
, const char *string
)
309 column
+= strlen(string
);
314 format(FILE *f
, const char *format
, ...)
318 va_start(args
, format
);
320 vsnprintf(buf
, sizeof(buf
) - 1, format
, args
);
344 control(FILE *file
, const char *name
, const char *const ctrl
[],
345 unsigned id
, int *space
)
348 fprintf(file
, "*** invalid %s value %d ", name
, id
);
354 string(file
, ctrl
[id
]);
362 print_opcode(FILE *file
, int id
)
364 if (!m_opcode
[id
].name
) {
365 format(file
, "*** invalid opcode value %d ", id
);
368 string(file
, m_opcode
[id
].name
);
373 reg(FILE *file
, unsigned reg_file
, unsigned _reg_nr
)
377 if (reg_file
== BRW_ARCHITECTURE_REGISTER_FILE
) {
378 switch (_reg_nr
& 0xf0) {
380 string(file
, "null");
382 case BRW_ARF_ADDRESS
:
383 format(file
, "a%d", _reg_nr
& 0x0f);
385 case BRW_ARF_ACCUMULATOR
:
386 format(file
, "acc%d", _reg_nr
& 0x0f);
389 format(file
, "f%d", _reg_nr
& 0x0f);
392 format(file
, "mask%d", _reg_nr
& 0x0f);
394 case BRW_ARF_MASK_STACK
:
395 format(file
, "msd%d", _reg_nr
& 0x0f);
398 format(file
, "sr%d", _reg_nr
& 0x0f);
400 case BRW_ARF_CONTROL
:
401 format(file
, "cr%d", _reg_nr
& 0x0f);
403 case BRW_ARF_NOTIFICATION_COUNT
:
404 format(file
, "n%d", _reg_nr
& 0x0f);
411 format(file
, "ARF%d", _reg_nr
);
415 err
|= control(file
, "src reg file", m_reg_file
, reg_file
, NULL
);
416 format(file
, "%d", _reg_nr
);
422 dest(FILE *file
, struct gen8_instruction
*inst
)
426 if (gen8_access_mode(inst
) == BRW_ALIGN_1
) {
427 assert(gen8_dst_address_mode(inst
) == BRW_ADDRESS_DIRECT
);
428 err
|= reg(file
, gen8_dst_reg_file(inst
), gen8_dst_da_reg_nr(inst
));
431 if (gen8_dst_da1_subreg_nr(inst
))
432 format(file
, ".%d", gen8_dst_da1_subreg_nr(inst
) /
433 reg_type_size
[gen8_dst_reg_type(inst
)]);
435 err
|= control(file
, "horiz stride", m_horiz_stride
, gen8_dst_da1_hstride(inst
), NULL
);
437 err
|= control(file
, "dest reg encoding", m_reg_encoding
, gen8_dst_reg_type(inst
), NULL
);
439 assert(gen8_dst_address_mode(inst
) == BRW_ADDRESS_DIRECT
);
440 err
|= reg(file
, gen8_dst_reg_file(inst
), gen8_dst_da_reg_nr(inst
));
443 if (gen8_dst_da16_subreg_nr(inst
))
444 format(file
, ".%d", gen8_dst_da16_subreg_nr(inst
) /
445 reg_type_size
[gen8_dst_reg_type(inst
)]);
447 err
|= control(file
, "writemask", m_writemask
, gen8_da16_writemask(inst
), NULL
);
448 err
|= control(file
, "dest reg encoding", m_reg_encoding
, gen8_dst_reg_type(inst
), NULL
);
455 dest_3src(FILE *file
, struct gen8_instruction
*inst
)
459 err
|= reg(file
, BRW_GENERAL_REGISTER_FILE
, gen8_dst_3src_reg_nr(inst
));
462 if (gen8_dst_3src_subreg_nr(inst
))
463 format(file
, ".%d", gen8_dst_3src_subreg_nr(inst
));
465 err
|= control(file
, "writemask", m_writemask
, gen8_dst_3src_writemask(inst
),
467 err
|= control(file
, "dest reg encoding", m_three_source_reg_encoding
,
468 gen8_dst_3src_type(inst
), NULL
);
474 src_align1_region(FILE *file
, unsigned vert_stride
, unsigned _width
,
475 unsigned horiz_stride
)
479 err
|= control(file
, "vert stride", m_vert_stride
, vert_stride
, NULL
);
481 err
|= control(file
, "width", width
, _width
, NULL
);
483 err
|= control(file
, "horiz_stride", m_horiz_stride
, horiz_stride
, NULL
);
489 src_swizzle(FILE *file
, unsigned x
, unsigned y
, unsigned z
, unsigned w
)
493 /* Three kinds of swizzle display:
494 * - identity - nothing printed
495 * - 1->all - print the single channel
496 * - 1->1 - print the mapping
498 if (x
== BRW_CHANNEL_X
&&
499 y
== BRW_CHANNEL_Y
&&
500 z
== BRW_CHANNEL_Z
&&
501 w
== BRW_CHANNEL_W
) {
502 ; /* Print nothing */
503 } else if (x
== y
&& x
== z
&& x
== w
) {
505 err
|= control(file
, "channel select", m_chan_sel
, x
, NULL
);
508 err
|= control(file
, "channel select", m_chan_sel
, x
, NULL
);
509 err
|= control(file
, "channel select", m_chan_sel
, y
, NULL
);
510 err
|= control(file
, "channel select", m_chan_sel
, z
, NULL
);
511 err
|= control(file
, "channel select", m_chan_sel
, w
, NULL
);
517 is_logic_instruction(unsigned opcode
)
519 return (opcode
== BRW_OPCODE_AND
||
520 opcode
== BRW_OPCODE_NOT
||
521 opcode
== BRW_OPCODE_OR
||
522 opcode
== BRW_OPCODE_XOR
);
526 src_da1(FILE *file
, unsigned opcode
, unsigned type
, unsigned reg_file
,
527 unsigned vert_stride
, unsigned _width
, unsigned horiz_stride
,
528 unsigned reg_num
, unsigned sub_reg_num
, unsigned _abs
, unsigned negate
)
531 err
|= control(file
, "negate", is_logic_instruction(opcode
) ?
532 m_bitnot
: m_negate
, negate
, NULL
);
533 err
|= control(file
, "abs", m_abs
, _abs
, NULL
);
535 err
|= reg(file
, reg_file
, reg_num
);
539 format(file
, ".%d", sub_reg_num
/ reg_type_size
[type
]); /* use formal style like spec */
540 src_align1_region(file
, vert_stride
, _width
, horiz_stride
);
541 err
|= control(file
, "src reg encoding", m_reg_encoding
, type
, NULL
);
550 unsigned vert_stride
,
561 err
|= control(file
, "negate", is_logic_instruction(opcode
) ?
562 m_bitnot
: m_negate
, negate
, NULL
);
563 err
|= control(file
, "abs", m_abs
, _abs
, NULL
);
565 err
|= reg(file
, reg_file
, _reg_nr
);
569 /* bit4 for subreg number byte addressing. Make this same meaning as
570 * in da1 case, so output looks consistent.
572 format(file
, ".%d", 16 / reg_type_size
[_reg_type
]);
574 err
|= control(file
, "vert stride", m_vert_stride
, vert_stride
, NULL
);
575 string(file
, ",4,1>");
577 * Three kinds of swizzle display:
578 * identity - nothing printed
579 * 1->all - print the single channel
580 * 1->1 - print the mapping
582 if (swz_x
== BRW_CHANNEL_X
&&
583 swz_y
== BRW_CHANNEL_Y
&&
584 swz_z
== BRW_CHANNEL_Z
&&
585 swz_w
== BRW_CHANNEL_W
) {
586 ; /* Print nothing */
587 } else if (swz_x
== swz_y
&& swz_x
== swz_z
&& swz_x
== swz_w
) {
589 err
|= control(file
, "channel select", m_chan_sel
, swz_x
, NULL
);
592 err
|= control(file
, "channel select", m_chan_sel
, swz_x
, NULL
);
593 err
|= control(file
, "channel select", m_chan_sel
, swz_y
, NULL
);
594 err
|= control(file
, "channel select", m_chan_sel
, swz_z
, NULL
);
595 err
|= control(file
, "channel select", m_chan_sel
, swz_w
, NULL
);
597 err
|= control(file
, "src da16 reg type", m_reg_encoding
, _reg_type
, NULL
);
602 src0_3src(FILE *file
, struct gen8_instruction
*inst
)
605 unsigned swiz
= gen8_src0_3src_swizzle(inst
);
606 unsigned swz_x
= (swiz
>> 0) & 0x3;
607 unsigned swz_y
= (swiz
>> 2) & 0x3;
608 unsigned swz_z
= (swiz
>> 4) & 0x3;
609 unsigned swz_w
= (swiz
>> 6) & 0x3;
611 err
|= control(file
, "negate", m_negate
, gen8_src0_3src_negate(inst
), NULL
);
612 err
|= control(file
, "abs", m_abs
, gen8_src0_3src_abs(inst
), NULL
);
614 err
|= reg(file
, BRW_GENERAL_REGISTER_FILE
, gen8_src0_3src_reg_nr(inst
));
617 if (gen8_src0_3src_subreg_nr(inst
))
618 format(file
, ".%d", gen8_src0_3src_subreg_nr(inst
));
619 if (gen8_src0_3src_rep_ctrl(inst
))
620 string(file
, "<0,1,0>");
622 string(file
, "<4,4,1>");
623 err
|= control(file
, "src da16 reg type", m_three_source_reg_encoding
,
624 gen8_src_3src_type(inst
), NULL
);
625 err
|= src_swizzle(file
, swz_x
, swz_y
, swz_z
, swz_w
);
630 src1_3src(FILE *file
, struct gen8_instruction
*inst
)
633 unsigned swiz
= gen8_src1_3src_swizzle(inst
);
634 unsigned swz_x
= (swiz
>> 0) & 0x3;
635 unsigned swz_y
= (swiz
>> 2) & 0x3;
636 unsigned swz_z
= (swiz
>> 4) & 0x3;
637 unsigned swz_w
= (swiz
>> 6) & 0x3;
638 unsigned src1_subreg_nr
= gen8_src1_3src_subreg_nr(inst
);
640 err
|= control(file
, "negate", m_negate
, gen8_src1_3src_negate(inst
), NULL
);
641 err
|= control(file
, "abs", m_abs
, gen8_src1_3src_abs(inst
), NULL
);
643 err
|= reg(file
, BRW_GENERAL_REGISTER_FILE
, gen8_src1_3src_reg_nr(inst
));
647 format(file
, ".%d", src1_subreg_nr
);
648 if (gen8_src1_3src_rep_ctrl(inst
))
649 string(file
, "<0,1,0>");
651 string(file
, "<4,4,1>");
652 err
|= control(file
, "src da16 reg type", m_three_source_reg_encoding
,
653 gen8_src_3src_type(inst
), NULL
);
654 err
|= src_swizzle(file
, swz_x
, swz_y
, swz_z
, swz_w
);
659 src2_3src(FILE *file
, struct gen8_instruction
*inst
)
662 unsigned swiz
= gen8_src2_3src_swizzle(inst
);
663 unsigned swz_x
= (swiz
>> 0) & 0x3;
664 unsigned swz_y
= (swiz
>> 2) & 0x3;
665 unsigned swz_z
= (swiz
>> 4) & 0x3;
666 unsigned swz_w
= (swiz
>> 6) & 0x3;
668 err
|= control(file
, "negate", m_negate
, gen8_src2_3src_negate(inst
), NULL
);
669 err
|= control(file
, "abs", m_abs
, gen8_src2_3src_abs(inst
), NULL
);
671 err
|= reg(file
, BRW_GENERAL_REGISTER_FILE
, gen8_src2_3src_reg_nr(inst
));
674 if (gen8_src2_3src_subreg_nr(inst
))
675 format(file
, ".%d", gen8_src2_3src_subreg_nr(inst
));
676 if (gen8_src2_3src_rep_ctrl(inst
))
677 string(file
, "<0,1,0>");
679 string(file
, "<4,4,1>");
680 err
|= control(file
, "src da16 reg type", m_three_source_reg_encoding
,
681 gen8_src_3src_type(inst
), NULL
);
682 err
|= src_swizzle(file
, swz_x
, swz_y
, swz_z
, swz_w
);
687 imm(FILE *file
, unsigned type
, struct gen8_instruction
*inst
)
690 case BRW_HW_REG_TYPE_UD
:
691 format(file
, "0x%08xUD", gen8_src1_imm_ud(inst
));
693 case BRW_HW_REG_TYPE_D
:
694 format(file
, "%dD", gen8_src1_imm_d(inst
));
696 case BRW_HW_REG_TYPE_UW
:
697 format(file
, "0x%04xUW", (uint16_t) gen8_src1_imm_ud(inst
));
699 case BRW_HW_REG_TYPE_W
:
700 format(file
, "%dW", (int16_t) gen8_src1_imm_d(inst
));
702 case BRW_HW_REG_IMM_TYPE_UV
:
703 format(file
, "0x%08xUV", gen8_src1_imm_ud(inst
));
705 case BRW_HW_REG_IMM_TYPE_VF
:
706 format(file
, "Vector Float");
708 case BRW_HW_REG_IMM_TYPE_V
:
709 format(file
, "0x%08xV", gen8_src1_imm_ud(inst
));
711 case BRW_HW_REG_TYPE_F
:
712 format(file
, "%-gF", gen8_src1_imm_f(inst
));
714 case GEN8_HW_REG_IMM_TYPE_DF
:
715 case GEN8_HW_REG_IMM_TYPE_HF
:
716 assert(!"Not implemented yet");
723 src0(FILE *file
, struct gen8_instruction
*inst
)
725 if (gen8_src0_reg_file(inst
) == BRW_IMMEDIATE_VALUE
)
726 return imm(file
, gen8_src0_reg_type(inst
), inst
);
728 if (gen8_access_mode(inst
) == BRW_ALIGN_1
) {
729 assert(gen8_src0_address_mode(inst
) == BRW_ADDRESS_DIRECT
);
732 gen8_src0_reg_type(inst
),
733 gen8_src0_reg_file(inst
),
734 gen8_src0_vert_stride(inst
),
735 gen8_src0_da1_width(inst
),
736 gen8_src0_da1_hstride(inst
),
737 gen8_src0_da_reg_nr(inst
),
738 gen8_src0_da1_subreg_nr(inst
),
740 gen8_src0_negate(inst
));
742 assert(gen8_src0_address_mode(inst
) == BRW_ADDRESS_DIRECT
);
743 return src_da16(file
,
745 gen8_src0_reg_type(inst
),
746 gen8_src0_reg_file(inst
),
747 gen8_src0_vert_stride(inst
),
748 gen8_src0_da_reg_nr(inst
),
749 gen8_src0_da16_subreg_nr(inst
),
751 gen8_src0_negate(inst
),
752 gen8_src0_da16_swiz_x(inst
),
753 gen8_src0_da16_swiz_y(inst
),
754 gen8_src0_da16_swiz_z(inst
),
755 gen8_src0_da16_swiz_w(inst
));
760 src1(FILE *file
, struct gen8_instruction
*inst
)
762 if (gen8_src1_reg_file(inst
) == BRW_IMMEDIATE_VALUE
)
763 return imm(file
, gen8_src1_reg_type(inst
), inst
);
765 if (gen8_access_mode(inst
) == BRW_ALIGN_1
) {
766 assert(gen8_src1_address_mode(inst
) == BRW_ADDRESS_DIRECT
);
769 gen8_src1_reg_type(inst
),
770 gen8_src1_reg_file(inst
),
771 gen8_src1_vert_stride(inst
),
772 gen8_src1_da1_width(inst
),
773 gen8_src1_da1_hstride(inst
),
774 gen8_src1_da_reg_nr(inst
),
775 gen8_src1_da1_subreg_nr(inst
),
777 gen8_src1_negate(inst
));
779 assert(gen8_src1_address_mode(inst
) == BRW_ADDRESS_DIRECT
);
780 return src_da16(file
,
782 gen8_src1_reg_type(inst
),
783 gen8_src1_reg_file(inst
),
784 gen8_src1_vert_stride(inst
),
785 gen8_src1_da_reg_nr(inst
),
786 gen8_src1_da16_subreg_nr(inst
),
788 gen8_src1_negate(inst
),
789 gen8_src1_da16_swiz_x(inst
),
790 gen8_src1_da16_swiz_y(inst
),
791 gen8_src1_da16_swiz_z(inst
),
792 gen8_src1_da16_swiz_w(inst
));
797 qtr_ctrl(FILE *file
, struct gen8_instruction
*inst
)
799 int qtr_ctl
= gen8_qtr_control(inst
);
800 int exec_size
= 1 << gen8_exec_size(inst
);
802 if (exec_size
== 8) {
817 } else if (exec_size
== 16) {
827 gen8_disassemble_inst(FILE *file
, struct gen8_instruction
*inst
, int gen
)
832 const int opcode
= gen8_opcode(inst
);
834 if (gen8_pred_control(inst
)) {
836 err
|= control(file
, "predicate inverse", m_pred_inv
, gen8_pred_inv(inst
), NULL
);
837 format(file
, "f%d", gen8_flag_reg_nr(inst
));
838 if (gen8_flag_subreg_nr(inst
))
839 format(file
, ".%d", gen8_flag_subreg_nr(inst
));
840 if (gen8_access_mode(inst
) == BRW_ALIGN_1
) {
841 err
|= control(file
, "predicate control align1", m_pred_ctrl_align1
,
842 gen8_pred_control(inst
), NULL
);
844 err
|= control(file
, "predicate control align16", m_pred_ctrl_align16
,
845 gen8_pred_control(inst
), NULL
);
850 err
|= print_opcode(file
, opcode
);
851 err
|= control(file
, "saturate", m_saturate
, gen8_saturate(inst
), NULL
);
852 err
|= control(file
, "debug control", m_debug_ctrl
, gen8_debug_control(inst
), NULL
);
854 if (opcode
== BRW_OPCODE_MATH
) {
856 err
|= control(file
, "function", m_math_function
, gen8_math_function(inst
),
858 } else if (opcode
!= BRW_OPCODE_SEND
&& opcode
!= BRW_OPCODE_SENDC
) {
859 err
|= control(file
, "conditional modifier", m_conditional_modifier
,
860 gen8_cond_modifier(inst
), NULL
);
862 /* If we're using the conditional modifier, print the flag reg used. */
863 if (gen8_cond_modifier(inst
) && opcode
!= BRW_OPCODE_SEL
) {
864 format(file
, ".f%d", gen8_flag_reg_nr(inst
));
865 if (gen8_flag_subreg_nr(inst
))
866 format(file
, ".%d", gen8_flag_subreg_nr(inst
));
870 if (opcode
!= BRW_OPCODE_NOP
) {
872 err
|= control(file
, "execution size", m_exec_size
, gen8_exec_size(inst
), NULL
);
876 if (m_opcode
[opcode
].nsrc
== 3) {
878 err
|= dest_3src(file
, inst
);
881 err
|= src0_3src(file
, inst
);
884 err
|= src1_3src(file
, inst
);
887 err
|= src2_3src(file
, inst
);
889 if (opcode
== BRW_OPCODE_ENDIF
|| opcode
== BRW_OPCODE_WHILE
) {
891 format(file
, "JIP: %d", gen8_jip(inst
));
892 } else if (opcode
== BRW_OPCODE_IF
||
893 opcode
== BRW_OPCODE_ELSE
||
894 opcode
== BRW_OPCODE_BREAK
||
895 opcode
== BRW_OPCODE_CONTINUE
||
896 opcode
== BRW_OPCODE_HALT
) {
898 format(file
, "JIP: %d", gen8_jip(inst
));
900 format(file
, "UIP: %d", gen8_uip(inst
));
902 if (m_opcode
[opcode
].ndst
> 0) {
904 err
|= dest(file
, inst
);
906 if (m_opcode
[opcode
].nsrc
> 0) {
908 err
|= src0(file
, inst
);
910 if (m_opcode
[opcode
].nsrc
> 1) {
912 err
|= src1(file
, inst
);
917 if (opcode
== BRW_OPCODE_SEND
|| opcode
== BRW_OPCODE_SENDC
) {
918 const int sfid
= gen8_sfid(inst
);
924 err
|= control(file
, "SFID", m_sfid
, sfid
, &space
);
927 case BRW_SFID_SAMPLER
:
928 format(file
, " (%d, %d, %d, %d)",
929 gen8_binding_table_index(inst
),
931 gen8_sampler_msg_type(inst
),
932 gen8_sampler_simd_mode(inst
));
937 err
|= control(file
, "urb opcode", m_urb_opcode
,
938 gen8_urb_opcode(inst
), &space
);
939 err
|= control(file
, "urb interleave", m_urb_interleave
,
940 gen8_urb_interleave(inst
), &space
);
941 format(file
, " %d %d",
942 gen8_urb_global_offset(inst
), gen8_urb_per_slot_offset(inst
));
945 case GEN6_SFID_DATAPORT_RENDER_CACHE
: {
946 err
|= control(file
, "rt message", m_rt_opcode
,
947 gen8_rt_message_type(inst
), &space
);
948 format(file
, " %s%sSurface = %d",
949 gen8_rt_slot_group(inst
) ? "Hi " : "",
950 gen8_rt_last(inst
) ? "LastRT " : "",
951 gen8_binding_table_index(inst
));
955 case GEN6_SFID_DATAPORT_SAMPLER_CACHE
:
956 case GEN6_SFID_DATAPORT_CONSTANT_CACHE
:
957 case GEN7_SFID_DATAPORT_DATA_CACHE
:
958 format(file
, " (%d, 0x%x)",
959 gen8_binding_table_index(inst
),
960 gen8_function_control(inst
));
963 case HSW_SFID_DATAPORT_DATA_CACHE_1
:
964 err
|= control(file
, "DP DC1 message type",
965 dp_dc1_msg_type
, gen8_dp_message_type(inst
), &space
);
966 format(file
, ", Surface = %d, ", gen8_binding_table_index(inst
));
967 switch (gen8_dp_message_type(inst
)) {
968 case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP
:
969 case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP
:
970 case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP
:
971 format(file
, "SIMD%d,",
972 (gen8_dp_message_control(inst
) & (1 << 4)) ? 8 : 16);
974 case HSW_DATAPORT_DC_PORT1_UNTYPED_ATOMIC_OP_SIMD4X2
:
975 case HSW_DATAPORT_DC_PORT1_TYPED_ATOMIC_OP_SIMD4X2
:
976 case HSW_DATAPORT_DC_PORT1_ATOMIC_COUNTER_OP_SIMD4X2
:
977 control(file
, "atomic op", aop
,
978 gen8_dp_message_control(inst
) & 0xf, &space
);
980 case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_READ
:
981 case HSW_DATAPORT_DC_PORT1_UNTYPED_SURFACE_WRITE
:
982 case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_READ
:
983 case HSW_DATAPORT_DC_PORT1_TYPED_SURFACE_WRITE
: {
984 static const char *simd_modes
[] = { "4x2", "16", "8" };
985 unsigned msg_ctrl
= gen8_dp_message_control(inst
);
986 format(file
, "SIMD%s, Mask = 0x%x",
987 simd_modes
[msg_ctrl
>> 4], msg_ctrl
& 0xf);
991 format(file
, "0x%x", gen8_dp_message_control(inst
));
996 format(file
, "unsupported shared function ID (%d)", sfid
);
1001 format(file
, "mlen %d", gen8_mlen(inst
));
1002 format(file
, " rlen %d", gen8_rlen(inst
));
1005 if (opcode
!= BRW_OPCODE_NOP
) {
1008 err
|= control(file
, "access mode", m_access_mode
, gen8_access_mode(inst
), &space
);
1009 err
|= control(file
, "mask control", m_maskctrl
, gen8_mask_control(inst
), &space
);
1010 err
|= control(file
, "DDClr", m_dep_clear
, gen8_no_dd_clear(inst
), &space
);
1011 err
|= control(file
, "DDChk", m_dep_check
, gen8_no_dd_check(inst
), &space
);
1013 err
|= qtr_ctrl(file
, inst
);
1015 err
|= control(file
, "thread control", m_thread_ctrl
, gen8_thread_control(inst
), &space
);
1016 err
|= control(file
, "acc write control", m_accwr
, gen8_acc_wr_control(inst
), &space
);
1017 if (opcode
== BRW_OPCODE_SEND
|| opcode
== BRW_OPCODE_SENDC
)
1018 err
|= control(file
, "end of thread", m_eot
, gen8_eot(inst
), &space
);