2 * Copyright (c) 2016 Etnaviv Project
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 * Christian Gmeiner <christian.gmeiner@gmail.com>
27 #include "etnaviv_disasm.h"
34 #include "hw/isa.xml.h"
42 uint32_t dst_amode
: 3;
44 uint32_t dst_comps
: 4;
48 uint32_t tex_amode
: 3;
49 uint32_t tex_swiz
: 8;
50 uint32_t src0_use
: 1;
51 uint32_t src0_reg
: 9;
52 uint32_t type_bit2
: 1;
53 uint32_t src0_swiz
: 8;
54 uint32_t src0_neg
: 1;
55 uint32_t src0_abs
: 1;
58 uint32_t src0_amode
: 3;
59 uint32_t src0_rgroup
: 3;
60 uint32_t src1_use
: 1;
61 uint32_t src1_reg
: 9;
62 uint32_t opcode_bit6
: 1;
63 uint32_t src1_swiz
: 8;
64 uint32_t src1_neg
: 1;
65 uint32_t src1_abs
: 1;
66 uint32_t src1_amode
: 3;
67 uint32_t type_bit01
: 2;
72 uint32_t src1_rgroup
: 3;
73 uint32_t src2_use
: 1;
74 uint32_t src2_reg
: 9;
76 uint32_t src2_swiz
: 8;
77 uint32_t src2_neg
: 1;
78 uint32_t src2_abs
: 1;
80 uint32_t src2_amode
: 3;
81 uint32_t src2_rgroup
: 3;
111 struct opc_operands
{
112 struct dst_operand
*dst
;
113 struct tex_operand
*tex
;
114 struct src_operand
*src0
;
115 struct src_operand
*src1
;
116 struct src_operand
*src2
;
122 printf_type(uint8_t type
)
126 /* as f32 is the default print nothing */
164 print_condition(uint8_t condition
)
167 case INST_CONDITION_TRUE
:
170 case INST_CONDITION_GT
:
174 case INST_CONDITION_LT
:
178 case INST_CONDITION_GE
:
182 case INST_CONDITION_LE
:
186 case INST_CONDITION_EQ
:
190 case INST_CONDITION_NE
:
194 case INST_CONDITION_AND
:
198 case INST_CONDITION_OR
:
202 case INST_CONDITION_XOR
:
206 case INST_CONDITION_NOT
:
210 case INST_CONDITION_NZ
:
214 case INST_CONDITION_GEZ
:
218 case INST_CONDITION_GZ
:
222 case INST_CONDITION_LEZ
:
226 case INST_CONDITION_LZ
:
237 print_rgroup(uint8_t rgoup
)
240 case INST_RGROUP_TEMP
:
244 case INST_RGROUP_INTERNAL
:
248 case INST_RGROUP_UNIFORM_0
:
249 case INST_RGROUP_UNIFORM_1
:
256 print_components(uint8_t components
)
258 if (components
== 15)
262 if (components
& INST_COMPS_X
)
267 if (components
& INST_COMPS_Y
)
272 if (components
& INST_COMPS_Z
)
277 if (components
& INST_COMPS_W
)
284 print_swiz_comp(uint8_t swiz_comp
)
287 case INST_SWIZ_COMP_X
:
291 case INST_SWIZ_COMP_Y
:
295 case INST_SWIZ_COMP_Z
:
299 case INST_SWIZ_COMP_W
:
310 print_swiz(uint8_t swiz
)
316 const unsigned x
= swiz
& 0x3;
317 const unsigned y
= (swiz
& 0x0C) >> 2;
318 const unsigned z
= (swiz
& 0x30) >> 4;
319 const unsigned w
= (swiz
& 0xc0) >> 6;
329 print_amode(uint8_t amode
)
332 case INST_AMODE_DIRECT
:
333 /* nothing to output */
336 case INST_AMODE_ADD_A_X
:
340 case INST_AMODE_ADD_A_Y
:
344 case INST_AMODE_ADD_A_Z
:
348 case INST_AMODE_ADD_A_W
:
359 print_dst(struct dst_operand
*dst
, bool sep
)
362 printf("t%u", dst
->reg
);
363 print_amode(dst
->amode
);
364 print_components(dst
->comps
);
374 print_tex(struct tex_operand
*tex
, bool sep
)
376 printf("tex%u", tex
->id
);
377 print_amode(tex
->amode
);
378 print_swiz(tex
->swiz
);
385 print_src(struct src_operand
*src
, bool sep
)
394 if (src
->rgroup
== INST_RGROUP_UNIFORM_1
)
397 print_rgroup(src
->rgroup
);
398 printf("%u", src
->reg
);
399 print_amode(src
->amode
);
400 print_swiz(src
->swiz
);
413 print_opc_default(struct opc_operands
*operands
)
415 print_dst(operands
->dst
, true);
416 print_src(operands
->src0
, true);
417 print_src(operands
->src1
, true);
418 print_src(operands
->src2
, false);
422 print_opc_mov(struct opc_operands
*operands
)
425 printf("a%u", operands
->dst
->reg
);
426 print_components(operands
->dst
->comps
);
429 print_src(operands
->src0
, true);
430 print_src(operands
->src1
, true);
431 print_src(operands
->src2
, false);
435 print_opc_tex(struct opc_operands
*operands
)
437 print_dst(operands
->dst
, true);
438 print_tex(operands
->tex
, true);
439 print_src(operands
->src0
, true);
440 print_src(operands
->src1
, true);
441 print_src(operands
->src2
, false);
445 print_opc_imm(struct opc_operands
*operands
)
447 print_dst(operands
->dst
, true);
448 print_src(operands
->src0
, true);
449 print_src(operands
->src1
, true);
450 printf("label_%04d", operands
->imm
);
455 static const struct opc_info
{
457 void (*print
)(struct opc_operands
*operands
);
458 } opcs
[1 << OPC_BITS
] = {
459 #define OPC(opc) [INST_OPCODE_##opc] = {#opc, print_opc_default}
460 #define OPC_MOV(opc) [INST_OPCODE_##opc] = {#opc, print_opc_mov}
461 #define OPC_TEX(opc) [INST_OPCODE_##opc] = {#opc, print_opc_tex}
462 #define OPC_IMM(opc) [INST_OPCODE_##opc] = {#opc, print_opc_imm}
520 print_instr(uint32_t *dwords
, int n
, enum debug_t debug
)
522 struct instr
*instr
= (struct instr
*)dwords
;
523 const unsigned opc
= instr
->opc
| (instr
->opcode_bit6
<< 6);
524 const char *name
= opcs
[opc
].name
;
527 if (debug
& PRINT_RAW
)
528 printf("%08x %08x %08x %08x ", dwords
[0], dwords
[1], dwords
[2],
533 struct dst_operand dst
= {
534 .use
= instr
->dst_use
,
535 .amode
= instr
->dst_amode
,
536 .reg
= instr
->dst_reg
,
537 .comps
= instr
->dst_comps
540 struct tex_operand tex
= {
542 .amode
= instr
->tex_amode
,
543 .swiz
= instr
->tex_swiz
,
546 struct src_operand src0
= {
547 .use
= instr
->src0_use
,
548 .neg
= instr
->src0_neg
,
549 .abs
= instr
->src0_abs
,
550 .rgroup
= instr
->src0_rgroup
,
551 .reg
= instr
->src0_reg
,
552 .swiz
= instr
->src0_swiz
,
553 .amode
= instr
->src0_amode
,
556 struct src_operand src1
= {
557 .use
= instr
->src1_use
,
558 .neg
= instr
->src1_neg
,
559 .abs
= instr
->src1_abs
,
560 .rgroup
= instr
->src1_rgroup
,
561 .reg
= instr
->src1_reg
,
562 .swiz
= instr
->src1_swiz
,
563 .amode
= instr
->src1_amode
,
566 struct src_operand src2
= {
567 .use
= instr
->src2_use
,
568 .neg
= instr
->src2_neg
,
569 .abs
= instr
->src2_abs
,
570 .rgroup
= instr
->src2_rgroup
,
571 .reg
= instr
->src2_reg
,
572 .swiz
= instr
->src2_swiz
,
573 .amode
= instr
->src2_amode
,
576 int imm
= (instr
->dword3
& VIV_ISA_WORD_3_SRC2_IMM__MASK
)
577 >> VIV_ISA_WORD_3_SRC2_IMM__SHIFT
;
579 struct opc_operands operands
= {
588 uint8_t type
= instr
->type_bit01
| (instr
->type_bit2
<< 2);
594 print_condition(instr
->cond
);
596 opcs
[opc
].print(&operands
);
598 printf("unknown (%d)", instr
->opc
);
605 etna_disasm(uint32_t *dwords
, int sizedwords
, enum debug_t debug
)
609 assert((sizedwords
% 2) == 0);
611 for (i
= 0; i
< sizedwords
; i
+= 4)
612 print_instr(&dwords
[i
], i
/ 4, debug
);