2 * Mesa 3-D graphics library
4 * Copyright (C) 2014 LunarG, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * Chia-I Wu <olv@lunarg.com>
29 #include "genhw/genhw.h"
30 #include "toy_compiler.h"
32 #define DISASM_PRINTER_BUFFER_SIZE 256
33 #define DISASM_PRINTER_COLUMN_WIDTH 16
35 struct disasm_printer
{
36 char buf
[DISASM_PRINTER_BUFFER_SIZE
];
40 struct disasm_operand
{
47 unsigned addr_subreg
:3;
51 struct disasm_dst_operand
{
52 struct disasm_operand base
;
54 unsigned horz_stride
:2;
58 struct disasm_src_operand
{
59 struct disasm_operand base
;
61 unsigned vert_stride
:4;
63 unsigned horz_stride
:2;
73 const struct ilo_dev_info
*dev
;
79 unsigned access_mode
:1;
83 unsigned thread_ctrl
:2;
88 unsigned cond_modifier
:4;
92 unsigned acc_wr_ctrl
:1;
94 unsigned debug_ctrl
:1;
100 unsigned flag_subreg
:1;
102 struct disasm_dst_operand dst
;
103 struct disasm_src_operand src0
;
104 struct disasm_src_operand src1
;
106 struct disasm_src_operand src2
;
111 static const struct {
114 } disasm_opcode_table
[128] = {
115 [GEN6_OPCODE_ILLEGAL
] = { "illegal", 0 },
116 [GEN6_OPCODE_MOV
] = { "mov", 1 },
117 [GEN6_OPCODE_SEL
] = { "sel", 2 },
118 [GEN6_OPCODE_MOVI
] = { "movi", 1 },
119 [GEN6_OPCODE_NOT
] = { "not", 1 },
120 [GEN6_OPCODE_AND
] = { "and", 2 },
121 [GEN6_OPCODE_OR
] = { "or", 2 },
122 [GEN6_OPCODE_XOR
] = { "xor", 2 },
123 [GEN6_OPCODE_SHR
] = { "shr", 2 },
124 [GEN6_OPCODE_SHL
] = { "shl", 2 },
125 [GEN6_OPCODE_DIM
] = { "dim", 1 },
126 [GEN6_OPCODE_ASR
] = { "asr", 2 },
127 [GEN6_OPCODE_CMP
] = { "cmp", 2 },
128 [GEN6_OPCODE_CMPN
] = { "cmpn", 2 },
129 [GEN7_OPCODE_CSEL
] = { "csel", 3 },
130 [GEN7_OPCODE_F32TO16
] = { "f32to16", 1 },
131 [GEN7_OPCODE_F16TO32
] = { "f16to32", 1 },
132 [GEN7_OPCODE_BFREV
] = { "bfrev", 1 },
133 [GEN7_OPCODE_BFE
] = { "bfe", 3 },
134 [GEN7_OPCODE_BFI1
] = { "bfi1", 2 },
135 [GEN7_OPCODE_BFI2
] = { "bfi2", 3 },
136 [GEN6_OPCODE_JMPI
] = { "jmpi", 1 },
137 [GEN7_OPCODE_BRD
] = { "brd", 1 },
138 [GEN6_OPCODE_IF
] = { "if", 2 },
139 [GEN7_OPCODE_BRC
] = { "brc", 1 },
140 [GEN6_OPCODE_ELSE
] = { "else", 1 },
141 [GEN6_OPCODE_ENDIF
] = { "endif", 0 },
142 [GEN6_OPCODE_CASE
] = { "case", 2 },
143 [GEN6_OPCODE_WHILE
] = { "while", 1 },
144 [GEN6_OPCODE_BREAK
] = { "break", 1 },
145 [GEN6_OPCODE_CONT
] = { "cont", 1 },
146 [GEN6_OPCODE_HALT
] = { "halt", 1 },
147 [GEN75_OPCODE_CALLA
] = { "calla", 1 },
148 [GEN6_OPCODE_CALL
] = { "call", 1 },
149 [GEN6_OPCODE_RETURN
] = { "return", 1 },
150 [GEN6_OPCODE_WAIT
] = { "wait", 1 },
151 [GEN6_OPCODE_SEND
] = { "send", 1 },
152 [GEN6_OPCODE_SENDC
] = { "sendc", 1 },
153 [GEN6_OPCODE_MATH
] = { "math", 2 },
154 [GEN6_OPCODE_ADD
] = { "add", 2 },
155 [GEN6_OPCODE_MUL
] = { "mul", 2 },
156 [GEN6_OPCODE_AVG
] = { "avg", 2 },
157 [GEN6_OPCODE_FRC
] = { "frc", 1 },
158 [GEN6_OPCODE_RNDU
] = { "rndu", 1 },
159 [GEN6_OPCODE_RNDD
] = { "rndd", 1 },
160 [GEN6_OPCODE_RNDE
] = { "rnde", 1 },
161 [GEN6_OPCODE_RNDZ
] = { "rndz", 1 },
162 [GEN6_OPCODE_MAC
] = { "mac", 2 },
163 [GEN6_OPCODE_MACH
] = { "mach", 2 },
164 [GEN6_OPCODE_LZD
] = { "lzd", 1 },
165 [GEN7_OPCODE_FBH
] = { "fbh", 1 },
166 [GEN7_OPCODE_FBL
] = { "fbl", 1 },
167 [GEN7_OPCODE_CBIT
] = { "cbit", 1 },
168 [GEN7_OPCODE_ADDC
] = { "addc", 2 },
169 [GEN7_OPCODE_SUBB
] = { "subb", 2 },
170 [GEN6_OPCODE_SAD2
] = { "sad2", 2 },
171 [GEN6_OPCODE_SADA2
] = { "sada2", 2 },
172 [GEN6_OPCODE_DP4
] = { "dp4", 2 },
173 [GEN6_OPCODE_DPH
] = { "dph", 2 },
174 [GEN6_OPCODE_DP3
] = { "dp3", 2 },
175 [GEN6_OPCODE_DP2
] = { "dp2", 2 },
176 [GEN6_OPCODE_LINE
] = { "line", 2 },
177 [GEN6_OPCODE_PLN
] = { "pln", 2 },
178 [GEN6_OPCODE_MAD
] = { "mad", 3 },
179 [GEN6_OPCODE_LRP
] = { "lrp", 3 },
180 [GEN6_OPCODE_NOP
] = { "nop", 0 },
184 disasm_inst_decode_dw0_gen6(struct disasm_inst
*inst
, uint32_t dw0
)
186 inst
->opcode
= GEN_EXTRACT(dw0
, GEN6_INST_OPCODE
);
188 switch (inst
->opcode
) {
190 inst
->has_jip
= true;
191 inst
->has_uip
= (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7));
193 case GEN6_OPCODE_BREAK
:
194 case GEN6_OPCODE_CONT
:
195 case GEN6_OPCODE_HALT
:
196 inst
->has_uip
= true;
198 case GEN6_OPCODE_JMPI
:
199 case GEN7_OPCODE_BRD
:
200 case GEN7_OPCODE_BRC
:
201 case GEN6_OPCODE_ELSE
:
202 case GEN6_OPCODE_ENDIF
:
203 case GEN6_OPCODE_CASE
:
204 case GEN6_OPCODE_WHILE
:
205 case GEN75_OPCODE_CALLA
:
206 case GEN6_OPCODE_CALL
:
207 case GEN6_OPCODE_RETURN
:
208 inst
->has_jip
= true;
214 inst
->access_mode
= GEN_EXTRACT(dw0
, GEN6_INST_ACCESSMODE
);
215 inst
->mask_ctrl
= GEN_EXTRACT(dw0
, GEN6_INST_MASKCTRL
);
216 inst
->dep_ctrl
= GEN_EXTRACT(dw0
, GEN6_INST_DEPCTRL
);
217 inst
->qtr_ctrl
= GEN_EXTRACT(dw0
, GEN6_INST_QTRCTRL
);
218 inst
->thread_ctrl
= GEN_EXTRACT(dw0
, GEN6_INST_THREADCTRL
);
219 inst
->pred_ctrl
= GEN_EXTRACT(dw0
, GEN6_INST_PREDCTRL
);
221 inst
->pred_inv
= (bool) (dw0
& GEN6_INST_PREDINV
);
223 inst
->exec_size
= GEN_EXTRACT(dw0
, GEN6_INST_EXECSIZE
);
225 switch (inst
->opcode
) {
226 case GEN6_OPCODE_SEND
:
227 case GEN6_OPCODE_SENDC
:
228 inst
->sfid
= GEN_EXTRACT(dw0
, GEN6_INST_SFID
);
230 case GEN6_OPCODE_MATH
:
231 inst
->fc
= GEN_EXTRACT(dw0
, GEN6_INST_FC
);
234 inst
->cond_modifier
= GEN_EXTRACT(dw0
, GEN6_INST_CONDMODIFIER
);
238 inst
->acc_wr_ctrl
= (bool) (dw0
& GEN6_INST_ACCWRCTRL
);
239 inst
->cmpt_ctrl
= (bool) (dw0
& GEN6_INST_CMPTCTRL
);
240 inst
->debug_ctrl
= (bool) (dw0
& GEN6_INST_DEBUGCTRL
);
241 inst
->saturate
= (bool) (dw0
& GEN6_INST_SATURATE
);
245 disasm_inst_jip_in_dw1_high_gen6(const struct disasm_inst
*inst
)
247 return (ilo_dev_gen(inst
->dev
) == ILO_GEN(6) &&
248 inst
->has_jip
&& !inst
->has_uip
);
252 disasm_inst_decode_dw1_gen6(struct disasm_inst
*inst
, uint32_t dw1
)
254 inst
->dst
.base
.file
= GEN_EXTRACT(dw1
, GEN6_INST_DST_FILE
);
255 inst
->dst
.base
.type
= GEN_EXTRACT(dw1
, GEN6_INST_DST_TYPE
);
256 inst
->src0
.base
.file
= GEN_EXTRACT(dw1
, GEN6_INST_SRC0_FILE
);
257 inst
->src0
.base
.type
= GEN_EXTRACT(dw1
, GEN6_INST_SRC0_TYPE
);
258 inst
->src1
.base
.file
= GEN_EXTRACT(dw1
, GEN6_INST_SRC1_FILE
);
259 inst
->src1
.base
.type
= GEN_EXTRACT(dw1
, GEN6_INST_SRC1_TYPE
);
261 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7))
262 inst
->nib_ctrl
= (bool) (dw1
& GEN7_INST_NIBCTRL
);
264 if (disasm_inst_jip_in_dw1_high_gen6(inst
)) {
265 inst
->u
.imm32
= dw1
>> 16;
269 inst
->dst
.base
.addr_mode
= GEN_EXTRACT(dw1
, GEN6_INST_DST_ADDRMODE
);
271 if (inst
->dst
.base
.addr_mode
== GEN6_ADDRMODE_DIRECT
) {
272 inst
->dst
.base
.reg
= GEN_EXTRACT(dw1
, GEN6_INST_DST_REG
);
274 if (inst
->access_mode
== GEN6_ALIGN_1
) {
275 inst
->dst
.base
.subreg
= GEN_EXTRACT(dw1
, GEN6_INST_DST_SUBREG
);
277 inst
->dst
.base
.subreg
=
278 GEN_EXTRACT(dw1
, GEN6_INST_DST_SUBREG_ALIGN16
) <<
279 GEN6_INST_DST_SUBREG_ALIGN16__SHR
;
282 inst
->dst
.base
.addr_subreg
= GEN_EXTRACT(dw1
, GEN6_INST_DST_ADDR_SUBREG
);
284 if (inst
->access_mode
== GEN6_ALIGN_1
) {
285 inst
->dst
.base
.addr_imm
= GEN_EXTRACT(dw1
, GEN6_INST_DST_ADDR_IMM
);
287 inst
->dst
.base
.addr_imm
= GEN_EXTRACT(dw1
,
288 GEN6_INST_DST_ADDR_IMM_ALIGN16
) <<
289 GEN6_INST_DST_ADDR_IMM_ALIGN16__SHR
;
293 inst
->dst
.horz_stride
= GEN_EXTRACT(dw1
, GEN6_INST_DST_HORZSTRIDE
);
295 if (inst
->access_mode
== GEN6_ALIGN_1
)
296 inst
->dst
.writemask
= 0xf;
298 inst
->dst
.writemask
= GEN_EXTRACT(dw1
, GEN6_INST_DST_WRITEMASK
);
302 disasm_inst_decode_dw2_dw3_gen6(struct disasm_inst
*inst
,
303 uint32_t dw2
, uint32_t dw3
)
307 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7))
308 inst
->flag_reg
= GEN_EXTRACT(dw2
, GEN7_INST_FLAG_REG
);
310 inst
->flag_subreg
= GEN_EXTRACT(dw2
, GEN6_INST_FLAG_SUBREG
);
312 if (inst
->src0
.base
.file
== GEN6_FILE_IMM
||
313 inst
->src1
.base
.file
== GEN6_FILE_IMM
) {
315 if (!disasm_inst_jip_in_dw1_high_gen6(inst
))
321 for (i
= 0; i
< count
; i
++) {
322 struct disasm_src_operand
*src
= (i
== 0) ? &inst
->src0
: &inst
->src1
;
323 const uint32_t dw
= (i
== 0) ? dw2
: dw3
;
325 src
->base
.addr_mode
= GEN_EXTRACT(dw
, GEN6_INST_SRC_ADDRMODE
);
327 if (src
->base
.addr_mode
== GEN6_ADDRMODE_DIRECT
) {
328 src
->base
.reg
= GEN_EXTRACT(dw
, GEN6_INST_SRC_REG
);
330 if (inst
->access_mode
== GEN6_ALIGN_1
) {
331 src
->base
.subreg
= GEN_EXTRACT(dw
, GEN6_INST_SRC_SUBREG
);
333 src
->base
.subreg
= GEN_EXTRACT(dw
, GEN6_INST_SRC_SUBREG_ALIGN16
) <<
334 GEN6_INST_SRC_SUBREG_ALIGN16__SHR
;
337 src
->base
.addr_subreg
= GEN_EXTRACT(dw
, GEN6_INST_SRC_ADDR_SUBREG
);
339 if (inst
->access_mode
== GEN6_ALIGN_1
) {
340 src
->base
.addr_imm
= GEN_EXTRACT(dw
, GEN6_INST_SRC_ADDR_IMM
);
343 GEN_EXTRACT(dw
, GEN6_INST_SRC_ADDR_IMM_ALIGN16
) <<
344 GEN6_INST_SRC_ADDR_IMM_ALIGN16__SHR
;
348 src
->vert_stride
= GEN_EXTRACT(dw
, GEN6_INST_SRC_VERTSTRIDE
);
350 if (inst
->access_mode
== GEN6_ALIGN_1
) {
351 src
->width
= GEN_EXTRACT(dw
, GEN6_INST_SRC_WIDTH
);
352 src
->horz_stride
= GEN_EXTRACT(dw
, GEN6_INST_SRC_HORZSTRIDE
);
354 src
->swizzle_x
= GEN6_SWIZZLE_X
;
355 src
->swizzle_y
= GEN6_SWIZZLE_Y
;
356 src
->swizzle_z
= GEN6_SWIZZLE_Z
;
357 src
->swizzle_w
= GEN6_SWIZZLE_W
;
359 src
->width
= GEN6_WIDTH_4
;
360 src
->horz_stride
= GEN6_HORZSTRIDE_1
;
362 src
->swizzle_x
= GEN_EXTRACT(dw
, GEN6_INST_SRC_SWIZZLE_X
);
363 src
->swizzle_y
= GEN_EXTRACT(dw
, GEN6_INST_SRC_SWIZZLE_Y
);
364 src
->swizzle_z
= GEN_EXTRACT(dw
, GEN6_INST_SRC_SWIZZLE_Z
);
365 src
->swizzle_w
= GEN_EXTRACT(dw
, GEN6_INST_SRC_SWIZZLE_W
);
368 src
->negate
= (bool) (dw
& GEN6_INST_SRC_NEGATE
);
369 src
->absolute
= (bool) (dw
& GEN6_INST_SRC_ABSOLUTE
);
374 disasm_inst_decode_3src_dw1_gen6(struct disasm_inst
*inst
, uint32_t dw1
)
376 static unsigned type_mapping
[4] = {
377 [GEN7_TYPE_F_3SRC
] = GEN6_TYPE_F
,
378 [GEN7_TYPE_D_3SRC
] = GEN6_TYPE_D
,
379 [GEN7_TYPE_UD_3SRC
] = GEN6_TYPE_UD
,
380 [GEN7_TYPE_DF_3SRC
] = GEN7_TYPE_DF
,
383 inst
->flag_subreg
= GEN_EXTRACT(dw1
, GEN6_3SRC_FLAG_SUBREG
);
385 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) {
386 inst
->nib_ctrl
= (bool) (dw1
& GEN7_3SRC_NIBCTRL
);
387 inst
->flag_reg
= GEN_EXTRACT(dw1
, GEN7_3SRC_FLAG_REG
);
389 inst
->dst
.base
.file
= GEN6_FILE_GRF
;
390 inst
->dst
.base
.type
= GEN_EXTRACT(dw1
, GEN7_3SRC_DST_TYPE
);
391 inst
->dst
.base
.type
= type_mapping
[inst
->dst
.base
.type
];
393 inst
->src0
.base
.type
= GEN_EXTRACT(dw1
, GEN7_3SRC_SRC_TYPE
);
394 inst
->src0
.base
.type
= type_mapping
[inst
->src0
.base
.type
];
396 inst
->src1
.base
.type
= inst
->src0
.base
.type
;
397 inst
->u
.src2
.base
.type
= inst
->src0
.base
.type
;
399 inst
->dst
.base
.file
= (dw1
& GEN6_3SRC_DST_FILE_MRF
) ?
400 GEN6_FILE_MRF
: GEN6_FILE_GRF
;
401 inst
->dst
.base
.type
= GEN6_TYPE_F
;
403 inst
->src0
.base
.type
= GEN6_TYPE_F
;
404 inst
->src1
.base
.type
= GEN6_TYPE_F
;
405 inst
->u
.src2
.base
.type
= GEN6_TYPE_F
;
408 inst
->dst
.base
.addr_mode
= GEN6_ADDRMODE_DIRECT
;
409 inst
->dst
.base
.reg
= GEN_EXTRACT(dw1
, GEN6_3SRC_DST_REG
);
410 inst
->dst
.base
.subreg
= GEN_EXTRACT(dw1
, GEN6_3SRC_DST_SUBREG
) <<
411 GEN6_3SRC_DST_SUBREG__SHR
;
413 inst
->dst
.horz_stride
= GEN6_HORZSTRIDE_1
;
414 inst
->dst
.writemask
= GEN_EXTRACT(dw1
, GEN6_3SRC_DST_WRITEMASK
);
416 inst
->src0
.base
.file
= GEN6_FILE_GRF
;
417 inst
->src0
.negate
= (bool) (dw1
& GEN6_3SRC_SRC0_NEGATE
);
418 inst
->src0
.absolute
= (bool) (dw1
& GEN6_3SRC_SRC0_ABSOLUTE
);
419 inst
->src1
.base
.file
= GEN6_FILE_GRF
;
420 inst
->src1
.negate
= (bool) (dw1
& GEN6_3SRC_SRC1_NEGATE
);
421 inst
->src1
.absolute
= (bool) (dw1
& GEN6_3SRC_SRC1_ABSOLUTE
);
422 inst
->u
.src2
.base
.file
= GEN6_FILE_GRF
;
423 inst
->u
.src2
.negate
= (bool) (dw1
& GEN6_3SRC_SRC2_NEGATE
);
424 inst
->u
.src2
.absolute
= (bool) (dw1
& GEN6_3SRC_SRC2_ABSOLUTE
);
428 disasm_inst_decode_3src_dw2_dw3_gen6(struct disasm_inst
*inst
,
429 uint32_t dw2
, uint32_t dw3
)
431 const uint64_t qw
= (uint64_t) dw3
<< 32 | dw2
;
434 for (i
= 0; i
< 3; i
++) {
435 struct disasm_src_operand
*src
= (i
== 0) ? &inst
->src0
:
436 (i
== 1) ? &inst
->src1
:
438 const uint32_t dw
= (i
== 0) ? GEN_EXTRACT(qw
, GEN6_3SRC_SRC_0
) :
439 (i
== 1) ? GEN_EXTRACT(qw
, GEN6_3SRC_SRC_1
) :
440 GEN_EXTRACT(qw
, GEN6_3SRC_SRC_2
);
442 src
->base
.addr_mode
= GEN6_ADDRMODE_DIRECT
;
443 src
->base
.reg
= GEN_EXTRACT(dw
, GEN6_3SRC_SRC_REG
);
444 src
->base
.subreg
= GEN_EXTRACT(dw
, GEN6_3SRC_SRC_SUBREG
) <<
445 GEN6_3SRC_SRC_SUBREG__SHR
;
447 if (dw
& GEN6_3SRC_SRC_REPCTRL
) {
448 src
->vert_stride
= GEN6_VERTSTRIDE_0
;
449 src
->width
= GEN6_WIDTH_1
;
450 src
->horz_stride
= GEN6_HORZSTRIDE_0
;
452 src
->vert_stride
= GEN6_VERTSTRIDE_4
;
453 src
->width
= GEN6_WIDTH_4
;
454 src
->horz_stride
= GEN6_HORZSTRIDE_1
;
457 src
->swizzle_x
= GEN_EXTRACT(dw
, GEN6_3SRC_SRC_SWIZZLE_X
);
458 src
->swizzle_y
= GEN_EXTRACT(dw
, GEN6_3SRC_SRC_SWIZZLE_Y
);
459 src
->swizzle_z
= GEN_EXTRACT(dw
, GEN6_3SRC_SRC_SWIZZLE_Z
);
460 src
->swizzle_w
= GEN_EXTRACT(dw
, GEN6_3SRC_SRC_SWIZZLE_W
);
465 * When GEN6_INST_CMPTCTRL of DW0 is set, the instruction has 64 bits and is
466 * in EU_INSTRUCTION_COMPACT_TWO_SRC form. We should have expanded it to its
469 * Depending on the opcode, the 128-bits instruction is in one of the
472 * - EU_INSTRUCTION_BASIC_ONE_SRC
473 * - EU_INSTRUCTION_BASIC_TWO_SRC
474 * - EU_INSTRUCTION_BASIC_THREE_SRC
475 * - EU_INSTRUCTION_BRANCH_CONDITIONAL
476 * - EU_INSTRUCTION_BRANCH_ONE_SRC
477 * - EU_INSTRUCTION_BRANCH_TWO_SRC
478 * - EU_INSTRUCTION_ILLEGAL
479 * - EU_INSTRUCTION_MATH
480 * - EU_INSTRUCTION_NOP
481 * - EU_INSTRUCTION_SEND
483 * In EU_INSTRUCTION_BASIC_ONE_SRC form,
485 * - DW0 is EU_INSTRUCTION_HEADER
486 * - DW1 is EU_INSTRUCTION_OPERAND_CONTROLS
487 * - DW2 is Source 0 and EU_INSTRUCTION_FLAGS
488 * - DW3 is reserved unless Source 0 is an immediate
490 * All other forms except EU_INSTRUCTION_BASIC_THREE_SRC are quite compatible
491 * with EU_INSTRUCTION_BASIC_ONE_SRC.
494 disasm_inst_decode(struct disasm_inst
*inst
,
497 assert(!(dw
[0] & GEN6_INST_CMPTCTRL
));
499 disasm_inst_decode_dw0_gen6(inst
, dw
[0]);
501 if (disasm_opcode_table
[inst
->opcode
].src_count
== 3) {
502 disasm_inst_decode_3src_dw1_gen6(inst
, dw
[1]);
503 disasm_inst_decode_3src_dw2_dw3_gen6(inst
, dw
[2], dw
[3]);
505 disasm_inst_decode_dw1_gen6(inst
, dw
[1]);
506 disasm_inst_decode_dw2_dw3_gen6(inst
, dw
[2], dw
[3]);
511 disasm_inst_opcode(const struct disasm_inst
*inst
)
513 return (disasm_opcode_table
[inst
->opcode
].name
) ?
514 disasm_opcode_table
[inst
->opcode
].name
: "BAD";
518 disasm_inst_pred_ctrl(const struct disasm_inst
*inst
)
520 if (inst
->access_mode
== GEN6_ALIGN_1
) {
521 switch (inst
->pred_ctrl
) {
522 case GEN6_PREDCTRL_NORMAL
: return "";
523 case GEN6_PREDCTRL_ANYV
: return ".anyv";
524 case GEN6_PREDCTRL_ALLV
: return ".allv";
525 case GEN6_PREDCTRL_ANY2H
: return ".any2h";
526 case GEN6_PREDCTRL_ALL2H
: return ".all2h";
527 case GEN6_PREDCTRL_ANY4H
: return ".any4h";
528 case GEN6_PREDCTRL_ALL4H
: return ".all4h";
529 case GEN6_PREDCTRL_ANY8H
: return ".any8h";
530 case GEN6_PREDCTRL_ALL8H
: return ".all8h";
531 case GEN6_PREDCTRL_ANY16H
: return ".any16h";
532 case GEN6_PREDCTRL_ALL16H
: return ".all16h";
533 case GEN7_PREDCTRL_ANY32H
: return ".any32h";
534 case GEN7_PREDCTRL_ALL32H
: return ".all32h";
535 default: return ".BAD";
538 switch (inst
->pred_ctrl
) {
539 case GEN6_PREDCTRL_NORMAL
: return "";
540 case GEN6_PREDCTRL_X
: return ".x";
541 case GEN6_PREDCTRL_Y
: return ".y";
542 case GEN6_PREDCTRL_Z
: return ".z";
543 case GEN6_PREDCTRL_W
: return ".w";
544 default: return ".BAD";
550 disasm_inst_pred_inv(const struct disasm_inst
*inst
)
552 return (inst
->pred_inv
) ? '-' : '+';
556 disasm_inst_exec_size(const struct disasm_inst
*inst
)
558 switch (inst
->exec_size
) {
559 case GEN6_EXECSIZE_1
: return "1";
560 case GEN6_EXECSIZE_2
: return "2";
561 case GEN6_EXECSIZE_4
: return "4";
562 case GEN6_EXECSIZE_8
: return "8";
563 case GEN6_EXECSIZE_16
: return "16";
564 case GEN6_EXECSIZE_32
: return "32";
565 default: return "BAD";
570 disasm_inst_fc(const struct disasm_inst
*inst
)
572 assert(inst
->opcode
== GEN6_OPCODE_MATH
);
575 case GEN6_MATH_INV
: return "inv";
576 case GEN6_MATH_LOG
: return "log";
577 case GEN6_MATH_EXP
: return "exp";
578 case GEN6_MATH_SQRT
: return "sqrt";
579 case GEN6_MATH_RSQ
: return "rsq";
580 case GEN6_MATH_SIN
: return "sin";
581 case GEN6_MATH_COS
: return "cos";
582 case GEN6_MATH_FDIV
: return "fdiv";
583 case GEN6_MATH_POW
: return "pow";
584 case GEN6_MATH_INT_DIV
: return "int_div";
585 case GEN6_MATH_INT_DIV_QUOTIENT
: return "int_div_quotient";
586 case GEN6_MATH_INT_DIV_REMAINDER
: return "int_div_remainder";
587 default: return "BAD";
592 disasm_inst_sfid(const struct disasm_inst
*inst
)
594 assert(inst
->opcode
== GEN6_OPCODE_SEND
||
595 inst
->opcode
== GEN6_OPCODE_SENDC
);
597 switch (inst
->sfid
) {
598 case GEN6_SFID_NULL
: return "null";
599 case GEN6_SFID_SAMPLER
: return "sampler";
600 case GEN6_SFID_GATEWAY
: return "gateway";
601 case GEN6_SFID_DP_SAMPLER
: return "dp sampler";
602 case GEN6_SFID_DP_RC
: return "dp render";
603 case GEN6_SFID_URB
: return "urb";
604 case GEN6_SFID_SPAWNER
: return "spawner";
605 case GEN6_SFID_VME
: return "vme";
606 case GEN6_SFID_DP_CC
: return "dp const";
607 case GEN7_SFID_DP_DC0
: return "dp data 0";
608 case GEN7_SFID_PI
: return "pixel interp";
609 case GEN75_SFID_DP_DC1
: return "dp data 1";
610 default: return "BAD";
615 disasm_inst_cond_modifier(const struct disasm_inst
*inst
)
617 switch (inst
->cond_modifier
) {
618 case GEN6_COND_NONE
: return "";
619 case GEN6_COND_Z
: return ".z";
620 case GEN6_COND_NZ
: return ".nz";
621 case GEN6_COND_G
: return ".g";
622 case GEN6_COND_GE
: return ".ge";
623 case GEN6_COND_L
: return ".l";
624 case GEN6_COND_LE
: return ".le";
625 case GEN6_COND_O
: return ".o";
626 case GEN6_COND_U
: return ".u";
627 default: return ".BAD";
632 disasm_inst_debug_ctrl(const struct disasm_inst
*inst
)
634 return (inst
->debug_ctrl
) ? ".breakpoint" : "";
638 disasm_inst_saturate(const struct disasm_inst
*inst
)
640 return (inst
->saturate
) ? ".sat" : "";
644 disasm_inst_flag_reg(const struct disasm_inst
*inst
)
646 static const char *flag_names
[2][2] = {
651 return (inst
->flag_reg
<= 1 && inst
->flag_subreg
<= 1) ?
652 flag_names
[inst
->flag_reg
][inst
->flag_subreg
] : "fBAD";
656 disasm_inst_access_mode(const struct disasm_inst
*inst
)
658 switch (inst
->access_mode
) {
659 case GEN6_ALIGN_1
: return " align1";
660 case GEN6_ALIGN_16
: return " align16";
661 default: return " alignBAD";
666 disasm_inst_mask_ctrl(const struct disasm_inst
*inst
)
668 switch (inst
->mask_ctrl
) {
669 case GEN6_MASKCTRL_NORMAL
: return "";
670 case GEN6_MASKCTRL_NOMASK
: return " WE_all";
671 default: return " WE_BAD";
676 disasm_inst_dep_ctrl(const struct disasm_inst
*inst
)
678 switch (inst
->dep_ctrl
) {
679 case GEN6_DEPCTRL_NORMAL
: return "";
680 case GEN6_DEPCTRL_NODDCLR
: return " NoDDClr";
681 case GEN6_DEPCTRL_NODDCHK
: return " NoDDChk";
682 case GEN6_DEPCTRL_NEITHER
: return " NoDDClr,NoDDChk";
683 default: return " NoDDBAD";
688 disasm_inst_qtr_ctrl(const struct disasm_inst
*inst
)
690 switch (inst
->exec_size
) {
691 case GEN6_EXECSIZE_8
:
692 switch (inst
->qtr_ctrl
) {
693 case GEN6_QTRCTRL_1Q
: return " 1Q";
694 case GEN6_QTRCTRL_2Q
: return " 2Q";
695 case GEN6_QTRCTRL_3Q
: return " 3Q";
696 case GEN6_QTRCTRL_4Q
: return " 4Q";
697 default: return " BADQ";
700 case GEN6_EXECSIZE_16
:
701 switch (inst
->qtr_ctrl
) {
702 case GEN6_QTRCTRL_1H
: return " 1H";
703 case GEN6_QTRCTRL_2H
: return " 2H";
704 default: return " BADH";
714 disasm_inst_thread_ctrl(const struct disasm_inst
*inst
)
716 switch (inst
->thread_ctrl
) {
717 case GEN6_THREADCTRL_NORMAL
: return "";
718 case GEN6_THREADCTRL_ATOMIC
: return " atomic";
719 case GEN6_THREADCTRL_SWITCH
: return " switch";
720 default: return " BAD";
725 disasm_inst_acc_wr_ctrl(const struct disasm_inst
*inst
)
727 return (inst
->acc_wr_ctrl
) ? " AccWrEnable" : "";
731 disasm_inst_cmpt_ctrl(const struct disasm_inst
*inst
)
733 return (inst
->cmpt_ctrl
) ? " compacted" : "";
737 disasm_inst_eot(const struct disasm_inst
*inst
)
739 if (inst
->opcode
== GEN6_OPCODE_SEND
||
740 inst
->opcode
== GEN6_OPCODE_SENDC
)
741 return (inst
->u
.imm32
& GEN6_MSG_EOT
) ? " EOT" : "";
747 disasm_inst_file(const struct disasm_inst
*inst
,
748 const struct disasm_operand
*operand
,
751 switch (operand
->file
) {
753 switch (operand
->reg
& 0xf0) {
754 case GEN6_ARF_NULL
: *multi_regs
= false; return "null";
755 case GEN6_ARF_A0
: *multi_regs
= true; return "a";
756 case GEN6_ARF_ACC0
: *multi_regs
= true; return "acc";
757 case GEN6_ARF_F0
: *multi_regs
= true; return "f";
758 case GEN6_ARF_SR0
: *multi_regs
= true; return "sr";
759 case GEN6_ARF_CR0
: *multi_regs
= true; return "cr";
760 case GEN6_ARF_N0
: *multi_regs
= true; return "n";
761 case GEN6_ARF_IP
: *multi_regs
= false; return "ip";
762 case GEN6_ARF_TDR
: *multi_regs
= false; return "tdr";
763 case GEN7_ARF_TM0
: *multi_regs
= true; return "tm";
764 default: *multi_regs
= false; return "BAD";
767 case GEN6_FILE_GRF
: *multi_regs
= true; return "g";
768 case GEN6_FILE_MRF
: *multi_regs
= true; return "m";
769 case GEN6_FILE_IMM
: *multi_regs
= true; return "";
770 default: *multi_regs
= false; return "BAD";
775 disasm_inst_type(const struct disasm_inst
*inst
,
776 const struct disasm_operand
*operand
)
778 if (operand
->file
== GEN6_FILE_IMM
) {
779 switch (operand
->type
) {
780 case GEN6_TYPE_UD
: return "UD";
781 case GEN6_TYPE_D
: return "D";
782 case GEN6_TYPE_UW
: return "UW";
783 case GEN6_TYPE_W
: return "W";
784 case GEN6_TYPE_UV_IMM
: return "UV";
785 case GEN6_TYPE_VF_IMM
: return "VF";
786 case GEN6_TYPE_V_IMM
: return "V";
787 case GEN6_TYPE_F
: return "F";
788 default: return "BAD";
791 switch (operand
->type
) {
792 case GEN6_TYPE_UD
: return "UD";
793 case GEN6_TYPE_D
: return "D";
794 case GEN6_TYPE_UW
: return "UW";
795 case GEN6_TYPE_W
: return "W";
796 case GEN6_TYPE_UB
: return "UB";
797 case GEN6_TYPE_B
: return "B";
798 case GEN7_TYPE_DF
: return "DF";
799 case GEN6_TYPE_F
: return "F";
800 default: return "BAD";
806 disasm_inst_vert_stride(const struct disasm_inst
*inst
, unsigned vert_stride
)
808 switch (vert_stride
) {
809 case GEN6_VERTSTRIDE_0
: return "0";
810 case GEN6_VERTSTRIDE_1
: return "1";
811 case GEN6_VERTSTRIDE_2
: return "2";
812 case GEN6_VERTSTRIDE_4
: return "4";
813 case GEN6_VERTSTRIDE_8
: return "8";
814 case GEN6_VERTSTRIDE_16
: return "16";
815 case GEN6_VERTSTRIDE_32
: return "32";
816 case GEN6_VERTSTRIDE_VXH
: return "VxH";
817 default: return "BAD";
822 disasm_inst_width(const struct disasm_inst
*inst
, unsigned width
)
825 case GEN6_WIDTH_1
: return "1";
826 case GEN6_WIDTH_2
: return "2";
827 case GEN6_WIDTH_4
: return "4";
828 case GEN6_WIDTH_8
: return "8";
829 case GEN6_WIDTH_16
: return "16";
830 default: return "BAD";
835 disasm_inst_horz_stride(const struct disasm_inst
*inst
, unsigned horz_stride
)
837 switch (horz_stride
) {
838 case GEN6_HORZSTRIDE_0
: return "0";
839 case GEN6_HORZSTRIDE_1
: return "1";
840 case GEN6_HORZSTRIDE_2
: return "2";
841 case GEN6_HORZSTRIDE_4
: return "4";
842 default: return "BAD";
847 disasm_inst_writemask(const struct disasm_inst
*inst
, unsigned writemask
)
850 case 0x0: return ".";
851 case 0x1: return ".x";
852 case 0x2: return ".y";
853 case 0x3: return ".xy";
854 case 0x4: return ".z";
855 case 0x5: return ".xz";
856 case 0x6: return ".yz";
857 case 0x7: return ".xyz";
858 case 0x8: return ".w";
859 case 0x9: return ".xw";
860 case 0xa: return ".yw";
861 case 0xb: return ".xyw";
862 case 0xc: return ".zw";
863 case 0xd: return ".xzw";
864 case 0xe: return ".yzw";
866 default: return ".BAD";
871 disasm_inst_negate(const struct disasm_inst
*inst
, bool negate
)
873 return (negate
) ? "-" : "";
877 disasm_inst_absolute(const struct disasm_inst
*inst
, bool absolute
)
879 return (absolute
) ? "(abs)" : "";
883 disasm_inst_mdesc_sampler_op(const struct disasm_inst
*inst
, int op
)
886 case GEN6_MSG_SAMPLER_SAMPLE
: return "sample";
887 case GEN6_MSG_SAMPLER_SAMPLE_B
: return "sample_b";
888 case GEN6_MSG_SAMPLER_SAMPLE_L
: return "sample_l";
889 case GEN6_MSG_SAMPLER_SAMPLE_C
: return "sample_c";
890 case GEN6_MSG_SAMPLER_SAMPLE_D
: return "sample_d";
891 case GEN6_MSG_SAMPLER_SAMPLE_B_C
: return "sample_b_c";
892 case GEN6_MSG_SAMPLER_SAMPLE_L_C
: return "sample_l_c";
893 case GEN6_MSG_SAMPLER_LD
: return "ld";
894 case GEN6_MSG_SAMPLER_GATHER4
: return "gather4";
895 case GEN6_MSG_SAMPLER_LOD
: return "lod";
896 case GEN6_MSG_SAMPLER_RESINFO
: return "resinfo";
897 case GEN6_MSG_SAMPLER_SAMPLEINFO
: return "sampleinfo";
898 case GEN7_MSG_SAMPLER_GATHER4_C
: return "gather4_c";
899 case GEN7_MSG_SAMPLER_GATHER4_PO
: return "gather4_po";
900 case GEN7_MSG_SAMPLER_GATHER4_PO_C
: return "gather4_po_c";
901 case GEN7_MSG_SAMPLER_SAMPLE_D_C
: return "sample_d_c";
902 case GEN7_MSG_SAMPLER_SAMPLE_LZ
: return "sample_lz";
903 case GEN7_MSG_SAMPLER_SAMPLE_C_LC
: return "sample_c_lc";
904 case GEN7_MSG_SAMPLER_SAMPLE_LD_LZ
: return "sample_ld_lz";
905 case GEN7_MSG_SAMPLER_LD_MCS
: return "ld_mcs";
906 case GEN7_MSG_SAMPLER_LD2DMS
: return "ld2dms";
907 case GEN7_MSG_SAMPLER_LD2DSS
: return "ld2dss";
908 default: return "BAD";
913 disasm_inst_mdesc_sampler_simd(const struct disasm_inst
*inst
, int simd
)
916 case GEN6_MSG_SAMPLER_SIMD4X2
: return "SIMD4x2";
917 case GEN6_MSG_SAMPLER_SIMD8
: return "SIMD8";
918 case GEN6_MSG_SAMPLER_SIMD16
: return "SIMD16";
919 case GEN6_MSG_SAMPLER_SIMD32_64
: return "SIMD32";
920 default: return "BAD";
925 disasm_inst_mdesc_urb_op(const struct disasm_inst
*inst
, int op
)
927 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) {
929 case GEN7_MSG_URB_WRITE_HWORD
: return "write HWord";
930 case GEN7_MSG_URB_WRITE_OWORD
: return "write OWord";
931 case GEN7_MSG_URB_READ_HWORD
: return "read HWord";
932 case GEN7_MSG_URB_READ_OWORD
: return "read OWord";
933 case GEN7_MSG_URB_ATOMIC_MOV
: return "atomic mov";
934 case GEN7_MSG_URB_ATOMIC_INC
: return "atomic inc";
935 default: return "BAD";
939 case GEN6_MSG_URB_WRITE
: return "urb_write";
940 case GEN6_MSG_URB_FF_SYNC
: return "ff_sync";
941 default: return "BAD";
947 disasm_inst_mdesc_dp_op_gen6(const struct disasm_inst
*inst
,
950 ILO_DEV_ASSERT(inst
->dev
, 6, 6);
953 case GEN6_MSG_DP_OWORD_BLOCK_READ
: return "OWORD block read";
954 case GEN6_MSG_DP_RT_UNORM_READ
: return "RT UNORM read";
955 case GEN6_MSG_DP_OWORD_DUAL_BLOCK_READ
: return "OWORD dual block read";
956 case GEN6_MSG_DP_MEDIA_BLOCK_READ
: return "media block read";
957 case GEN6_MSG_DP_UNALIGNED_OWORD_BLOCK_READ
: return "unaligned OWORD block read";
958 case GEN6_MSG_DP_DWORD_SCATTERED_READ
: return "DWORD scattered read";
959 case GEN6_MSG_DP_DWORD_ATOMIC_WRITE
: return "DWORD atomic write";
960 case GEN6_MSG_DP_OWORD_BLOCK_WRITE
: return "OWORD block write";
961 case GEN6_MSG_DP_OWORD_DUAL_BLOCK_WRITE
: return "OWORD dual block_write";
962 case GEN6_MSG_DP_MEDIA_BLOCK_WRITE
: return "media block write";
963 case GEN6_MSG_DP_DWORD_SCATTERED_WRITE
: return "DWORD scattered write";
964 case GEN6_MSG_DP_RT_WRITE
: return "RT write";
965 case GEN6_MSG_DP_SVB_WRITE
: return "SVB write";
966 case GEN6_MSG_DP_RT_UNORM_WRITE
: return "RT UNORM write";
967 default: return "BAD";
972 disasm_inst_mdesc_dp_op_gen7(const struct disasm_inst
*inst
,
975 ILO_DEV_ASSERT(inst
->dev
, 7, 7);
978 case GEN6_SFID_DP_SAMPLER
:
980 case GEN7_MSG_DP_SAMPLER_OWORD_BLOCK_READ
: return "OWORD block read";
981 case GEN7_MSG_DP_SAMPLER_MEDIA_BLOCK_READ
: return "media block read";
982 default: return "BAD";
984 case GEN6_SFID_DP_RC
:
986 case GEN7_MSG_DP_RC_MEDIA_BLOCK_READ
: return "media block read";
987 case GEN7_MSG_DP_RC_TYPED_SURFACE_READ
: return "typed surface read";
988 case GEN7_MSG_DP_RC_TYPED_ATOMIC_OP
: return "typed atomic op";
989 case GEN7_MSG_DP_RC_MEMORY_FENCE
: return "memory fence";
990 case GEN7_MSG_DP_RC_MEDIA_BLOCK_WRITE
: return "media block write";
991 case GEN7_MSG_DP_RC_RT_WRITE
: return "RT write";
992 case GEN7_MSG_DP_RC_TYPED_SURFACE_WRITE
: return "typed surface write";
993 default: return "BAD";
995 case GEN6_SFID_DP_CC
:
997 case GEN7_MSG_DP_CC_OWORD_BLOCK_READ
: return "OWROD block read";
998 case GEN7_MSG_DP_CC_UNALIGNED_OWORD_BLOCK_READ
: return "unaligned OWORD block read";
999 case GEN7_MSG_DP_CC_OWORD_DUAL_BLOCK_READ
: return "OWORD dual block read";
1000 case GEN7_MSG_DP_CC_DWORD_SCATTERED_READ
: return "DWORD scattered read";
1001 default: return "BAD";
1003 case GEN7_SFID_DP_DC0
:
1005 case GEN7_MSG_DP_DC0_OWORD_BLOCK_READ
: return "OWORD block read";
1006 case GEN7_MSG_DP_DC0_UNALIGNED_OWORD_BLOCK_READ
: return "unaligned OWORD block read";
1007 case GEN7_MSG_DP_DC0_OWORD_DUAL_BLOCK_READ
: return "OWORD dual block read";
1008 case GEN7_MSG_DP_DC0_DWORD_SCATTERED_READ
: return "DWORD scattered read";
1009 case GEN7_MSG_DP_DC0_BYTE_SCATTERED_READ
: return "BYTE scattered read";
1010 case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_READ
: return "untyped surface read";
1011 case GEN7_MSG_DP_DC0_UNTYPED_ATOMIC_OP
: return "untyped atomic op";
1012 case GEN7_MSG_DP_DC0_MEMORY_FENCE
: return "memory fence";
1013 case GEN7_MSG_DP_DC0_OWORD_BLOCK_WRITE
: return "OWORD block write";
1014 case GEN7_MSG_DP_DC0_OWORD_DUAL_BLOCK_WRITE
: return "OWORD dual block write";
1015 case GEN7_MSG_DP_DC0_DWORD_SCATTERED_WRITE
: return "OWORD scattered write";
1016 case GEN7_MSG_DP_DC0_BYTE_SCATTERED_WRITE
: return "BYTE scattered write";
1017 case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_WRITE
: return "untyped surface write";
1018 default: return "BAD";
1020 default: return "BAD";
1025 disasm_inst_mdesc_dp_op_gen75(const struct disasm_inst
*inst
,
1028 ILO_DEV_ASSERT(inst
->dev
, 7.5, 7.5);
1031 case GEN6_SFID_DP_SAMPLER
:
1033 case GEN75_MSG_DP_SAMPLER_READ_SURFACE_INFO
: return "read surface info";
1034 case GEN75_MSG_DP_SAMPLER_UNALIGNED_OWORD_BLOCK_READ
: return "unaligned OWORD block read";
1035 case GEN75_MSG_DP_SAMPLER_MEDIA_BLOCK_READ
: return "media block read";
1036 default: return "BAD";
1039 case GEN6_SFID_DP_RC
:
1041 case GEN75_MSG_DP_RC_MEDIA_BLOCK_READ
: return "media block read";
1042 case GEN75_MSG_DP_RC_MEMORY_FENCE
: return "memory fence";
1043 case GEN75_MSG_DP_RC_MEDIA_BLOCK_WRITE
: return "media block write";
1044 case GEN75_MSG_DP_RC_RT_WRITE
: return "RT write";
1045 default: return "BAD";
1047 case GEN6_SFID_DP_CC
:
1049 case GEN75_MSG_DP_CC_OWORD_BLOCK_READ
: return "OWROD block read";
1050 case GEN75_MSG_DP_CC_UNALIGNED_OWORD_BLOCK_READ
: return "unaligned OWORD block read";
1051 case GEN75_MSG_DP_CC_OWORD_DUAL_BLOCK_READ
: return "OWORD dual block read";
1052 case GEN75_MSG_DP_CC_DWORD_SCATTERED_READ
: return "DWORD scattered read";
1053 default: return "BAD";
1055 case GEN7_SFID_DP_DC0
:
1057 case GEN75_MSG_DP_DC0_OWORD_BLOCK_READ
: return "OWORD block read";
1058 case GEN75_MSG_DP_DC0_UNALIGNED_OWORD_BLOCK_READ
: return "unaligned OWORD block read";
1059 case GEN75_MSG_DP_DC0_OWORD_DUAL_BLOCK_READ
: return "OWORD dual block read";
1060 case GEN75_MSG_DP_DC0_DWORD_SCATTERED_READ
: return "DWORD scattered read";
1061 case GEN75_MSG_DP_DC0_BYTE_SCATTERED_READ
: return "BYTE scattered read";
1062 case GEN75_MSG_DP_DC0_MEMORY_FENCE
: return "memory fence";
1063 case GEN75_MSG_DP_DC0_OWORD_BLOCK_WRITE
: return "OWORD block write";
1064 case GEN75_MSG_DP_DC0_OWORD_DUAL_BLOCK_WRITE
: return "OWORD dual block write";
1065 case GEN75_MSG_DP_DC0_DWORD_SCATTERED_WRITE
: return "OWORD scattered write";
1066 case GEN75_MSG_DP_DC0_BYTE_SCATTERED_WRITE
: return "BYTE scattered write";
1067 default: return "BAD";
1069 case GEN75_SFID_DP_DC1
:
1071 case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_READ
: return "untyped surface read";
1072 case GEN75_MSG_DP_DC1_UNTYPED_ATOMIC_OP
: return "DC untyped atomic op";
1073 case GEN75_MSG_DP_DC1_UNTYPED_ATOMIC_OP_SIMD4X2
: return "DC untyped 4x2 atomic op";
1074 case GEN75_MSG_DP_DC1_MEDIA_BLOCK_READ
: return "DC media block read";
1075 case GEN75_MSG_DP_DC1_TYPED_SURFACE_READ
: return "DC typed surface read";
1076 case GEN75_MSG_DP_DC1_TYPED_ATOMIC_OP
: return "DC typed atomic";
1077 case GEN75_MSG_DP_DC1_TYPED_ATOMIC_OP_SIMD4X2
: return "DC typed 4x2 atomic op";
1078 case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_WRITE
: return "DC untyped surface write";
1079 case GEN75_MSG_DP_DC1_MEDIA_BLOCK_WRITE
: return "DC media block write";
1080 case GEN75_MSG_DP_DC1_ATOMIC_COUNTER_OP
: return "DC atomic counter op";
1081 case GEN75_MSG_DP_DC1_ATOMIC_COUNTER_OP_SIMD4X2
: return "DC 4x2 atomic counter op";
1082 case GEN75_MSG_DP_DC1_TYPED_SURFACE_WRITE
: return "DC typed surface write";
1083 default: return "BAD";
1085 default: return "BAD";
1090 disasm_inst_mdesc_dp_op(const struct disasm_inst
*inst
, int sfid
, int op
)
1092 switch (ilo_dev_gen(inst
->dev
)) {
1093 case ILO_GEN(7.5): return disasm_inst_mdesc_dp_op_gen75(inst
, sfid
, op
);
1094 case ILO_GEN(7): return disasm_inst_mdesc_dp_op_gen7(inst
, sfid
, op
);
1095 case ILO_GEN(6): return disasm_inst_mdesc_dp_op_gen6(inst
, sfid
, op
);
1096 default: return "BAD";
1101 disasm_inst_mdesc_dp_untyped_surface_simd_mode(const struct disasm_inst
*inst
,
1104 switch (mdesc
& GEN7_MSG_DP_UNTYPED_MODE__MASK
) {
1105 case GEN7_MSG_DP_UNTYPED_MODE_SIMD4X2
: return "SIMD4x2";
1106 case GEN7_MSG_DP_UNTYPED_MODE_SIMD16
: return "SIMD16";
1107 case GEN7_MSG_DP_UNTYPED_MODE_SIMD8
: return "SIMD8";
1108 default: return "BAD";
1113 disasm_inst_mdesc_dp_rt_write_simd_mode(const struct disasm_inst
*inst
,
1116 switch (mdesc
& GEN6_MSG_DP_RT_MODE__MASK
) {
1117 case GEN6_MSG_DP_RT_MODE_SIMD16
: return "SIMD16";
1118 case GEN6_MSG_DP_RT_MODE_SIMD16_REPDATA
: return "SIMD16/RepData";
1119 case GEN6_MSG_DP_RT_MODE_SIMD8_DUALSRC_LO
: return "SIMD8/DualSrcLow";
1120 case GEN6_MSG_DP_RT_MODE_SIMD8_DUALSRC_HI
: return "SIMD8/DualSrcHigh";
1121 case GEN6_MSG_DP_RT_MODE_SIMD8_LO
: return "SIMD8";
1122 case GEN6_MSG_DP_RT_MODE_SIMD8_IMAGE_WR
: return "SIMD8/ImageWrite";
1123 default: return "BAD";
1128 disasm_inst_is_null(const struct disasm_inst
*inst
,
1129 const struct disasm_operand
*operand
)
1131 return (operand
->file
== GEN6_FILE_ARF
&& operand
->reg
== GEN6_ARF_NULL
);
1135 disasm_inst_type_size(const struct disasm_inst
*inst
,
1136 const struct disasm_operand
*operand
)
1138 assert(operand
->file
!= GEN6_FILE_IMM
);
1140 switch (operand
->type
) {
1141 case GEN6_TYPE_UD
: return 4;
1142 case GEN6_TYPE_D
: return 4;
1143 case GEN6_TYPE_UW
: return 2;
1144 case GEN6_TYPE_W
: return 2;
1145 case GEN6_TYPE_UB
: return 1;
1146 case GEN6_TYPE_B
: return 1;
1147 case GEN7_TYPE_DF
: return 8;
1148 case GEN6_TYPE_F
: return 4;
1154 disasm_printer_reset(struct disasm_printer
*printer
)
1156 printer
->buf
[0] = '\0';
1161 disasm_printer_get_string(struct disasm_printer
*printer
)
1163 return printer
->buf
;
1166 static void _util_printf_format(2, 3)
1167 disasm_printer_add(struct disasm_printer
*printer
, const char *format
, ...)
1169 const size_t avail
= sizeof(printer
->buf
) - printer
->len
;
1173 va_start(ap
, format
);
1174 written
= vsnprintf(printer
->buf
+ printer
->len
, avail
, format
, ap
);
1178 if (written
< 0 || written
>= avail
) {
1179 memcpy(printer
->buf
+ sizeof(printer
->buf
) - 4, "...", 4);
1180 printer
->len
= sizeof(printer
->buf
) - 1;
1182 printer
->len
+= written
;
1187 * Pad to the specified column.
1190 disasm_printer_column(struct disasm_printer
*printer
, int col
)
1192 int len
= DISASM_PRINTER_COLUMN_WIDTH
* col
;
1194 if (len
<= printer
->len
) {
1198 /* at least one space */
1199 len
= printer
->len
+ 1;
1202 if (len
>= sizeof(printer
->buf
)) {
1203 len
= sizeof(printer
->buf
) - 1;
1205 if (len
<= printer
->len
)
1209 memset(printer
->buf
+ printer
->len
, ' ', len
- printer
->len
);
1211 printer
->buf
[printer
->len
] = '\0';
1215 disasm_printer_add_op(struct disasm_printer
*printer
,
1216 const struct disasm_inst
*inst
)
1218 if (inst
->pred_ctrl
!= GEN6_PREDCTRL_NONE
) {
1219 disasm_printer_add(printer
, "(%c%s%s) ",
1220 disasm_inst_pred_inv(inst
),
1221 disasm_inst_flag_reg(inst
),
1222 disasm_inst_pred_ctrl(inst
));
1225 disasm_printer_add(printer
, "%s%s%s%s",
1226 disasm_inst_opcode(inst
),
1227 disasm_inst_saturate(inst
),
1228 disasm_inst_debug_ctrl(inst
),
1229 disasm_inst_cond_modifier(inst
));
1231 if (inst
->cond_modifier
!= GEN6_COND_NONE
) {
1232 switch (inst
->opcode
) {
1233 case GEN6_OPCODE_SEL
:
1234 case GEN6_OPCODE_IF
:
1235 case GEN6_OPCODE_WHILE
:
1236 /* these do not update flag registers */
1239 disasm_printer_add(printer
, ".%s", disasm_inst_flag_reg(inst
));
1244 if (inst
->opcode
== GEN6_OPCODE_MATH
)
1245 disasm_printer_add(printer
, " %s", disasm_inst_fc(inst
));
1246 if (inst
->opcode
!= GEN6_OPCODE_NOP
)
1247 disasm_printer_add(printer
, "(%s)", disasm_inst_exec_size(inst
));
1251 disasm_printer_add_operand(struct disasm_printer
*printer
,
1252 const struct disasm_inst
*inst
,
1253 const struct disasm_operand
*operand
)
1258 name
= disasm_inst_file(inst
, operand
, &multi_regs
);
1260 disasm_printer_add(printer
, "%s", name
);
1264 if (operand
->file
== GEN6_FILE_IMM
) {
1265 switch (operand
->type
) {
1267 disasm_printer_add(printer
, "0x%08xUD", inst
->u
.imm32
);
1270 disasm_printer_add(printer
, "%dD", inst
->u
.imm32
);
1273 disasm_printer_add(printer
, "0x%04xUW", (uint16_t) inst
->u
.imm32
);
1276 disasm_printer_add(printer
, "%dW", (int16_t) inst
->u
.imm32
);
1278 case GEN6_TYPE_UV_IMM
:
1279 disasm_printer_add(printer
, "0x%08xUV", inst
->u
.imm32
);
1281 case GEN6_TYPE_VF_IMM
:
1282 disasm_printer_add(printer
, "Vector Float");
1284 case GEN6_TYPE_V_IMM
:
1285 disasm_printer_add(printer
, "0x%08xV", inst
->u
.imm32
);
1288 disasm_printer_add(printer
, "%-gF", uif(inst
->u
.imm32
));
1291 disasm_printer_add(printer
, "BAD");
1298 if (operand
->addr_mode
== GEN6_ADDRMODE_DIRECT
) {
1299 unsigned reg
, subreg
;
1302 if (operand
->file
== GEN6_FILE_ARF
)
1305 subreg
= operand
->subreg
/ disasm_inst_type_size(inst
, operand
);
1308 disasm_printer_add(printer
, "%s%d.%d", name
, reg
, subreg
);
1310 disasm_printer_add(printer
, "%s%d", name
, reg
);
1312 disasm_printer_add(printer
, "%s[a0.%d %d]",
1313 name
, operand
->addr_subreg
, operand
->addr_imm
);
1318 disasm_printer_add_dst(struct disasm_printer
*printer
,
1319 const struct disasm_inst
*inst
,
1320 const struct disasm_dst_operand
*dst
)
1322 disasm_printer_add_operand(printer
, inst
, &dst
->base
);
1324 /* dst is an immediate when in EU_INSTRUCTION_BRANCH_CONDITIONAL form */
1325 if (disasm_inst_is_null(inst
, &dst
->base
) ||
1326 dst
->base
.file
== GEN6_FILE_IMM
)
1329 disasm_printer_add(printer
, "<%s>%s%s",
1330 disasm_inst_horz_stride(inst
, dst
->horz_stride
),
1331 disasm_inst_writemask(inst
, dst
->writemask
),
1332 disasm_inst_type(inst
, &dst
->base
));
1336 disasm_printer_add_src(struct disasm_printer
*printer
,
1337 const struct disasm_inst
*inst
,
1338 const struct disasm_src_operand
*src
)
1340 static const char swizzle_chars
[4] = { 'x', 'y', 'z', 'w' };
1343 disasm_printer_add(printer
, "%s%s",
1344 disasm_inst_negate(inst
, src
->negate
),
1345 disasm_inst_absolute(inst
, src
->absolute
));
1347 disasm_printer_add_operand(printer
, inst
, &src
->base
);
1349 if (disasm_inst_is_null(inst
, &src
->base
) ||
1350 src
->base
.file
== GEN6_FILE_IMM
)
1353 if (src
->swizzle_x
== 0 && src
->swizzle_y
== 1 &&
1354 src
->swizzle_z
== 2 && src
->swizzle_w
== 3) {
1356 } else if (src
->swizzle_x
== src
->swizzle_y
&&
1357 src
->swizzle_x
== src
->swizzle_z
&&
1358 src
->swizzle_x
== src
->swizzle_w
) {
1359 swizzle
[0] = swizzle_chars
[src
->swizzle_x
];
1362 swizzle
[0] = swizzle_chars
[src
->swizzle_x
];
1363 swizzle
[1] = swizzle_chars
[src
->swizzle_y
];
1364 swizzle
[2] = swizzle_chars
[src
->swizzle_z
];
1365 swizzle
[3] = swizzle_chars
[src
->swizzle_w
];
1369 disasm_printer_add(printer
, "<%s,%s,%s>%s%s",
1370 disasm_inst_vert_stride(inst
, src
->vert_stride
),
1371 disasm_inst_width(inst
, src
->width
),
1372 disasm_inst_horz_stride(inst
, src
->horz_stride
),
1374 disasm_inst_type(inst
, &src
->base
));
1378 disasm_printer_add_ctrl(struct disasm_printer
*printer
,
1379 const struct disasm_inst
*inst
)
1381 if (inst
->opcode
== GEN6_OPCODE_NOP
) {
1382 disasm_printer_add(printer
, ";");
1386 disasm_printer_add(printer
, "{%s%s%s%s%s%s%s%s };",
1387 disasm_inst_access_mode(inst
),
1388 disasm_inst_mask_ctrl(inst
),
1389 disasm_inst_dep_ctrl(inst
),
1390 disasm_inst_qtr_ctrl(inst
),
1391 disasm_inst_cmpt_ctrl(inst
),
1392 disasm_inst_thread_ctrl(inst
),
1393 disasm_inst_acc_wr_ctrl(inst
),
1394 disasm_inst_eot(inst
));
1398 disasm_printer_add_mdesc_sampler(struct disasm_printer
*printer
,
1399 const struct disasm_inst
*inst
,
1404 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) {
1405 op
= GEN_EXTRACT(mdesc
, GEN7_MSG_SAMPLER_OP
);
1406 simd
= GEN_EXTRACT(mdesc
, GEN7_MSG_SAMPLER_SIMD
);
1408 op
= GEN_EXTRACT(mdesc
, GEN6_MSG_SAMPLER_OP
);
1409 simd
= GEN_EXTRACT(mdesc
, GEN6_MSG_SAMPLER_SIMD
);
1412 disasm_printer_add(printer
,
1413 "%s %s samp %d surf %d",
1414 disasm_inst_mdesc_sampler_op(inst
, op
),
1415 disasm_inst_mdesc_sampler_simd(inst
, simd
),
1416 GEN_EXTRACT(mdesc
, GEN6_MSG_SAMPLER_INDEX
),
1417 GEN_EXTRACT(mdesc
, GEN6_MSG_SAMPLER_SURFACE
));
1421 disasm_printer_add_mdesc_urb(struct disasm_printer
*printer
,
1422 const struct disasm_inst
*inst
,
1426 bool interleaved
, complete
, allocate
, used
;
1428 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) {
1429 op
= GEN_EXTRACT(mdesc
, GEN7_MSG_URB_OP
);
1430 offset
= GEN_EXTRACT(mdesc
, GEN7_MSG_URB_GLOBAL_OFFSET
);
1431 interleaved
= mdesc
& GEN7_MSG_URB_INTERLEAVED
;
1432 complete
= mdesc
& GEN7_MSG_URB_COMPLETE
;
1437 op
= GEN_EXTRACT(mdesc
, GEN6_MSG_URB_OP
);
1438 offset
= GEN_EXTRACT(mdesc
, GEN6_MSG_URB_OFFSET
);
1439 interleaved
= mdesc
& GEN6_MSG_URB_INTERLEAVED
;
1440 complete
= mdesc
& GEN6_MSG_URB_COMPLETE
;
1442 allocate
= mdesc
& GEN6_MSG_URB_ALLOCATE
;
1443 used
= mdesc
& GEN6_MSG_URB_USED
;
1446 disasm_printer_add(printer
, "%s offset %d%s%s%s%s",
1447 disasm_inst_mdesc_urb_op(inst
, op
),
1449 (interleaved
) ? " interleave" : "",
1450 (allocate
) ? " allocate" : "",
1451 (used
) ? " used" : "",
1452 (complete
) ? " complete" : "");
1456 disasm_printer_add_mdesc_spawner(struct disasm_printer
*printer
,
1457 const struct disasm_inst
*inst
,
1460 const char *requester
, *op
;
1462 switch (mdesc
& GEN6_MSG_TS_REQUESTER_TYPE__MASK
) {
1463 case GEN6_MSG_TS_REQUESTER_TYPE_ROOT
: requester
= "root"; break;
1464 case GEN6_MSG_TS_REQUESTER_TYPE_CHILD
: requester
= "child"; break;
1465 default: requester
= "BAD"; break;
1468 switch (mdesc
& GEN6_MSG_TS_OPCODE__MASK
) {
1469 case GEN6_MSG_TS_OPCODE_DEREF
:
1470 op
= (mdesc
& GEN6_MSG_TS_RESOURCE_SELECT_NO_DEREF
) ?
1471 "no deref" : "deref";
1473 case GEN6_MSG_TS_OPCODE_SPAWN
:
1474 op
= (mdesc
& GEN6_MSG_TS_RESOURCE_SELECT_ROOT
) ?
1475 "spawn root" : "spawn child";
1482 disasm_printer_add(printer
, "%s thread %s", requester
, op
);
1486 disasm_printer_add_mdesc_dp_sampler(struct disasm_printer
*printer
,
1487 const struct disasm_inst
*inst
,
1490 const int op
= (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) ?
1491 GEN_EXTRACT(mdesc
, GEN7_MSG_DP_OP
) : GEN_EXTRACT(mdesc
, GEN6_MSG_DP_OP
);
1492 const bool write_commit
= (ilo_dev_gen(inst
->dev
) == ILO_GEN(6)) ?
1493 (mdesc
& GEN6_MSG_DP_SEND_WRITE_COMMIT
) : 0;
1495 disasm_printer_add(printer
, "%s block size %d commit %d surf %d",
1496 disasm_inst_mdesc_dp_op(inst
, GEN6_SFID_DP_SAMPLER
, op
),
1497 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_OWORD_BLOCK_SIZE
),
1499 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1503 disasm_printer_add_mdesc_dp_dc0(struct disasm_printer
*printer
,
1504 const struct disasm_inst
*inst
,
1507 const int op
= GEN_EXTRACT(mdesc
, GEN7_MSG_DP_OP
);
1509 ILO_DEV_ASSERT(inst
->dev
, 7, 7.5);
1511 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7.5)) {
1512 disasm_printer_add(printer
, "%s ctrl 0x%x surf %d",
1513 disasm_inst_mdesc_dp_op(inst
, GEN7_SFID_DP_DC0
, op
),
1514 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_CTRL
),
1515 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1518 case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_READ
:
1519 case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_WRITE
:
1520 disasm_printer_add(printer
, "%s %s mask 0x%x surf %d",
1521 disasm_inst_mdesc_dp_op(inst
, GEN7_SFID_DP_DC0
, op
),
1522 disasm_inst_mdesc_dp_untyped_surface_simd_mode(inst
, mdesc
),
1523 GEN_EXTRACT(mdesc
, GEN7_MSG_DP_UNTYPED_MASK
),
1524 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1527 disasm_printer_add(printer
, "%s ctrl 0x%x surf %d",
1528 disasm_inst_mdesc_dp_op(inst
, GEN7_SFID_DP_DC0
, op
),
1529 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_CTRL
),
1530 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1537 disasm_printer_add_mdesc_dp_dc1(struct disasm_printer
*printer
,
1538 const struct disasm_inst
*inst
,
1541 const int op
= GEN_EXTRACT(mdesc
, GEN7_MSG_DP_OP
);
1543 ILO_DEV_ASSERT(inst
->dev
, 7.5, 7.5);
1546 case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_READ
:
1547 case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_WRITE
:
1548 disasm_printer_add(printer
, "%s %s mask 0x%x surf %d",
1549 disasm_inst_mdesc_dp_op(inst
, GEN75_SFID_DP_DC1
, op
),
1550 disasm_inst_mdesc_dp_untyped_surface_simd_mode(inst
, mdesc
),
1551 GEN_EXTRACT(mdesc
, GEN7_MSG_DP_UNTYPED_MASK
),
1552 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1555 disasm_printer_add(printer
, "%s ctrl 0x%x surf %d",
1556 disasm_inst_mdesc_dp_op(inst
, GEN75_SFID_DP_DC1
, op
),
1557 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_CTRL
),
1558 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1564 disasm_printer_add_mdesc_dp_rc(struct disasm_printer
*printer
,
1565 const struct disasm_inst
*inst
,
1568 const int op
= (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) ?
1569 GEN_EXTRACT(mdesc
, GEN7_MSG_DP_OP
) : GEN_EXTRACT(mdesc
, GEN6_MSG_DP_OP
);
1572 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7.5))
1573 is_rt_write
= (op
== GEN75_MSG_DP_RC_RT_WRITE
);
1574 else if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7))
1575 is_rt_write
= (op
== GEN7_MSG_DP_RC_RT_WRITE
);
1577 is_rt_write
= (op
== GEN6_MSG_DP_RT_WRITE
);
1579 disasm_printer_add(printer
, "%s",
1580 disasm_inst_mdesc_dp_op(inst
, GEN6_SFID_DP_RC
, op
));
1583 disasm_printer_add(printer
, " %s%s%s%s",
1584 disasm_inst_mdesc_dp_rt_write_simd_mode(inst
, mdesc
),
1585 (mdesc
& GEN6_MSG_DP_SLOTGRP_HI
) ? " Hi" : "",
1586 (mdesc
& GEN6_MSG_DP_RT_LAST
) ? " LastRT" : "",
1587 (ilo_dev_gen(inst
->dev
) == ILO_GEN(6) &&
1588 (mdesc
& GEN6_MSG_DP_SEND_WRITE_COMMIT
)) ? " WriteCommit" : "");
1591 disasm_printer_add(printer
, " surf %d",
1592 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1596 disasm_printer_add_mdesc(struct disasm_printer
*printer
,
1597 const struct disasm_inst
*inst
)
1599 const uint32_t mdesc
= inst
->u
.imm32
;
1601 assert(inst
->opcode
== GEN6_OPCODE_SEND
||
1602 inst
->opcode
== GEN6_OPCODE_SENDC
);
1603 assert(inst
->src1
.base
.file
== GEN6_FILE_IMM
);
1605 disasm_printer_add(printer
, " %s (", disasm_inst_sfid(inst
));
1607 switch (inst
->sfid
) {
1608 case GEN6_SFID_SAMPLER
:
1609 disasm_printer_add_mdesc_sampler(printer
, inst
, mdesc
);
1611 case GEN6_SFID_DP_SAMPLER
:
1612 disasm_printer_add_mdesc_dp_sampler(printer
, inst
, mdesc
);
1614 case GEN6_SFID_DP_RC
:
1615 disasm_printer_add_mdesc_dp_rc(printer
, inst
, mdesc
);
1618 disasm_printer_add_mdesc_urb(printer
, inst
, mdesc
);
1620 case GEN6_SFID_SPAWNER
:
1621 disasm_printer_add_mdesc_spawner(printer
, inst
, mdesc
);
1623 case GEN7_SFID_DP_DC0
:
1624 disasm_printer_add_mdesc_dp_dc0(printer
, inst
, mdesc
);
1626 case GEN75_SFID_DP_DC1
:
1627 disasm_printer_add_mdesc_dp_dc1(printer
, inst
, mdesc
);
1629 case GEN6_SFID_DP_CC
:
1635 disasm_printer_add(printer
, ") mlen %d rlen %d",
1636 GEN_EXTRACT(mdesc
, GEN6_MSG_MLEN
),
1637 GEN_EXTRACT(mdesc
, GEN6_MSG_RLEN
));
1641 disasm_printer_print_inst(struct disasm_printer
*printer
,
1642 const struct disasm_inst
*inst
)
1646 disasm_printer_reset(printer
);
1648 disasm_printer_column(printer
, col
++);
1649 disasm_printer_add_op(printer
, inst
);
1651 if (inst
->has_jip
|| inst
->has_uip
) {
1652 if (inst
->has_jip
) {
1653 disasm_printer_column(printer
, col
++);
1654 disasm_printer_add(printer
, "JIP: %d", (int16_t) inst
->u
.imm32
);
1657 if (inst
->has_uip
) {
1658 disasm_printer_column(printer
, col
++);
1659 disasm_printer_add(printer
, "UIP: %d",
1660 (int16_t) (inst
->u
.imm32
>> 16));
1663 const int src_count
= disasm_opcode_table
[inst
->opcode
].src_count
;
1666 const struct disasm_src_operand
*src
[3] = {
1667 &inst
->src0
, &inst
->src1
, &inst
->u
.src2
1671 disasm_printer_column(printer
, col
++);
1672 disasm_printer_add_dst(printer
, inst
, &inst
->dst
);
1674 for (i
= 0; i
< src_count
; i
++) {
1675 disasm_printer_column(printer
, col
++);
1676 disasm_printer_add_src(printer
, inst
, src
[i
]);
1681 if (inst
->opcode
== GEN6_OPCODE_SEND
||
1682 inst
->opcode
== GEN6_OPCODE_SENDC
) {
1683 /* start a new line */
1684 ilo_printf("%s\n", disasm_printer_get_string(printer
));
1685 disasm_printer_reset(printer
);
1688 disasm_printer_column(printer
, col
++);
1690 disasm_printer_column(printer
, col
++);
1691 disasm_printer_add_mdesc(printer
, inst
);
1697 disasm_printer_column(printer
, col
++);
1698 disasm_printer_add_ctrl(printer
, inst
);
1700 ilo_printf("%s\n", disasm_printer_get_string(printer
));
1704 disasm_uncompact(const struct ilo_dev_info
*dev
,
1705 uint64_t compact
, uint32_t *dw
)
1707 const struct toy_compaction_table
*tbl
=
1708 toy_compiler_get_compaction_table(dev
);
1712 memset(dw
, 0, sizeof(*dw
) * 4);
1714 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_OPCODE
);
1715 dw
[0] |= GEN_SHIFT32(tmp
, GEN6_INST_OPCODE
);
1717 if (ilo_dev_gen(dev
) >= ILO_GEN(7) && (compact
& GEN6_COMPACT_DEBUGCTRL
))
1718 dw
[0] |= GEN6_INST_DEBUGCTRL
;
1721 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_CONTROL_INDEX
);
1722 tmp
= tbl
->control
[tmp
];
1724 dw
[0] |= (tmp
& 0xffff) << GEN6_INST_ACCESSMODE__SHIFT
;
1726 dw
[0] |= GEN6_INST_SATURATE
;
1728 if (ilo_dev_gen(dev
) >= ILO_GEN(7))
1729 dw
[2] |= (tmp
>> 17) << GEN6_INST_FLAG_SUBREG__SHIFT
;
1732 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_DATATYPE_INDEX
);
1733 tmp
= tbl
->datatype
[tmp
];
1735 dw
[1] |= (tmp
& 0x7fff) << GEN6_INST_DST_FILE__SHIFT
;
1736 dw
[1] |= (tmp
>> 15) << GEN6_INST_DST_HORZSTRIDE__SHIFT
;
1739 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SUBREG_INDEX
);
1740 tmp
= tbl
->subreg
[tmp
];
1742 dw
[1] |= (tmp
& 0x1f) << 16;
1743 dw
[2] |= ((tmp
>> 5) & 0x1f);
1744 dw
[3] |= ((tmp
>> 10) & 0x1f);
1746 if (compact
& GEN6_COMPACT_ACCWRCTRL
)
1747 dw
[0] |= GEN6_INST_ACCWRCTRL
;
1749 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_CONDMODIFIER
);
1750 dw
[0] |= GEN_SHIFT32(tmp
, GEN6_INST_CONDMODIFIER
);
1752 if (ilo_dev_gen(dev
) == ILO_GEN(6)) {
1753 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_FLAG_SUBREG
);
1754 dw
[2] |= GEN_SHIFT32(compact
, GEN6_INST_FLAG_SUBREG
);
1757 assert(compact
& GEN6_COMPACT_CMPTCTRL
);
1760 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SRC0_INDEX
);
1761 tmp
= tbl
->src
[tmp
];
1764 src_is_imm
= (GEN_EXTRACT(dw
[1], GEN6_INST_SRC0_FILE
) == GEN6_FILE_IMM
) ||
1765 (GEN_EXTRACT(dw
[1], GEN6_INST_SRC1_FILE
) == GEN6_FILE_IMM
);
1768 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SRC1_INDEX
);
1774 tmp
= tbl
->src
[tmp
];
1778 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_DST_REG
);
1779 dw
[1] |= GEN_SHIFT32(tmp
, GEN6_INST_DST_REG
);
1781 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SRC0_REG
);
1782 dw
[2] |= GEN_SHIFT32(tmp
, GEN6_INST_SRC_REG
);
1784 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SRC1_REG
);
1788 dw
[3] |= GEN_SHIFT32(tmp
, GEN6_INST_SRC_REG
);
1792 toy_compiler_disassemble(const struct ilo_dev_info
*dev
,
1793 const void *kernel
, int size
,
1796 const uint32_t *cur
= (const uint32_t *) kernel
;
1797 const uint32_t *end
= cur
+ size
/ sizeof(*cur
);
1798 struct disasm_printer printer
;
1800 disasm_printer_reset(&printer
);
1803 struct disasm_inst inst
;
1804 const bool compacted
= (cur
[0] & GEN6_INST_CMPTCTRL
);
1805 const uint32_t *dw
= cur
;
1808 cur
+= (compacted
) ? 2 : 4;
1809 /* incomplete instruction */
1814 const uint64_t compact
= (uint64_t) dw
[1] << 32 | dw
[0];
1815 disasm_uncompact(dev
, compact
, temp
);
1820 ilo_printf("0x%08x 0x%08x 0x%08x 0x%08x ",
1821 dw
[0], dw
[1], dw
[2], dw
[3]);
1824 memset(&inst
, 0, sizeof(inst
));
1826 disasm_inst_decode(&inst
, dw
);
1827 inst
.cmpt_ctrl
= compacted
;
1829 disasm_printer_print_inst(&printer
, &inst
);