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 <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8175>
This commit is contained in:
Rob Clark 2020-12-20 11:05:57 -08:00 committed by Marge Bot
parent 4e272003b1
commit b90a1cf747
6 changed files with 38 additions and 37 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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);

View file

@ -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