From b90a1cf7470a41b7826681e8fd45ab25d61641ac Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sun, 20 Dec 2020 11:05:57 -0800 Subject: [PATCH] freedreno/ir3: Cleanup cat6 load instructions There was some src2 vs src3 confusion, but since the syntax is like: ldl.f32 rDst, l[rBase+off], ncomp it makes more sense to call the offset src2 and ncomp src3, than the way we had it. This is also easier to deal with for the ir3 assembly parser. Also, src_offset was only ever used by the assembly parser, and was handled incorrectly in emit_cat6(), resulting that cat6 load instrs would not work properly in (for ex) computerator. Since we are cleaning things up, drop src_offset and make the asm parser work in the same way as the nir->ir3 frontend. Signed-off-by: Rob Clark Part-of: --- src/freedreno/ir3/disasm-a3xx.c | 22 +++++++++++----------- src/freedreno/ir3/instr-a3xx.h | 8 ++++---- src/freedreno/ir3/ir3.c | 17 ++++++++--------- src/freedreno/ir3/ir3.h | 1 - src/freedreno/ir3/ir3_compiler_nir.c | 21 +++++++++++---------- src/freedreno/ir3/ir3_parser.y | 6 ++++-- 6 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/freedreno/ir3/disasm-a3xx.c b/src/freedreno/ir3/disasm-a3xx.c index 8f19e2f3e43..38eb9ec0f98 100644 --- a/src/freedreno/ir3/disasm-a3xx.c +++ b/src/freedreno/ir3/disasm-a3xx.c @@ -1135,26 +1135,26 @@ static void print_instr_cat6_a3xx(struct disasm_ctx *ctx, instr_t *instr) 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) { + } else if (_OPC(6, cat6->opc) == OPC_LDG && cat6->a.src1_im && cat6->a.src3_im) { struct reginfo src3; memset(&src3, 0, sizeof(src3)); src1.reg = (reg_t)(cat6->a.src1); - src2.reg = (reg_t)(cat6->a.src2); - src2.im = cat6->a.src2_im; - if (src2.im) - src2.full = true; - src3.reg = (reg_t)(cat6->a.off); - src3.full = true; + src3.reg = (reg_t)(cat6->a.src3); + src3.im = cat6->a.src3_im; + if (src3.im) + src3.full = true; + src2.reg = (reg_t)(cat6->a.off); + src2.full = true; dst.reg = (reg_t)(cat6->d.dst); print_src(ctx, &dst); fprintf(ctx->out, ", g["); print_src(ctx, &src1); fprintf(ctx->out, "+"); - print_src(ctx, &src3); - fprintf(ctx->out, "], "); print_src(ctx, &src2); + fprintf(ctx->out, "], "); + print_src(ctx, &src3); return; } @@ -1162,8 +1162,8 @@ static void print_instr_cat6_a3xx(struct disasm_ctx *ctx, instr_t *instr) if (cat6->src_off) { src1.reg = (reg_t)(cat6->a.src1); src1.im = cat6->a.src1_im; - src2.reg = (reg_t)(cat6->a.src2); - src2.im = cat6->a.src2_im; + src2.reg = (reg_t)(cat6->a.src3); + src2.im = cat6->a.src3_im; src1off = cat6->a.off; } else { src1.reg = (reg_t)(cat6->b.src1); diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index 595f1c920d5..138d7210eb9 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -738,15 +738,15 @@ typedef struct PACKED { uint32_t opc_cat : 3; } instr_cat5_t; -/* dword0 encoding for src_off: [src1 + off], src2: */ +/* dword0 encoding for src_off: [src1 + off], src3: */ typedef struct PACKED { /* dword0: */ uint32_t mustbe1 : 1; - int32_t off : 13; + int32_t off : 13; /* src2 */ uint32_t src1 : 8; uint32_t src1_im : 1; - uint32_t src2_im : 1; - uint32_t src2 : 8; + uint32_t src3_im : 1; + uint32_t src3 : 8; /* dword1: */ uint32_t dword1; diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index 411cd9e8e2c..e9ab730ea0f 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -884,9 +884,8 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr, stgb->src3_im = !!(src3->flags & IR3_REG_IMMED); return 0; - } else if (instr->cat6.src_offset || (instr->opc == OPC_LDG) || - (instr->opc == OPC_LDL) || (instr->opc == OPC_LDLW) || - (instr->opc == OPC_LDP)) { + } else if ((instr->opc == OPC_LDG) || (instr->opc == OPC_LDL) || + (instr->opc == OPC_LDLW) || (instr->opc == OPC_LDP)) { struct ir3_register *src3 = instr->regs[3]; instr_cat6a_t *cat6a = ptr; @@ -898,18 +897,18 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr, * register or an immediate offset. */ cat6a->src1 = reg(src1, info, instr->repeat, 0); - cat6a->src1_im = !(src3->flags & IR3_REG_IMMED); - cat6a->off = reg(src3, info, instr->repeat, IR3_REG_IMMED); + cat6a->src1_im = !(src2->flags & IR3_REG_IMMED); + cat6a->off = reg(src2, info, instr->repeat, IR3_REG_IMMED); } else { cat6a->src1 = reg(src1, info, instr->repeat, IR3_REG_IMMED); cat6a->src1_im = !!(src1->flags & IR3_REG_IMMED); - cat6a->off = reg(src3, info, instr->repeat, IR3_REG_IMMED); - iassert(src3->flags & IR3_REG_IMMED); + cat6a->off = reg(src2, info, instr->repeat, IR3_REG_IMMED); + iassert(src2->flags & IR3_REG_IMMED); } /* Num components */ - cat6a->src2 = reg(src2, info, instr->repeat, IR3_REG_IMMED); - cat6a->src2_im = true; + cat6a->src3 = reg(src3, info, instr->repeat, IR3_REG_IMMED); + cat6a->src3_im = true; } else { instr_cat6b_t *cat6b = ptr; diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 10847089d44..4397225af10 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -274,7 +274,6 @@ struct ir3_instruction { } cat5; struct { type_t type; - int src_offset; int dst_offset; int iim_val : 3; /* for ldgb/stgb, # of components */ unsigned d : 3; /* for ldc, component offset */ diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index e7ee1101da4..713fb20df8f 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -816,8 +816,9 @@ emit_intrinsic_load_ubo(struct ir3_context *ctx, nir_intrinsic_instr *intr, for (int i = 0; i < intr->num_components; i++) { struct ir3_instruction *load = - ir3_LDG(b, addr, 0, create_immed(b, 1), 0, /* num components */ - create_immed(b, off + i * 4), 0); + ir3_LDG(b, addr, 0, + create_immed(b, off + i * 4), 0, + create_immed(b, 1), 0); /* num components */ load->cat6.type = TYPE_U32; dst[i] = load; } @@ -874,8 +875,8 @@ emit_intrinsic_load_shared(struct ir3_context *ctx, nir_intrinsic_instr *intr, base = nir_intrinsic_base(intr); ldl = ir3_LDL(b, offset, 0, - create_immed(b, intr->num_components), 0, - create_immed(b, base), 0); + create_immed(b, base), 0, + create_immed(b, intr->num_components), 0); ldl->cat6.type = utype_dst(intr->dest); ldl->regs[0]->wrmask = MASK(intr->num_components); @@ -928,8 +929,8 @@ emit_intrinsic_load_shared_ir3(struct ir3_context *ctx, nir_intrinsic_instr *int base = nir_intrinsic_base(intr); load = ir3_LDLW(b, offset, 0, - create_immed(b, intr->num_components), 0, - create_immed(b, base), 0); + create_immed(b, base), 0, + create_immed(b, intr->num_components), 0); /* for a650, use LDL for tess ctrl inputs: */ if (ctx->so->type == MESA_SHADER_TESS_CTRL && ctx->compiler->tess_use_shared) @@ -1063,8 +1064,8 @@ emit_intrinsic_load_scratch(struct ir3_context *ctx, nir_intrinsic_instr *intr, offset = ir3_get_src(ctx, &intr->src[0])[0]; ldp = ir3_LDP(b, offset, 0, - create_immed(b, intr->num_components), 0, - create_immed(b, 0), 0); + create_immed(b, 0), 0, + create_immed(b, intr->num_components), 0); ldp->cat6.type = utype_dst(intr->dest); ldp->regs[0]->wrmask = MASK(intr->num_components); @@ -1666,8 +1667,8 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) offset = ir3_get_src(ctx, &intr->src[1])[0]; struct ir3_instruction *load = - ir3_LDG(b, addr, 0, create_immed(ctx->block, dest_components), - 0, offset, 0); + ir3_LDG(b, addr, 0, offset, 0, + create_immed(ctx->block, dest_components), 0); load->cat6.type = TYPE_U32; load->regs[0]->wrmask = MASK(dest_components); diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index f08ef7bb004..9a3fb3afb7e 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -862,14 +862,16 @@ cat6_dim: '.' T_1D { instr->cat6.d = 1; } | '.' T_4D { instr->cat6.d = 4; } cat6_type: '.' type { instr->cat6.type = $2; } -cat6_offset: offset { instr->cat6.src_offset = $1; } +cat6_offset: offset { new_reg(0, IR3_REG_IMMED)->iim_val = $1; } cat6_immed: integer { instr->cat6.iim_val = $1; } cat6_load: T_OP_LDG { new_instr(OPC_LDG); } cat6_type dst_reg ',' 'g' '[' reg cat6_offset ']' ',' immediate | T_OP_LDP { new_instr(OPC_LDP); } cat6_type dst_reg ',' 'p' '[' reg cat6_offset ']' ',' immediate | T_OP_LDL { new_instr(OPC_LDL); } cat6_type dst_reg ',' 'l' '[' reg cat6_offset ']' ',' immediate | T_OP_LDLW { new_instr(OPC_LDLW); } cat6_type dst_reg ',' 'l' '[' reg cat6_offset ']' ',' immediate -| T_OP_LDLV { new_instr(OPC_LDLV); } cat6_type dst_reg ',' 'l' '[' reg cat6_offset ']' ',' immediate +| T_OP_LDLV { new_instr(OPC_LDLV); } cat6_type dst_reg ',' 'l' '[' integer ']' { + new_reg(0, IR3_REG_IMMED)->iim_val = $8; + } ',' immediate // TODO some of the cat6 instructions have different syntax for a6xx.. //| T_OP_LDIB { new_instr(OPC_LDIB); } cat6_type dst_reg cat6_offset ',' reg ',' cat6_immed