diff options
author | Christian Gmeiner <cgmeiner@igalia.com> | 2022-12-01 18:53:18 +0100 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-12-16 14:34:18 +0000 |
commit | 64caf906328dad0491a07898cf4b6382f4baab35 (patch) | |
tree | 6f9c32470cb1db752dc9ce34987c3e06423c8d20 | |
parent | fa0ff0849c5d96534195d276658aa8211d115076 (diff) |
etnaviv: disassembler: Switch to isaspec
Use the power of isaspec for our integrated disassembler.
Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20144>
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_disasm.c | 615 | ||||
-rw-r--r-- | src/gallium/drivers/etnaviv/meson.build | 2 |
2 files changed, 15 insertions, 602 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_disasm.c b/src/gallium/drivers/etnaviv/etnaviv_disasm.c index 70c75339a20..7ac6f1fec8b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_disasm.c +++ b/src/gallium/drivers/etnaviv/etnaviv_disasm.c @@ -24,617 +24,30 @@ * Christian Gmeiner <christian.gmeiner@gmail.com> */ -#include "etnaviv_disasm.h" -#include "etnaviv_asm.h" - #include <assert.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> - -#include "hw/isa.xml.h" -#include "util/u_math.h" -#include "util/half_float.h" - -struct instr { - /* dword0: */ - uint32_t opc : 6; - uint32_t cond : 5; - uint32_t sat : 1; - uint32_t dst_use : 1; - uint32_t dst_amode : 3; - uint32_t dst_reg : 7; - uint32_t dst_comps : 4; - uint32_t tex_id : 5; - - /* dword1: */ - uint32_t tex_amode : 3; - uint32_t tex_swiz : 8; - uint32_t src0_use : 1; - uint32_t src0_reg : 9; - uint32_t type_bit2 : 1; - uint32_t src0_swiz : 8; - uint32_t src0_neg : 1; - uint32_t src0_abs : 1; - - /* dword2: */ - uint32_t src0_amode : 3; - uint32_t src0_rgroup : 3; - uint32_t src1_use : 1; - uint32_t src1_reg : 9; - uint32_t opcode_bit6 : 1; - uint32_t src1_swiz : 8; - uint32_t src1_neg : 1; - uint32_t src1_abs : 1; - uint32_t src1_amode : 3; - uint32_t type_bit01 : 2; - - /* dword3: */ - union { - struct { - uint32_t src1_rgroup : 3; - uint32_t src2_use : 1; - uint32_t src2_reg : 9; - uint32_t sel_0 : 1; - uint32_t src2_swiz : 8; - uint32_t src2_neg : 1; - uint32_t src2_abs : 1; - uint32_t sel_1 : 1; - uint32_t src2_amode : 3; - uint32_t src2_rgroup : 3; - uint32_t dst_full : 1; - }; - uint32_t dword3; - }; -}; -struct opc_operands { - struct etna_inst_dst *dst; - struct etna_inst_tex *tex; - struct etna_inst_src *src0; - struct etna_inst_src *src1; - struct etna_inst_src *src2; - - int imm; -}; - -static void -printf_type(uint8_t type) -{ - switch(type) { - case INST_TYPE_F32: - /* as f32 is the default print nothing */ - break; - - case INST_TYPE_S32: - printf(".s32"); - break; - - case INST_TYPE_S8: - printf(".s8"); - break; - - case INST_TYPE_U16: - printf(".u16"); - break; - - case INST_TYPE_F16: - printf(".f16"); - break; - - case INST_TYPE_S16: - printf(".s16"); - break; - - case INST_TYPE_U32: - printf(".u32"); - break; - - case INST_TYPE_U8: - printf(".u8"); - break; - - default: - abort(); - break; - } -} - -static void -print_condition(uint8_t condition) -{ - switch (condition) { - case INST_CONDITION_TRUE: - break; - - case INST_CONDITION_GT: - printf(".GT"); - break; - - case INST_CONDITION_LT: - printf(".LT"); - break; - - case INST_CONDITION_GE: - printf(".GE"); - break; - - case INST_CONDITION_LE: - printf(".LE"); - break; - - case INST_CONDITION_EQ: - printf(".EQ"); - break; - - case INST_CONDITION_NE: - printf(".NE"); - break; - - case INST_CONDITION_AND: - printf(".AND"); - break; - - case INST_CONDITION_OR: - printf(".OR"); - break; - - case INST_CONDITION_XOR: - printf(".XOR"); - break; - - case INST_CONDITION_NOT: - printf(".NOT"); - break; - - case INST_CONDITION_NZ: - printf(".NZ"); - break; - - case INST_CONDITION_GEZ: - printf(".GEZ"); - break; - - case INST_CONDITION_GZ: - printf(".GZ"); - break; - - case INST_CONDITION_LEZ: - printf(".LEZ"); - break; - - case INST_CONDITION_LZ: - printf(".LZ"); - break; - - default: - abort(); - break; - } -} - -static void -print_rgroup(uint8_t rgoup) -{ - switch (rgoup) { - case INST_RGROUP_TEMP: - printf("t"); - break; - - case INST_RGROUP_INTERNAL: - printf("i"); - break; - - case INST_RGROUP_UNIFORM_0: - case INST_RGROUP_UNIFORM_1: - printf("u"); - break; - case 4: - printf("th"); - break; - } -} - -static void -print_components(uint8_t components) -{ - if (components == 15) - return; - - printf("."); - if (components & INST_COMPS_X) - printf("x"); - else - printf("_"); - - if (components & INST_COMPS_Y) - printf("y"); - else - printf("_"); - - if (components & INST_COMPS_Z) - printf("z"); - else - printf("_"); - - if (components & INST_COMPS_W) - printf("w"); - else - printf("_"); -} - -static inline void -print_swiz_comp(uint8_t swiz_comp) -{ - switch (swiz_comp) { - case INST_SWIZ_COMP_X: - printf("x"); - break; - - case INST_SWIZ_COMP_Y: - printf("y"); - break; - - case INST_SWIZ_COMP_Z: - printf("z"); - break; - - case INST_SWIZ_COMP_W: - printf("w"); - break; - - default: - abort(); - break; - } -} - -static void -print_swiz(uint8_t swiz) -{ - // if a null swizzle - if (swiz == 0xe4) - return; - - const unsigned x = swiz & 0x3; - const unsigned y = (swiz & 0x0C) >> 2; - const unsigned z = (swiz & 0x30) >> 4; - const unsigned w = (swiz & 0xc0) >> 6; - - printf("."); - print_swiz_comp(x); - print_swiz_comp(y); - print_swiz_comp(z); - print_swiz_comp(w); -} - -static void -print_amode(uint8_t amode) -{ - switch (amode) { - case INST_AMODE_DIRECT: - /* nothing to output */ - break; - - case INST_AMODE_ADD_A_X: - printf("[a.x]"); - break; - - case INST_AMODE_ADD_A_Y: - printf("[a.y]"); - break; - - case INST_AMODE_ADD_A_Z: - printf("[a.z]"); - break; - - case INST_AMODE_ADD_A_W: - printf("[a.w]"); - break; - - default: - abort(); - break; - } -} - -static void -print_dst(struct etna_inst_dst *dst, bool sep) -{ - if (dst->use) { - printf("t%u", dst->reg); - print_amode(dst->amode); - print_components(dst->write_mask); - } else { - printf("void"); - } - - if (sep) - printf(", "); -} - -static void -print_tex(struct etna_inst_tex *tex, bool sep) -{ - printf("tex%u", tex->id); - print_amode(tex->amode); - print_swiz(tex->swiz); - - if (sep) - printf(", "); -} +#include <isa/isa.h> -static void -print_src(struct etna_inst_src *src, bool sep) -{ - if (src->use) { - if (src->rgroup == INST_RGROUP_IMMEDIATE) { - switch (src->imm_type) { - case 0: /* float */ - printf("%f", uif(src->imm_val << 12)); - break; - case 1: /* signed */ - printf("%d", ((int) src->imm_val << 12) >> 12); - break; - case 2: /* unsigned */ - printf("%d", src->imm_val); - break; - case 3: /* 16-bit */ - printf("%f/%.5X", _mesa_half_to_float(src->imm_val), src->imm_val); - break; - } - } else { - if (src->neg) - printf("-"); - - if (src->abs) - printf("|"); - - if (src->rgroup == INST_RGROUP_UNIFORM_1) - src->reg += 128; - - print_rgroup(src->rgroup); - printf("%u", src->reg); - print_amode(src->amode); - print_swiz(src->swiz); - - if (src->abs) - printf("|"); - } - } else { - printf("void"); - } - - if (sep) - printf(", "); -} - -static void -print_opc_default(struct opc_operands *operands) -{ - print_dst(operands->dst, true); - print_src(operands->src0, true); - print_src(operands->src1, true); - print_src(operands->src2, false); -} - -static void -print_opc_mov(struct opc_operands *operands) -{ - // dst (areg) - printf("a%u", operands->dst->reg); - print_components(operands->dst->write_mask); - printf(", "); - - print_src(operands->src0, true); - print_src(operands->src1, true); - print_src(operands->src2, false); -} - -static void -print_opc_tex(struct opc_operands *operands) -{ - print_dst(operands->dst, true); - print_tex(operands->tex, true); - print_src(operands->src0, true); - print_src(operands->src1, true); - print_src(operands->src2, false); -} - -static void -print_opc_imm(struct opc_operands *operands) -{ - print_dst(operands->dst, true); - print_src(operands->src0, true); - print_src(operands->src1, true); - printf("label_%04d", operands->imm); -} - -static void -print_opc_store(struct opc_operands *operands) -{ - printf("mem"); - print_components(operands->dst->write_mask); - printf(", "); - - print_src(operands->src0, true); - print_src(operands->src1, true); - print_src(operands->src2, false); -} - -#define OPC_BITS 7 - -static const struct opc_info { - const char *name; - void (*print)(struct opc_operands *operands); -} opcs[1 << OPC_BITS] = { -#define OPC(opc) [INST_OPCODE_##opc] = {#opc, print_opc_default} -#define OPC_MOV(opc) [INST_OPCODE_##opc] = {#opc, print_opc_mov} -#define OPC_TEX(opc) [INST_OPCODE_##opc] = {#opc, print_opc_tex} -#define OPC_IMM(opc) [INST_OPCODE_##opc] = {#opc, print_opc_imm} -#define OPC_STORE(opc) [INST_OPCODE_##opc] = {#opc, print_opc_store} - OPC(NOP), - OPC(ADD), - OPC(MAD), - OPC(MUL), - OPC(DST), - OPC(DP3), - OPC(DP4), - OPC(DSX), - OPC(DSY), - OPC(MOV), - OPC_MOV(MOVAR), - OPC_MOV(MOVAF), - OPC_MOV(MOVAI), - OPC(RCP), - OPC(RSQ), - OPC(LITP), - OPC(SELECT), - OPC(SET), - OPC(EXP), - OPC(LOG), - OPC(FRC), - OPC_IMM(CALL), - OPC(RET), - OPC_IMM(BRANCH), - OPC_TEX(TEXKILL), - OPC_TEX(TEXLD), - OPC_TEX(TEXLDB), - OPC_TEX(TEXLDD), - OPC_TEX(TEXLDL), - OPC_TEX(TEXLDPCF), - OPC_TEX(TEXLDLPCF), - OPC_TEX(TEXLDGPCF), - OPC(REP), - OPC(ENDREP), - OPC(LOOP), - OPC(ENDLOOP), - OPC(SQRT), - OPC(SIN), - OPC(COS), - OPC(FLOOR), - OPC(CEIL), - OPC(SIGN), - OPC(I2I), - OPC(I2F), - OPC(F2I), - OPC(CMP), - OPC(LOAD), - OPC_STORE(STORE), - OPC(IMULLO0), - OPC(IMULHI0), - OPC(IMADLO0), - OPC(IMADHI0), - OPC(LEADZERO), - OPC(LSHIFT), - OPC(RSHIFT), - OPC(ROTATE), - OPC(OR), - OPC(AND), - OPC(XOR), - OPC(NOT), - OPC(DP2), - OPC(DIV), - OPC(IABS), -}; +#include "etnaviv_disasm.h" static void -print_instr(uint32_t *dwords, int n, enum debug_t debug) +pre_instr_cb(void *d, unsigned n, void *instr) { - struct instr *instr = (struct instr *)dwords; - const unsigned opc = instr->opc | (instr->opcode_bit6 << 6); - const char *name = opcs[opc].name; - - printf("%04d: ", n); - if (debug & PRINT_RAW) - printf("%08x %08x %08x %08x ", dwords[0], dwords[1], dwords[2], - dwords[3]); - - if (name) { - - struct etna_inst_dst dst = { - .use = instr->dst_use, - .amode = instr->dst_amode, - .reg = instr->dst_reg, - .write_mask = instr->dst_comps - }; - - struct etna_inst_tex tex = { - .id = instr->tex_id, - .amode = instr->tex_amode, - .swiz = instr->tex_swiz, - }; - - struct etna_inst_src src0 = { - .use = instr->src0_use, - .neg = instr->src0_neg, - .abs = instr->src0_abs, - .rgroup = instr->src0_rgroup, - .reg = instr->src0_reg, - .swiz = instr->src0_swiz, - .amode = instr->src0_amode, - }; - - struct etna_inst_src src1 = { - .use = instr->src1_use, - .neg = instr->src1_neg, - .abs = instr->src1_abs, - .rgroup = instr->src1_rgroup, - .reg = instr->src1_reg, - .swiz = instr->src1_swiz, - .amode = instr->src1_amode, - }; - - struct etna_inst_src src2 = { - .use = instr->src2_use, - .neg = instr->src2_neg, - .abs = instr->src2_abs, - .rgroup = instr->src2_rgroup, - .reg = instr->src2_reg, - .swiz = instr->src2_swiz, - .amode = instr->src2_amode, - }; - - int imm = (instr->dword3 & VIV_ISA_WORD_3_SRC2_IMM__MASK) - >> VIV_ISA_WORD_3_SRC2_IMM__SHIFT; - - struct opc_operands operands = { - .dst = &dst, - .tex = &tex, - .src0 = &src0, - .src1 = &src1, - .src2 = &src2, - .imm = imm, - }; - - uint8_t type = instr->type_bit01 | (instr->type_bit2 << 2); - - printf("%s", name); - printf_type(type); - if (instr->sat) - printf(".SAT"); - print_condition(instr->cond); - printf(" "); - if (instr->sel_0) - printf("SEL_0 "); - if (instr->sel_1) - printf("SEL_1 "); - if (instr->dst_full) - printf("DST_FULL "); - opcs[opc].print(&operands); - } else { - printf("unknown (%d)", instr->opc); - } - - printf("\n"); + uint32_t *dwords = (uint32_t *)instr; + printf("%03d [%08x %08x %08x %08x] ", n, dwords[0], dwords[1], dwords[2], dwords[3]); } void etna_disasm(uint32_t *dwords, int sizedwords, enum debug_t debug) { - unsigned i; - assert((sizedwords % 2) == 0); - for (i = 0; i < sizedwords; i += 4) - print_instr(&dwords[i], i / 4, debug); + struct isa_decode_options options = { + .show_errors = true, + .branch_labels = true, + }; + + if (debug & PRINT_RAW) + options.pre_instr_cb = pre_instr_cb; + + isa_disasm(dwords, sizedwords * sizeof(uint32_t), stdout, &options); } diff --git a/src/gallium/drivers/etnaviv/meson.build b/src/gallium/drivers/etnaviv/meson.build index 331c303f7ec..cc450fc2e72 100644 --- a/src/gallium/drivers/etnaviv/meson.build +++ b/src/gallium/drivers/etnaviv/meson.build @@ -111,7 +111,7 @@ libetnaviv = static_library( include_directories : [ inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_etnaviv, ], - link_with: libetnaviv_drm, + link_with: [libetnaviv_drm, libetnaviv_decode], dependencies : [dep_libdrm, idep_nir_headers, idep_mesautil], ) |