Module: Mesa Branch: master Commit: e7471ce77612b746b01a4926a7d04b0921044ae0 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e7471ce77612b746b01a4926a7d04b0921044ae0
Author: Connor Abbott <[email protected]> Date: Fri Oct 23 14:07:04 2020 +0200 ir3: Support assembling & disassembling getspid/getwid These aren't useful yet in the driver, but were useful for reverse-engineering how private memory works. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7386> --- src/freedreno/ir3/disasm-a3xx.c | 42 +++++++++++++--------- src/freedreno/ir3/ir3.c | 78 ++++++++++++++++++++++------------------ src/freedreno/ir3/ir3_lexer.l | 2 ++ src/freedreno/ir3/ir3_parser.y | 9 +++++ src/freedreno/ir3/tests/disasm.c | 4 +++ 5 files changed, 84 insertions(+), 51 deletions(-) diff --git a/src/freedreno/ir3/disasm-a3xx.c b/src/freedreno/ir3/disasm-a3xx.c index 420d27442a8..66699e66880 100644 --- a/src/freedreno/ir3/disasm-a3xx.c +++ b/src/freedreno/ir3/disasm-a3xx.c @@ -1185,6 +1185,7 @@ static void print_instr_cat6_a6xx(struct disasm_ctx *ctx, instr_t *instr) instr_cat6_a6xx_t *cat6 = &instr->cat6_a6xx; struct reginfo src1, src2, ssbo; uint32_t opc = _OPC(6, cat6->opc); + bool is_id = opc == OPC_GETSPID || opc == OPC_GETWID; bool uses_type = opc != OPC_LDC; static const struct { @@ -1229,35 +1230,44 @@ static void print_instr_cat6_a6xx(struct disasm_ctx *ctx, instr_t *instr) memset(&ssbo, 0, sizeof(ssbo)); if (uses_type) { - fprintf(ctx->out, ".%s", cat6->typed ? "typed" : "untyped"); - fprintf(ctx->out, ".%dd", cat6->d + 1); + if (!is_id) { + fprintf(ctx->out, ".%s", cat6->typed ? "typed" : "untyped"); + fprintf(ctx->out, ".%dd", cat6->d + 1); + } fprintf(ctx->out, ".%s", type[cat6->type]); } else { fprintf(ctx->out, ".offset%d", cat6->d); } - fprintf(ctx->out, ".%u", cat6->type_size + 1); - fprintf(ctx->out, ".%s", desc_features[cat6->desc_mode].name); - if (bindless) - fprintf(ctx->out, ".base%d", cat6->base); + if (!is_id) { + fprintf(ctx->out, ".%u", cat6->type_size + 1); + fprintf(ctx->out, ".%s", desc_features[cat6->desc_mode].name); + + if (bindless) + fprintf(ctx->out, ".base%d", cat6->base); + } + fprintf(ctx->out, " "); src2.reg = (reg_t)(cat6->src2); src2.full = type_full; print_src(ctx, &src2); - fprintf(ctx->out, ", "); - if (opc != OPC_RESINFO) { - src1.reg = (reg_t)(cat6->src1); - src1.full = true; // XXX - print_src(ctx, &src1); + if (!is_id) { fprintf(ctx->out, ", "); - } - ssbo.reg = (reg_t)(cat6->ssbo); - ssbo.im = !indirect_ssbo; - ssbo.full = true; - print_src(ctx, &ssbo); + if (opc != OPC_RESINFO) { + src1.reg = (reg_t)(cat6->src1); + src1.full = true; // XXX + print_src(ctx, &src1); + fprintf(ctx->out, ", "); + } + + ssbo.reg = (reg_t)(cat6->ssbo); + ssbo.im = !indirect_ssbo; + ssbo.full = true; + print_src(ctx, &ssbo); + } if (debug & PRINT_VERBOSE) { fprintf(ctx->out, " (pad1=%x, pad2=%x, pad3=%x, pad4=%x, pad5=%x)", diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index 8966e7afecc..05720b44dc2 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -537,53 +537,57 @@ static int emit_cat5(struct ir3_instruction *instr, void *ptr, static int emit_cat6_a6xx(struct ir3_instruction *instr, void *ptr, struct ir3_info *info) { - struct ir3_register *ssbo; instr_cat6_a6xx_t *cat6 = ptr; - ssbo = instr->regs[1]; - cat6->type = instr->cat6.type; - cat6->d = instr->cat6.d - (instr->opc == OPC_LDC ? 0 : 1); - cat6->typed = instr->cat6.typed; - cat6->type_size = instr->cat6.iim_val - 1; cat6->opc = instr->opc; cat6->jmp_tgt = !!(instr->flags & IR3_INSTR_JP); cat6->sync = !!(instr->flags & IR3_INSTR_SY); cat6->opc_cat = 6; - cat6->ssbo = reg(ssbo, info, instr->repeat, IR3_REG_IMMED); - - /* For unused sources in an opcode, initialize contents with the ir3 dest - * reg - */ - switch (instr->opc) { - case OPC_RESINFO: - cat6->src1 = reg(instr->regs[0], info, instr->repeat, 0); + if (instr->opc == OPC_GETWID || instr->opc == OPC_GETSPID) { cat6->src2 = reg(instr->regs[0], info, instr->repeat, 0); - break; - case OPC_LDC: - case OPC_LDIB: - cat6->src1 = reg(instr->regs[2], info, instr->repeat, 0); - cat6->src2 = reg(instr->regs[0], info, instr->repeat, 0); - break; - default: - cat6->src1 = reg(instr->regs[2], info, instr->repeat, 0); - cat6->src2 = reg(instr->regs[3], info, instr->repeat, 0); - break; - } + cat6->src1 = cat6->ssbo = 0; + cat6->d = cat6->typed = cat6->type_size = 0; + } else { + struct ir3_register *ssbo = instr->regs[1]; + cat6->d = instr->cat6.d - (instr->opc == OPC_LDC ? 0 : 1); + cat6->typed = instr->cat6.typed; + cat6->type_size = instr->cat6.iim_val - 1; + cat6->ssbo = reg(ssbo, info, instr->repeat, IR3_REG_IMMED); + + /* For unused sources in an opcode, initialize contents with the ir3 + * dest reg + */ + switch (instr->opc) { + case OPC_RESINFO: + cat6->src1 = reg(instr->regs[0], info, instr->repeat, 0); + cat6->src2 = reg(instr->regs[0], info, instr->repeat, 0); + break; + case OPC_LDC: + case OPC_LDIB: + cat6->src1 = reg(instr->regs[2], info, instr->repeat, 0); + cat6->src2 = reg(instr->regs[0], info, instr->repeat, 0); + break; + default: + cat6->src1 = reg(instr->regs[2], info, instr->repeat, 0); + cat6->src2 = reg(instr->regs[3], info, instr->repeat, 0); + break; + } - if (instr->flags & IR3_INSTR_B) { - if (ssbo->flags & IR3_REG_IMMED) { - cat6->desc_mode = CAT6_BINDLESS_IMM; + if (instr->flags & IR3_INSTR_B) { + if (ssbo->flags & IR3_REG_IMMED) { + cat6->desc_mode = CAT6_BINDLESS_IMM; + } else { + cat6->desc_mode = CAT6_BINDLESS_UNIFORM; + } + cat6->base = instr->cat6.base; } else { - cat6->desc_mode = CAT6_BINDLESS_UNIFORM; + if (ssbo->flags & IR3_REG_IMMED) + cat6->desc_mode = CAT6_IMM; + else + cat6->desc_mode = CAT6_UNIFORM; } - cat6->base = instr->cat6.base; - } else { - if (ssbo->flags & IR3_REG_IMMED) - cat6->desc_mode = CAT6_IMM; - else - cat6->desc_mode = CAT6_UNIFORM; } switch (instr->opc) { @@ -614,6 +618,8 @@ static int emit_cat6_a6xx(struct ir3_instruction *instr, void *ptr, cat6->pad5 = 0x2; break; case OPC_LDC: + case OPC_GETWID: + case OPC_GETSPID: cat6->pad1 = 0x0; cat6->pad3 = 0x4; cat6->pad5 = 0x2; @@ -658,6 +664,8 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr, case OPC_LDIB: case OPC_LDC: case OPC_RESINFO: + case OPC_GETSPID: + case OPC_GETWID: return emit_cat6_a6xx(instr, ptr, info); default: break; diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l index f93d25b5328..b0ba0032c4a 100644 --- a/src/freedreno/ir3/ir3_lexer.l +++ b/src/freedreno/ir3/ir3_lexer.l @@ -264,6 +264,8 @@ static int parse_reg(const char *str) "stib" return TOKEN(T_OP_STIB); "ldc" return TOKEN(T_OP_LDC); "ldlv" return TOKEN(T_OP_LDLV); +"getspid" return TOKEN(T_OP_GETSPID); +"getwid" return TOKEN(T_OP_GETWID); "f16" return TOKEN(T_TYPE_F16); "f32" return TOKEN(T_TYPE_F32); diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index 945a3e0d1ce..fbb0c3f6fae 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -439,6 +439,8 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token <tok> T_OP_STIB %token <tok> T_OP_LDC %token <tok> T_OP_LDLV +%token <tok> T_OP_GETSPID +%token <tok> T_OP_GETWID /* type qualifiers: */ %token <tok> T_TYPE_F16 @@ -811,6 +813,12 @@ cat6_atomic: T_OP_ATOMIC_ADD { new_instr(OPC_ATOMIC_ADD); } cat6_at | T_OP_ATOMIC_OR { new_instr(OPC_ATOMIC_OR); } cat6_atomic_l_g cat6_type dst_reg ',' 'l' '[' reg cat6_offset ']' ',' cat6_immed | T_OP_ATOMIC_XOR { new_instr(OPC_ATOMIC_XOR); } cat6_atomic_l_g cat6_type dst_reg ',' 'l' '[' reg cat6_offset ']' ',' cat6_immed +cat6_id_opc: + T_OP_GETSPID { new_instr(OPC_GETSPID); } +| T_OP_GETWID { new_instr(OPC_GETWID); } + +cat6_id: cat6_id_opc cat6_type dst_reg + cat6_todo: T_OP_G2L { new_instr(OPC_G2L); } | T_OP_L2G { new_instr(OPC_L2G); } | T_OP_RESFMT { new_instr(OPC_RESFMT); } @@ -824,6 +832,7 @@ cat6_instr: cat6_load | cat6_storeib | cat6_prefetch | cat6_atomic +| cat6_id | cat6_todo reg: T_REGISTER { $$ = new_reg($1, 0); } diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 1b16fad6957..1747f05393b 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -192,6 +192,10 @@ static const struct test { INSTR_6XX(a0c81f07_0100000b, "sam.s2en (f32)(xyzw)r1.w, r1.y, hr2.x"), /* sam.s2en.mode0 (f32)(xyzw)r1.w, r1.y, hr2.x */ /* dEQP-GLES31.functional.shaders.opaque_type_indexing.sampler.dynamically_uniform.fragment.sampler2d */ INSTR_6XX(a0c81f07_8100000b, "sam.s2en.uniform (f32)(xyzw)r1.w, r1.y, hr2.x"), /* sam.s2en.mode4 (f32)(xyzw)r1.w, r1.y, hr2.x */ + + /* Custom test since we've never seen the blob emit these. */ + INSTR_6XX(c0260004_00490000, "getspid.u32 r1.x"), + INSTR_6XX(c0260005_00494000, "getwid.u32 r1.y"), }; static void _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
