From 00b9099dd599ecaede1c0ddbb8fa3097e299667e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 20 May 2020 15:29:14 -0700 Subject: [PATCH] freedreno: Set the immediate flag in a4/a5xx resinfos. Noticed comparing our RESINFO asm to qcom's for the same test, and if I drop this bit their disasm switches from immediate to reg. ldgb seems to have the same behavior. Part-of: --- src/freedreno/ir3/disasm-a3xx.c | 28 ++++++++++++++++++++-------- src/freedreno/ir3/instr-a3xx.h | 2 +- src/freedreno/ir3/ir3.c | 10 +++++----- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/freedreno/ir3/disasm-a3xx.c b/src/freedreno/ir3/disasm-a3xx.c index 3db422f0d6f..6dd3da04924 100644 --- a/src/freedreno/ir3/disasm-a3xx.c +++ b/src/freedreno/ir3/disasm-a3xx.c @@ -673,12 +673,13 @@ static void print_instr_cat6_a3xx(struct disasm_ctx *ctx, instr_t *instr) instr_cat6_t *cat6 = &instr->cat6; char sd = 0, ss = 0; /* dst/src address space */ bool nodst = false; - struct reginfo dst, src1, src2; + struct reginfo dst, src1, src2, ssbo; int src1off = 0, dstoff = 0; memset(&dst, 0, sizeof(dst)); memset(&src1, 0, sizeof(src1)); memset(&src2, 0, sizeof(src2)); + memset(&ssbo, 0, sizeof(ssbo)); switch (_OPC(6, cat6->opc)) { case OPC_RESINFO: @@ -852,8 +853,8 @@ static void print_instr_cat6_a3xx(struct disasm_ctx *ctx, instr_t *instr) print_src(ctx, &src3); /* 64b byte offset.. */ if (debug & PRINT_VERBOSE) { - fprintf(ctx->out, " (pad0=%x, pad3=%x, mustbe0=%x)", cat6->ldgb.pad0, - cat6->ldgb.pad3, cat6->ldgb.mustbe0); + fprintf(ctx->out, " (pad0=%x, mustbe0=%x)", cat6->ldgb.pad0, + cat6->ldgb.mustbe0); } } else { /* ss == 'l' */ fprintf(ctx->out, "l["); @@ -862,19 +863,24 @@ static void print_instr_cat6_a3xx(struct disasm_ctx *ctx, instr_t *instr) print_src(ctx, &src2); /* value */ if (debug & PRINT_VERBOSE) { - fprintf(ctx->out, " (src3=%x, pad0=%x, pad3=%x, mustbe0=%x)", + fprintf(ctx->out, " (src3=%x, pad0=%x, src_ssbo_im=%x, mustbe0=%x)", cat6->ldgb.src3, cat6->ldgb.pad0, - cat6->ldgb.pad3, cat6->ldgb.mustbe0); + cat6->ldgb.src_ssbo_im, cat6->ldgb.mustbe0); } } return; } else if (_OPC(6, cat6->opc) == OPC_RESINFO) { dst.reg = (reg_t)(cat6->ldgb.dst); + ssbo.reg = (reg_t)(cat6->ldgb.src_ssbo); + ssbo.im = cat6->ldgb.src_ssbo_im; print_src(ctx, &dst); fprintf(ctx->out, ", "); - fprintf(ctx->out, "g[%u]", cat6->ldgb.src_ssbo); + + fprintf(ctx->out, "g["); + print_src(ctx, &ssbo); + fprintf(ctx->out, "]"); return; } else if (_OPC(6, cat6->opc) == OPC_LDGB) { @@ -883,17 +889,23 @@ static void print_instr_cat6_a3xx(struct disasm_ctx *ctx, instr_t *instr) src1.im = cat6->ldgb.src1_im; src2.reg = (reg_t)(cat6->ldgb.src2); src2.im = cat6->ldgb.src2_im; + ssbo.reg = (reg_t)(cat6->ldgb.src_ssbo); + ssbo.im = cat6->ldgb.src_ssbo_im; dst.reg = (reg_t)(cat6->ldgb.dst); print_src(ctx, &dst); fprintf(ctx->out, ", "); - fprintf(ctx->out, "g[%u], ", cat6->ldgb.src_ssbo); + + fprintf(ctx->out, "g["); + print_src(ctx, &ssbo); + fprintf(ctx->out, "], "); + print_src(ctx, &src1); fprintf(ctx->out, ", "); print_src(ctx, &src2); if (debug & PRINT_VERBOSE) - fprintf(ctx->out, " (pad0=%x, pad3=%x, mustbe0=%x)", cat6->ldgb.pad0, cat6->ldgb.pad3, cat6->ldgb.mustbe0); + fprintf(ctx->out, " (pad0=%x, ssbo_im=%x, mustbe0=%x)", cat6->ldgb.pad0, cat6->ldgb.src_ssbo_im, cat6->ldgb.mustbe0); return; } else if (_OPC(6, cat6->opc) == OPC_LDG && cat6->a.src1_im && cat6->a.src2_im) { diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index e4f548d639a..822d9dd7bc1 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -774,7 +774,7 @@ typedef struct PACKED { uint32_t src_ssbo : 8; uint32_t pad2 : 3; // type uint32_t g : 1; - uint32_t pad3 : 1; + uint32_t src_ssbo_im : 1; uint32_t pad4 : 10; // opc/jmp_tgt/sync/opc_cat } instr_cat6ldgb_t; diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index 6e43e34023e..d41022b7b29 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -740,6 +740,7 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr, /* first src is src_ssbo: */ iassert(src1->flags & IR3_REG_IMMED); ldgb->src_ssbo = src1->uim_val; + ldgb->src_ssbo_im = 0x1; ldgb->src1 = reg(src2, info, instr->repeat, IR3_REG_IMMED); ldgb->src1_im = !!(src2->flags & IR3_REG_IMMED); @@ -748,14 +749,13 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr, ldgb->src3 = reg(src4, info, instr->repeat, 0); ldgb->pad0 = 0x1; - ldgb->pad3 = 0x1; } else { ldgb->src1 = reg(src1, info, instr->repeat, IR3_REG_IMMED); ldgb->src1_im = !!(src1->flags & IR3_REG_IMMED); ldgb->src2 = reg(src2, info, instr->repeat, IR3_REG_IMMED); ldgb->src2_im = !!(src2->flags & IR3_REG_IMMED); ldgb->pad0 = 0x1; - ldgb->pad3 = 0x0; + ldgb->src_ssbo_im = 0x0; } return 0; @@ -783,7 +783,7 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr, ldgb->src2_im = !!(src3->flags & IR3_REG_IMMED); ldgb->pad0 = 0x0; - ldgb->pad3 = 0x1; + ldgb->src_ssbo_im = true; return 0; } else if (instr->opc == OPC_RESINFO) { @@ -794,8 +794,8 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr, ldgb->dst = reg(dst, info, instr->repeat, IR3_REG_R | IR3_REG_HALF); /* first src is src_ssbo: */ - iassert(src1->flags & IR3_REG_IMMED); - ldgb->src_ssbo = src1->uim_val; + ldgb->src_ssbo = reg(src1, info, instr->repeat, IR3_REG_IMMED); + ldgb->src_ssbo_im = !!(src1->flags & IR3_REG_IMMED); return 0; } else if ((instr->opc == OPC_STGB) || (instr->opc == OPC_STIB)) { -- 2.30.2