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_is_null(const struct disasm_inst
*inst
,
884 const struct disasm_operand
*operand
)
886 return (operand
->file
== GEN6_FILE_ARF
&& operand
->reg
== GEN6_ARF_NULL
);
890 disasm_inst_type_size(const struct disasm_inst
*inst
,
891 const struct disasm_operand
*operand
)
893 assert(operand
->file
!= GEN6_FILE_IMM
);
895 switch (operand
->type
) {
896 case GEN6_TYPE_UD
: return 4;
897 case GEN6_TYPE_D
: return 4;
898 case GEN6_TYPE_UW
: return 2;
899 case GEN6_TYPE_W
: return 2;
900 case GEN6_TYPE_UB
: return 1;
901 case GEN6_TYPE_B
: return 1;
902 case GEN7_TYPE_DF
: return 8;
903 case GEN6_TYPE_F
: return 4;
909 disasm_printer_reset(struct disasm_printer
*printer
)
911 printer
->buf
[0] = '\0';
916 disasm_printer_get_string(struct disasm_printer
*printer
)
921 static void _util_printf_format(2, 3)
922 disasm_printer_add(struct disasm_printer
*printer
, const char *format
, ...)
924 const size_t avail
= sizeof(printer
->buf
) - printer
->len
;
928 va_start(ap
, format
);
929 written
= vsnprintf(printer
->buf
+ printer
->len
, avail
, format
, ap
);
933 if (written
< 0 || written
>= avail
) {
934 memcpy(printer
->buf
+ sizeof(printer
->buf
) - 4, "...", 4);
935 printer
->len
= sizeof(printer
->buf
) - 1;
937 printer
->len
+= written
;
942 * Pad to the specified column.
945 disasm_printer_column(struct disasm_printer
*printer
, int col
)
947 int len
= DISASM_PRINTER_COLUMN_WIDTH
* col
;
949 if (len
<= printer
->len
) {
953 /* at least one space */
954 len
= printer
->len
+ 1;
957 if (len
>= sizeof(printer
->buf
)) {
958 len
= sizeof(printer
->buf
) - 1;
960 if (len
<= printer
->len
)
964 memset(printer
->buf
+ printer
->len
, ' ', len
- printer
->len
);
966 printer
->buf
[printer
->len
] = '\0';
970 disasm_printer_add_op(struct disasm_printer
*printer
,
971 const struct disasm_inst
*inst
)
973 if (inst
->pred_ctrl
!= GEN6_PREDCTRL_NONE
) {
974 disasm_printer_add(printer
, "(%c%s%s) ",
975 disasm_inst_pred_inv(inst
),
976 disasm_inst_flag_reg(inst
),
977 disasm_inst_pred_ctrl(inst
));
980 disasm_printer_add(printer
, "%s%s%s%s",
981 disasm_inst_opcode(inst
),
982 disasm_inst_saturate(inst
),
983 disasm_inst_debug_ctrl(inst
),
984 disasm_inst_cond_modifier(inst
));
986 if (inst
->cond_modifier
!= GEN6_COND_NONE
) {
987 switch (inst
->opcode
) {
988 case GEN6_OPCODE_SEL
:
990 case GEN6_OPCODE_WHILE
:
991 /* these do not update flag registers */
994 disasm_printer_add(printer
, ".%s", disasm_inst_flag_reg(inst
));
999 if (inst
->opcode
== GEN6_OPCODE_MATH
)
1000 disasm_printer_add(printer
, " %s", disasm_inst_fc(inst
));
1001 if (inst
->opcode
!= GEN6_OPCODE_NOP
)
1002 disasm_printer_add(printer
, "(%s)", disasm_inst_exec_size(inst
));
1006 disasm_printer_add_operand(struct disasm_printer
*printer
,
1007 const struct disasm_inst
*inst
,
1008 const struct disasm_operand
*operand
)
1013 name
= disasm_inst_file(inst
, operand
, &multi_regs
);
1015 disasm_printer_add(printer
, "%s", name
);
1019 if (operand
->file
== GEN6_FILE_IMM
) {
1020 switch (operand
->type
) {
1022 disasm_printer_add(printer
, "0x%08xUD", inst
->u
.imm32
);
1025 disasm_printer_add(printer
, "%dD", inst
->u
.imm32
);
1028 disasm_printer_add(printer
, "0x%04xUW", (uint16_t) inst
->u
.imm32
);
1031 disasm_printer_add(printer
, "%dW", (int16_t) inst
->u
.imm32
);
1033 case GEN6_TYPE_UV_IMM
:
1034 disasm_printer_add(printer
, "0x%08xUV", inst
->u
.imm32
);
1036 case GEN6_TYPE_VF_IMM
:
1037 disasm_printer_add(printer
, "Vector Float");
1039 case GEN6_TYPE_V_IMM
:
1040 disasm_printer_add(printer
, "0x%08xV", inst
->u
.imm32
);
1043 disasm_printer_add(printer
, "%-gF", uif(inst
->u
.imm32
));
1046 disasm_printer_add(printer
, "BAD");
1053 if (operand
->addr_mode
== GEN6_ADDRMODE_DIRECT
) {
1054 unsigned reg
, subreg
;
1057 if (operand
->file
== GEN6_FILE_ARF
)
1060 subreg
= operand
->subreg
/ disasm_inst_type_size(inst
, operand
);
1063 disasm_printer_add(printer
, "%s%d.%d", name
, reg
, subreg
);
1065 disasm_printer_add(printer
, "%s%d", name
, reg
);
1067 disasm_printer_add(printer
, "%s[a0.%d %d]",
1068 name
, operand
->addr_subreg
, operand
->addr_imm
);
1073 disasm_printer_add_dst(struct disasm_printer
*printer
,
1074 const struct disasm_inst
*inst
,
1075 const struct disasm_dst_operand
*dst
)
1077 disasm_printer_add_operand(printer
, inst
, &dst
->base
);
1079 /* dst is an immediate when in EU_INSTRUCTION_BRANCH_CONDITIONAL form */
1080 if (disasm_inst_is_null(inst
, &dst
->base
) ||
1081 dst
->base
.file
== GEN6_FILE_IMM
)
1084 disasm_printer_add(printer
, "<%s>%s%s",
1085 disasm_inst_horz_stride(inst
, dst
->horz_stride
),
1086 disasm_inst_writemask(inst
, dst
->writemask
),
1087 disasm_inst_type(inst
, &dst
->base
));
1091 disasm_printer_add_src(struct disasm_printer
*printer
,
1092 const struct disasm_inst
*inst
,
1093 const struct disasm_src_operand
*src
)
1095 static const char swizzle_chars
[4] = { 'x', 'y', 'z', 'w' };
1098 disasm_printer_add(printer
, "%s%s",
1099 disasm_inst_negate(inst
, src
->negate
),
1100 disasm_inst_absolute(inst
, src
->absolute
));
1102 disasm_printer_add_operand(printer
, inst
, &src
->base
);
1104 if (disasm_inst_is_null(inst
, &src
->base
) ||
1105 src
->base
.file
== GEN6_FILE_IMM
)
1108 if (src
->swizzle_x
== 0 && src
->swizzle_y
== 1 &&
1109 src
->swizzle_z
== 2 && src
->swizzle_w
== 3) {
1111 } else if (src
->swizzle_x
== src
->swizzle_y
&&
1112 src
->swizzle_x
== src
->swizzle_z
&&
1113 src
->swizzle_x
== src
->swizzle_w
) {
1114 swizzle
[0] = swizzle_chars
[src
->swizzle_x
];
1117 swizzle
[0] = swizzle_chars
[src
->swizzle_x
];
1118 swizzle
[1] = swizzle_chars
[src
->swizzle_y
];
1119 swizzle
[2] = swizzle_chars
[src
->swizzle_z
];
1120 swizzle
[3] = swizzle_chars
[src
->swizzle_w
];
1124 disasm_printer_add(printer
, "<%s,%s,%s>%s%s",
1125 disasm_inst_vert_stride(inst
, src
->vert_stride
),
1126 disasm_inst_width(inst
, src
->width
),
1127 disasm_inst_horz_stride(inst
, src
->horz_stride
),
1129 disasm_inst_type(inst
, &src
->base
));
1133 disasm_printer_add_ctrl(struct disasm_printer
*printer
,
1134 const struct disasm_inst
*inst
)
1136 if (inst
->opcode
== GEN6_OPCODE_NOP
) {
1137 disasm_printer_add(printer
, ";");
1141 disasm_printer_add(printer
, "{%s%s%s%s%s%s%s%s };",
1142 disasm_inst_access_mode(inst
),
1143 disasm_inst_mask_ctrl(inst
),
1144 disasm_inst_dep_ctrl(inst
),
1145 disasm_inst_qtr_ctrl(inst
),
1146 disasm_inst_cmpt_ctrl(inst
),
1147 disasm_inst_thread_ctrl(inst
),
1148 disasm_inst_acc_wr_ctrl(inst
),
1149 disasm_inst_eot(inst
));
1153 disasm_printer_add_mdesc_sampler(struct disasm_printer
*printer
,
1154 const struct disasm_inst
*inst
,
1159 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) {
1160 op
= GEN_EXTRACT(mdesc
, GEN7_MSG_SAMPLER_OP
);
1161 simd
= GEN_EXTRACT(mdesc
, GEN7_MSG_SAMPLER_SIMD
);
1163 op
= GEN_EXTRACT(mdesc
, GEN6_MSG_SAMPLER_OP
);
1164 simd
= GEN_EXTRACT(mdesc
, GEN6_MSG_SAMPLER_SIMD
);
1167 disasm_printer_add(printer
, " (%d, %d, %d, %d)",
1168 GEN_EXTRACT(mdesc
, GEN6_MSG_SAMPLER_SURFACE
),
1169 GEN_EXTRACT(mdesc
, GEN6_MSG_SAMPLER_INDEX
),
1174 disasm_printer_add_mdesc_urb(struct disasm_printer
*printer
,
1175 const struct disasm_inst
*inst
,
1180 bool interleaved
, complete
, allocate
, used
;
1182 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) {
1183 switch (GEN_EXTRACT(mdesc
, GEN7_MSG_URB_OP
)) {
1184 case GEN7_MSG_URB_WRITE_HWORD
: op
= "write HWord"; break;
1185 case GEN7_MSG_URB_WRITE_OWORD
: op
= "write OWord"; break;
1186 case GEN7_MSG_URB_READ_HWORD
: op
= "read HWord"; break;
1187 case GEN7_MSG_URB_READ_OWORD
: op
= "read OWord"; break;
1188 case GEN7_MSG_URB_ATOMIC_MOV
: op
= "atomic mov"; break;
1189 case GEN7_MSG_URB_ATOMIC_INC
: op
= "atomic inc"; break;
1190 default: op
= "BAD"; break;
1193 offset
= GEN_EXTRACT(mdesc
, GEN7_MSG_URB_GLOBAL_OFFSET
);
1194 interleaved
= mdesc
& GEN7_MSG_URB_INTERLEAVED
;
1195 complete
= mdesc
& GEN7_MSG_URB_COMPLETE
;
1200 switch (GEN_EXTRACT(mdesc
, GEN6_MSG_URB_OP
)) {
1201 case GEN6_MSG_URB_WRITE
: op
= "urb_write"; break;
1202 case GEN6_MSG_URB_FF_SYNC
: op
= "ff_sync"; break;
1203 default: op
= "BAD"; break;
1206 offset
= GEN_EXTRACT(mdesc
, GEN6_MSG_URB_OFFSET
);
1207 interleaved
= mdesc
& GEN6_MSG_URB_INTERLEAVED
;
1208 complete
= mdesc
& GEN6_MSG_URB_COMPLETE
;
1210 allocate
= mdesc
& GEN6_MSG_URB_ALLOCATE
;
1211 used
= mdesc
& GEN6_MSG_URB_USED
;
1214 disasm_printer_add(printer
, " %d %s%s%s%s%s", offset
, op
,
1215 (interleaved
) ? " interleave" : "",
1216 (allocate
) ? " allocate" : "",
1217 (used
) ? " used" : "",
1218 (complete
) ? " complete" : "");
1222 disasm_printer_add_mdesc_spawner(struct disasm_printer
*printer
,
1223 const struct disasm_inst
*inst
,
1228 switch (mdesc
& GEN6_MSG_TS_REQUESTER_TYPE__MASK
) {
1229 case GEN6_MSG_TS_REQUESTER_TYPE_ROOT
: from
= "root"; break;
1230 case GEN6_MSG_TS_REQUESTER_TYPE_CHILD
: from
= "child"; break;
1231 default: from
= "BAD"; break;
1234 disasm_printer_add(printer
, "(%s thread ", from
);
1236 switch (mdesc
& GEN6_MSG_TS_OPCODE__MASK
) {
1237 case GEN6_MSG_TS_OPCODE_DEREF
:
1238 disasm_printer_add(printer
, "%sderef",
1239 (mdesc
& GEN6_MSG_TS_RESOURCE_SELECT_NO_DEREF
) ? "no " : "");
1241 case GEN6_MSG_TS_OPCODE_SPAWN
:
1242 disasm_printer_add(printer
, "spawn %s)",
1243 (mdesc
& GEN6_MSG_TS_RESOURCE_SELECT_ROOT
) ? "root" : "child");
1246 disasm_printer_add(printer
, "BAD");
1250 disasm_printer_add(printer
, ")");
1254 disasm_printer_add_mdesc_dp_sampler(struct disasm_printer
*printer
,
1255 const struct disasm_inst
*inst
,
1258 const int op
= (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) ?
1259 GEN_EXTRACT(mdesc
, GEN7_MSG_DP_OP
) : GEN_EXTRACT(mdesc
, GEN6_MSG_DP_OP
);
1260 const bool write_commit
= (ilo_dev_gen(inst
->dev
) == ILO_GEN(6)) ?
1261 (mdesc
& GEN6_MSG_DP_SEND_WRITE_COMMIT
) : 0;
1263 disasm_printer_add(printer
, " (%d, %d, %d, %d)",
1264 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
),
1265 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_OWORD_BLOCK_SIZE
),
1270 disasm_printer_add_mdesc_dp_dc0(struct disasm_printer
*printer
,
1271 const struct disasm_inst
*inst
,
1274 const int op
= GEN_EXTRACT(mdesc
, GEN7_MSG_DP_OP
);
1277 ILO_DEV_ASSERT(inst
->dev
, 7, 7.5);
1279 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7.5)) {
1281 case GEN75_MSG_DP_DC0_OWORD_BLOCK_READ
: str
= "OWORD block read"; break;
1282 case GEN75_MSG_DP_DC0_UNALIGNED_OWORD_BLOCK_READ
: str
= "unaligned OWORD block read"; break;
1283 case GEN75_MSG_DP_DC0_OWORD_DUAL_BLOCK_READ
: str
= "OWORD dual block read"; break;
1284 case GEN75_MSG_DP_DC0_DWORD_SCATTERED_READ
: str
= "DWORD scattered read"; break;
1285 case GEN75_MSG_DP_DC0_BYTE_SCATTERED_READ
: str
= "BYTE scattered read"; break;
1286 case GEN75_MSG_DP_DC0_MEMORY_FENCE
: str
= "memory fence"; break;
1287 case GEN75_MSG_DP_DC0_OWORD_BLOCK_WRITE
: str
= "OWORD block write"; break;
1288 case GEN75_MSG_DP_DC0_OWORD_DUAL_BLOCK_WRITE
: str
= "OWORD dual block write"; break;
1289 case GEN75_MSG_DP_DC0_DWORD_SCATTERED_WRITE
: str
= "OWORD scattered write"; break;
1290 case GEN75_MSG_DP_DC0_BYTE_SCATTERED_WRITE
: str
= "BYTE scattered write"; break;
1291 default: str
= "BAD"; break;
1295 case GEN7_MSG_DP_DC0_OWORD_BLOCK_READ
: str
= "OWORD block read"; break;
1296 case GEN7_MSG_DP_DC0_UNALIGNED_OWORD_BLOCK_READ
: str
= "unaligned OWORD block read"; break;
1297 case GEN7_MSG_DP_DC0_OWORD_DUAL_BLOCK_READ
: str
= "OWORD dual block read"; break;
1298 case GEN7_MSG_DP_DC0_DWORD_SCATTERED_READ
: str
= "DWORD scattered read"; break;
1299 case GEN7_MSG_DP_DC0_BYTE_SCATTERED_READ
: str
= "BYTE scattered read"; break;
1300 case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_READ
: str
= "untyped surface read"; break;
1301 case GEN7_MSG_DP_DC0_UNTYPED_ATOMIC_OP
: str
= "untyped atomic op"; break;
1302 case GEN7_MSG_DP_DC0_MEMORY_FENCE
: str
= "memory fence"; break;
1303 case GEN7_MSG_DP_DC0_OWORD_BLOCK_WRITE
: str
= "OWORD block write"; break;
1304 case GEN7_MSG_DP_DC0_OWORD_DUAL_BLOCK_WRITE
: str
= "OWORD dual block write"; break;
1305 case GEN7_MSG_DP_DC0_DWORD_SCATTERED_WRITE
: str
= "OWORD scattered write"; break;
1306 case GEN7_MSG_DP_DC0_BYTE_SCATTERED_WRITE
: str
= "BYTE scattered write"; break;
1307 case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_WRITE
: str
= "untyped surface write"; break;
1308 default: str
= "BAD"; break;
1312 disasm_printer_add(printer
, "(%s, Surface = %d, ",
1313 str
, GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1315 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7.5)) {
1316 disasm_printer_add(printer
, "0x%x",
1317 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_CTRL
));
1320 case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_READ
:
1321 case GEN7_MSG_DP_DC0_UNTYPED_SURFACE_WRITE
:
1322 switch (mdesc
& GEN7_MSG_DP_UNTYPED_MODE__MASK
) {
1323 case GEN7_MSG_DP_UNTYPED_MODE_SIMD4X2
: str
= "4x2"; break;
1324 case GEN7_MSG_DP_UNTYPED_MODE_SIMD16
: str
= "16"; break;
1325 case GEN7_MSG_DP_UNTYPED_MODE_SIMD8
: str
= "8"; break;
1326 default: str
= "BAD"; break;
1329 disasm_printer_add(printer
, "SIMD%s, Mask = 0x%x",
1330 str
, GEN_EXTRACT(mdesc
, GEN7_MSG_DP_UNTYPED_MASK
));
1333 disasm_printer_add(printer
, "0x%x",
1334 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_CTRL
));
1339 disasm_printer_add(printer
, ")");
1343 disasm_printer_add_mdesc_dp_dc1(struct disasm_printer
*printer
,
1344 const struct disasm_inst
*inst
,
1347 const int op
= GEN_EXTRACT(mdesc
, GEN7_MSG_DP_OP
);
1350 ILO_DEV_ASSERT(inst
->dev
, 7.5, 7.5);
1353 case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_READ
: str
= "untyped surface read"; break;
1354 case GEN75_MSG_DP_DC1_UNTYPED_ATOMIC_OP
: str
= "DC untyped atomic op"; break;
1355 case GEN75_MSG_DP_DC1_UNTYPED_ATOMIC_OP_SIMD4X2
: str
= "DC untyped 4x2 atomic op"; break;
1356 case GEN75_MSG_DP_DC1_MEDIA_BLOCK_READ
: str
= "DC media block read"; break;
1357 case GEN75_MSG_DP_DC1_TYPED_SURFACE_READ
: str
= "DC typed surface read"; break;
1358 case GEN75_MSG_DP_DC1_TYPED_ATOMIC_OP
: str
= "DC typed atomic"; break;
1359 case GEN75_MSG_DP_DC1_TYPED_ATOMIC_OP_SIMD4X2
: str
= "DC typed 4x2 atomic op"; break;
1360 case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_WRITE
: str
= "DC untyped surface write"; break;
1361 case GEN75_MSG_DP_DC1_MEDIA_BLOCK_WRITE
: str
= "DC media block write"; break;
1362 case GEN75_MSG_DP_DC1_ATOMIC_COUNTER_OP
: str
= "DC atomic counter op"; break;
1363 case GEN75_MSG_DP_DC1_ATOMIC_COUNTER_OP_SIMD4X2
: str
= "DC 4x2 atomic counter op"; break;
1364 case GEN75_MSG_DP_DC1_TYPED_SURFACE_WRITE
: str
= "DC typed surface write"; break;
1365 default: str
= "BAD"; break;
1368 disasm_printer_add(printer
, "(%s, Surface = %d, ",
1369 str
, GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1372 case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_READ
:
1373 case GEN75_MSG_DP_DC1_UNTYPED_SURFACE_WRITE
:
1374 switch (mdesc
& GEN7_MSG_DP_UNTYPED_MODE__MASK
) {
1375 case GEN7_MSG_DP_UNTYPED_MODE_SIMD4X2
: str
= "4x2"; break;
1376 case GEN7_MSG_DP_UNTYPED_MODE_SIMD16
: str
= "16"; break;
1377 case GEN7_MSG_DP_UNTYPED_MODE_SIMD8
: str
= "8"; break;
1378 default: str
= "BAD"; break;
1381 disasm_printer_add(printer
, "SIMD%s, Mask = 0x%x",
1382 str
, GEN_EXTRACT(mdesc
, GEN7_MSG_DP_UNTYPED_MASK
));
1384 case GEN75_MSG_DP_DC1_UNTYPED_ATOMIC_OP
:
1385 case GEN75_MSG_DP_DC1_UNTYPED_ATOMIC_OP_SIMD4X2
:
1386 case GEN75_MSG_DP_DC1_MEDIA_BLOCK_READ
:
1387 case GEN75_MSG_DP_DC1_TYPED_SURFACE_READ
:
1388 case GEN75_MSG_DP_DC1_TYPED_ATOMIC_OP
:
1389 case GEN75_MSG_DP_DC1_TYPED_ATOMIC_OP_SIMD4X2
:
1390 case GEN75_MSG_DP_DC1_MEDIA_BLOCK_WRITE
:
1391 case GEN75_MSG_DP_DC1_ATOMIC_COUNTER_OP
:
1392 case GEN75_MSG_DP_DC1_ATOMIC_COUNTER_OP_SIMD4X2
:
1393 case GEN75_MSG_DP_DC1_TYPED_SURFACE_WRITE
:
1395 disasm_printer_add(printer
, "0x%x",
1396 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_CTRL
));
1400 disasm_printer_add(printer
, ")");
1404 disasm_printer_add_mdesc_dp_rc(struct disasm_printer
*printer
,
1405 const struct disasm_inst
*inst
,
1408 const int op
= (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) ?
1409 GEN_EXTRACT(mdesc
, GEN7_MSG_DP_OP
) : GEN_EXTRACT(mdesc
, GEN6_MSG_DP_OP
);
1413 if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7.5)) {
1415 case GEN75_MSG_DP_RC_MEDIA_BLOCK_READ
: str
= "media block read"; break;
1416 case GEN75_MSG_DP_RC_MEMORY_FENCE
: str
= "memory fence"; break;
1417 case GEN75_MSG_DP_RC_MEDIA_BLOCK_WRITE
: str
= "media block write"; break;
1418 case GEN75_MSG_DP_RC_RT_WRITE
: str
= "RT write"; break;
1419 default: str
= "BAD"; break;
1422 is_rt_write
= (op
== GEN75_MSG_DP_RC_RT_WRITE
);
1423 } else if (ilo_dev_gen(inst
->dev
) >= ILO_GEN(7)) {
1425 case GEN7_MSG_DP_RC_MEDIA_BLOCK_READ
: str
= "media block read"; break;
1426 case GEN7_MSG_DP_RC_TYPED_SURFACE_READ
: str
= "typed surface read"; break;
1427 case GEN7_MSG_DP_RC_TYPED_ATOMIC_OP
: str
= "typed atomic op"; break;
1428 case GEN7_MSG_DP_RC_MEMORY_FENCE
: str
= "memory fence"; break;
1429 case GEN7_MSG_DP_RC_MEDIA_BLOCK_WRITE
: str
= "media block write"; break;
1430 case GEN7_MSG_DP_RC_RT_WRITE
: str
= "RT write"; break;
1431 case GEN7_MSG_DP_RC_TYPED_SURFACE_WRITE
: str
= "typed surface write"; break;
1432 default: str
= "BAD"; break;
1435 is_rt_write
= (op
== GEN7_MSG_DP_RC_RT_WRITE
);
1438 case GEN6_MSG_DP_OWORD_BLOCK_READ
: str
= "OWORD block read"; break;
1439 case GEN6_MSG_DP_RT_UNORM_READ
: str
= "RT UNORM read"; break;
1440 case GEN6_MSG_DP_OWORD_DUAL_BLOCK_READ
: str
= "OWORD dual block read"; break;
1441 case GEN6_MSG_DP_MEDIA_BLOCK_READ
: str
= "media block read"; break;
1442 case GEN6_MSG_DP_UNALIGNED_OWORD_BLOCK_READ
: str
= "unaligned OWORD block read"; break;
1443 case GEN6_MSG_DP_DWORD_SCATTERED_READ
: str
= "DWORD scattered read"; break;
1444 case GEN6_MSG_DP_DWORD_ATOMIC_WRITE
: str
= "DWORD atomic write"; break;
1445 case GEN6_MSG_DP_OWORD_BLOCK_WRITE
: str
= "OWORD block write"; break;
1446 case GEN6_MSG_DP_OWORD_DUAL_BLOCK_WRITE
: str
= "OWORD dual block_write"; break;
1447 case GEN6_MSG_DP_MEDIA_BLOCK_WRITE
: str
= "media block write"; break;
1448 case GEN6_MSG_DP_DWORD_SCATTERED_WRITE
: str
= "DWORD scattered write"; break;
1449 case GEN6_MSG_DP_RT_WRITE
: str
= "RT write"; break;
1450 case GEN6_MSG_DP_SVB_WRITE
: str
= "SVB write"; break;
1451 case GEN6_MSG_DP_RT_UNORM_WRITE
: str
= "RT UNORM write"; break;
1452 default: str
= "BAD"; break;
1455 is_rt_write
= (op
== GEN6_MSG_DP_RT_WRITE
);
1458 disasm_printer_add(printer
, " %s", str
);
1461 switch (mdesc
& GEN6_MSG_DP_RT_MODE__MASK
) {
1462 case GEN6_MSG_DP_RT_MODE_SIMD16
: str
= "SIMD16"; break;
1463 case GEN6_MSG_DP_RT_MODE_SIMD16_REPDATA
: str
= "SIMD16/RepData"; break;
1464 case GEN6_MSG_DP_RT_MODE_SIMD8_DUALSRC_LO
: str
= "SIMD8/DualSrcLow"; break;
1465 case GEN6_MSG_DP_RT_MODE_SIMD8_DUALSRC_HI
: str
= "SIMD8/DualSrcHigh"; break;
1466 case GEN6_MSG_DP_RT_MODE_SIMD8_LO
: str
= "SIMD8"; break;
1467 case GEN6_MSG_DP_RT_MODE_SIMD8_IMAGE_WR
: str
= "SIMD8/ImageWrite"; break;
1468 default: str
= "BAD"; break;
1471 disasm_printer_add(printer
, " %s%s%s%s", str
,
1472 (mdesc
& GEN6_MSG_DP_SLOTGRP_HI
) ? " Hi" : "",
1473 (mdesc
& GEN6_MSG_DP_RT_LAST
) ? " LastRT" : "",
1474 (ilo_dev_gen(inst
->dev
) == ILO_GEN(6) &&
1475 (mdesc
& GEN6_MSG_DP_SEND_WRITE_COMMIT
)) ? " WriteCommit" : "");
1478 disasm_printer_add(printer
, " Surface = %d",
1479 GEN_EXTRACT(mdesc
, GEN6_MSG_DP_SURFACE
));
1483 disasm_printer_add_mdesc(struct disasm_printer
*printer
,
1484 const struct disasm_inst
*inst
)
1486 const uint32_t mdesc
= inst
->u
.imm32
;
1488 assert(inst
->opcode
== GEN6_OPCODE_SEND
||
1489 inst
->opcode
== GEN6_OPCODE_SENDC
);
1490 assert(inst
->src1
.base
.file
== GEN6_FILE_IMM
);
1492 disasm_printer_add(printer
, " %s", disasm_inst_sfid(inst
));
1494 switch (inst
->sfid
) {
1495 case GEN6_SFID_SAMPLER
:
1496 disasm_printer_add_mdesc_sampler(printer
, inst
, mdesc
);
1498 case GEN6_SFID_DP_SAMPLER
:
1499 disasm_printer_add_mdesc_dp_sampler(printer
, inst
, mdesc
);
1501 case GEN6_SFID_DP_RC
:
1502 disasm_printer_add_mdesc_dp_rc(printer
, inst
, mdesc
);
1505 disasm_printer_add_mdesc_urb(printer
, inst
, mdesc
);
1507 case GEN6_SFID_SPAWNER
:
1508 disasm_printer_add_mdesc_spawner(printer
, inst
, mdesc
);
1510 case GEN7_SFID_DP_DC0
:
1511 disasm_printer_add_mdesc_dp_dc0(printer
, inst
, mdesc
);
1513 case GEN75_SFID_DP_DC1
:
1514 disasm_printer_add_mdesc_dp_dc1(printer
, inst
, mdesc
);
1516 case GEN6_SFID_DP_CC
:
1522 disasm_printer_add(printer
, " mlen %d rlen %d",
1523 GEN_EXTRACT(mdesc
, GEN6_MSG_MLEN
),
1524 GEN_EXTRACT(mdesc
, GEN6_MSG_RLEN
));
1528 disasm_printer_print_inst(struct disasm_printer
*printer
,
1529 const struct disasm_inst
*inst
)
1533 disasm_printer_reset(printer
);
1535 disasm_printer_column(printer
, col
++);
1536 disasm_printer_add_op(printer
, inst
);
1538 if (inst
->has_jip
|| inst
->has_uip
) {
1539 if (inst
->has_jip
) {
1540 disasm_printer_column(printer
, col
++);
1541 disasm_printer_add(printer
, "JIP: %d", (int16_t) inst
->u
.imm32
);
1544 if (inst
->has_uip
) {
1545 disasm_printer_column(printer
, col
++);
1546 disasm_printer_add(printer
, "UIP: %d",
1547 (int16_t) (inst
->u
.imm32
>> 16));
1550 const int src_count
= disasm_opcode_table
[inst
->opcode
].src_count
;
1553 const struct disasm_src_operand
*src
[3] = {
1554 &inst
->src0
, &inst
->src1
, &inst
->u
.src2
1558 disasm_printer_column(printer
, col
++);
1559 disasm_printer_add_dst(printer
, inst
, &inst
->dst
);
1561 for (i
= 0; i
< src_count
; i
++) {
1562 disasm_printer_column(printer
, col
++);
1563 disasm_printer_add_src(printer
, inst
, src
[i
]);
1568 if (inst
->opcode
== GEN6_OPCODE_SEND
||
1569 inst
->opcode
== GEN6_OPCODE_SENDC
) {
1570 /* start a new line */
1571 ilo_printf("%s\n", disasm_printer_get_string(printer
));
1572 disasm_printer_reset(printer
);
1575 disasm_printer_column(printer
, col
++);
1577 disasm_printer_column(printer
, col
++);
1578 disasm_printer_add_mdesc(printer
, inst
);
1584 disasm_printer_column(printer
, col
++);
1585 disasm_printer_add_ctrl(printer
, inst
);
1587 ilo_printf("%s\n", disasm_printer_get_string(printer
));
1591 disasm_uncompact(const struct ilo_dev_info
*dev
,
1592 uint64_t compact
, uint32_t *dw
)
1594 const struct toy_compaction_table
*tbl
=
1595 toy_compiler_get_compaction_table(dev
);
1599 memset(dw
, 0, sizeof(*dw
) * 4);
1601 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_OPCODE
);
1602 dw
[0] |= GEN_SHIFT32(tmp
, GEN6_INST_OPCODE
);
1604 if (ilo_dev_gen(dev
) >= ILO_GEN(7) && (compact
& GEN6_COMPACT_DEBUGCTRL
))
1605 dw
[0] |= GEN6_INST_DEBUGCTRL
;
1608 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_CONTROL_INDEX
);
1609 tmp
= tbl
->control
[tmp
];
1611 dw
[0] |= (tmp
& 0xffff) << GEN6_INST_ACCESSMODE__SHIFT
;
1613 dw
[0] |= GEN6_INST_SATURATE
;
1615 if (ilo_dev_gen(dev
) >= ILO_GEN(7))
1616 dw
[2] |= (tmp
>> 17) << GEN6_INST_FLAG_SUBREG__SHIFT
;
1619 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_DATATYPE_INDEX
);
1620 tmp
= tbl
->datatype
[tmp
];
1622 dw
[1] |= (tmp
& 0x7fff) << GEN6_INST_DST_FILE__SHIFT
;
1623 dw
[1] |= (tmp
>> 15) << GEN6_INST_DST_HORZSTRIDE__SHIFT
;
1626 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SUBREG_INDEX
);
1627 tmp
= tbl
->subreg
[tmp
];
1629 dw
[1] |= (tmp
& 0x1f) << 16;
1630 dw
[2] |= ((tmp
>> 5) & 0x1f);
1631 dw
[3] |= ((tmp
>> 10) & 0x1f);
1633 if (compact
& GEN6_COMPACT_ACCWRCTRL
)
1634 dw
[0] |= GEN6_INST_ACCWRCTRL
;
1636 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_CONDMODIFIER
);
1637 dw
[0] |= GEN_SHIFT32(tmp
, GEN6_INST_CONDMODIFIER
);
1639 if (ilo_dev_gen(dev
) == ILO_GEN(6)) {
1640 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_FLAG_SUBREG
);
1641 dw
[2] |= GEN_SHIFT32(compact
, GEN6_INST_FLAG_SUBREG
);
1644 assert(compact
& GEN6_COMPACT_CMPTCTRL
);
1647 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SRC0_INDEX
);
1648 tmp
= tbl
->src
[tmp
];
1651 src_is_imm
= (GEN_EXTRACT(dw
[1], GEN6_INST_SRC0_FILE
) == GEN6_FILE_IMM
) ||
1652 (GEN_EXTRACT(dw
[1], GEN6_INST_SRC1_FILE
) == GEN6_FILE_IMM
);
1655 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SRC1_INDEX
);
1661 tmp
= tbl
->src
[tmp
];
1665 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_DST_REG
);
1666 dw
[1] |= GEN_SHIFT32(tmp
, GEN6_INST_DST_REG
);
1668 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SRC0_REG
);
1669 dw
[2] |= GEN_SHIFT32(tmp
, GEN6_INST_SRC_REG
);
1671 tmp
= GEN_EXTRACT(compact
, GEN6_COMPACT_SRC1_REG
);
1675 dw
[3] |= GEN_SHIFT32(tmp
, GEN6_INST_SRC_REG
);
1679 toy_compiler_disassemble(const struct ilo_dev_info
*dev
,
1680 const void *kernel
, int size
,
1683 const uint32_t *cur
= (const uint32_t *) kernel
;
1684 const uint32_t *end
= cur
+ size
/ sizeof(*cur
);
1685 struct disasm_printer printer
;
1687 disasm_printer_reset(&printer
);
1690 struct disasm_inst inst
;
1691 const bool compacted
= (cur
[0] & GEN6_INST_CMPTCTRL
);
1692 const uint32_t *dw
= cur
;
1695 cur
+= (compacted
) ? 2 : 4;
1696 /* incomplete instruction */
1701 const uint64_t compact
= (uint64_t) dw
[1] << 32 | dw
[0];
1702 disasm_uncompact(dev
, compact
, temp
);
1707 ilo_printf("0x%08x 0x%08x 0x%08x 0x%08x ",
1708 dw
[0], dw
[1], dw
[2], dw
[3]);
1711 memset(&inst
, 0, sizeof(inst
));
1713 disasm_inst_decode(&inst
, dw
);
1714 inst
.cmpt_ctrl
= compacted
;
1716 disasm_printer_print_inst(&printer
, &inst
);