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