diff --git a/src/freedreno/.gitlab-ci/reference/prefetch-test.log b/src/freedreno/.gitlab-ci/reference/prefetch-test.log index c4f5e76029a..afb7a1cd048 100644 --- a/src/freedreno/.gitlab-ci/reference/prefetch-test.log +++ b/src/freedreno/.gitlab-ci/reference/prefetch-test.log @@ -149157,7 +149157,7 @@ shader-blocks: :0:0047:0057[00000000x_00000000x] nop :3:0048:0058[6d70fe56x_c102890cx] (ss)(jp)(sat)(rpt2)(ul)sel.s16 r21.z, (r)hr, (neg)(r)hr56.y, (neg) ; no match: FIELD: 'sel.s16.SRC3': 0000000000000102 :4:0049:0061[821c4006x_20905a42x] no match: 821c400620905a42 - :5:0050:0062[b002819cx_d601061dx] (sy)isam.a (f16)(x)hr39.x, r3.z, s#0, t#107 ; WARNING: unexpected bits[47:47] in #instruction-cat5: 0000000000000001 vs 0000000000000000, WARNING: unexpected bits[0:7] in #cat5-src2: 0000000000000083 vs 0000000000000000 + :5:0050:0062[b002819cx_d601061dx] (sy)isam.a.1d (f16)(x)hr39.x, r3.z, s#0, t#107 ; WARNING: unexpected bits[47:47] in #instruction-cat5: 0000000000000001 vs 0000000000000000, WARNING: unexpected bits[0:7] in #cat5-src2: 0000000000000083 vs 0000000000000000 :0:0051:0063[19d70515x_81d857bex] no match: 19d7051581d857be :3:0052:0064[7972f999x_e4df0ecbx] (sy)(ss)(jp)(rpt1)(ul)mad.s16 r38.y, (r)hc, (neg)hr57.y, (neg)(r)(last)hr55.w :6:0053:0066[dda7eb4fx_f96f6ddfx] no match: dda7eb4ff96f6ddf diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 52df6e2d287..da7c8aedb34 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -357,6 +357,17 @@ typedef enum ir3_instruction_flags { * (eq) calculations. */ IR3_INSTR_NEEDS_HELPERS = BIT(18), + + /* isam.v */ + IR3_INSTR_V = BIT(19), + + /* isam.1d. Note that .1d is an active-low bit. */ + IR3_INSTR_INV_1D = BIT(20), + + /* isam.v/ldib.b/stib.b can optionally use an immediate offset with one of + * their sources. + */ + IR3_INSTR_IMM_OFFSET = BIT(21), } ir3_instruction_flags; struct ir3_instruction { diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l index 9a2e0efdc35..3df1a98e2e2 100644 --- a/src/freedreno/ir3/ir3_lexer.l +++ b/src/freedreno/ir3/ir3_lexer.l @@ -436,6 +436,7 @@ static int parse_reg(const char *str) "s" return 's'; "k" return 'k'; "u" return 'u'; +"v" return 'v'; "base"[0-9]+ ir3_yylval.num = strtol(yytext+4, NULL, 10); return T_BASE; "offset"[0-9]+ ir3_yylval.num = strtol(yytext+6, NULL, 10); return T_OFFSET; "uniform" return T_UNIFORM; diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index a7796bd4ef8..052a7e16939 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -716,7 +716,7 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token T_MOD_MEM %token T_MOD_RT -%type integer offset +%type integer offset uoffset %type flut_immed %type float %type src dst const cat0_src1 cat0_src2 @@ -1079,8 +1079,9 @@ cat4_instr: cat4_opc dst_reg ',' src_reg_or_const_or_rel_or_imm cat5_opc_dsxypp: T_OP_DSXPP_1 { new_instr(OPC_DSXPP_1)->cat5.type = TYPE_F32; } | T_OP_DSYPP_1 { new_instr(OPC_DSYPP_1)->cat5.type = TYPE_F32; } -cat5_opc: T_OP_ISAM { new_instr(OPC_ISAM); } -| T_OP_ISAML { new_instr(OPC_ISAML); } +cat5_opc_isam: T_OP_ISAM { new_instr(OPC_ISAM)->flags |= IR3_INSTR_INV_1D; } + +cat5_opc: T_OP_ISAML { new_instr(OPC_ISAML); } | T_OP_ISAMM { new_instr(OPC_ISAMM); } | T_OP_SAM { new_instr(OPC_SAM); } | T_OP_SAMB { new_instr(OPC_SAMB); } @@ -1117,6 +1118,7 @@ cat5_flag: '.' T_3D { instr->flags |= IR3_INSTR_3D; } | '.' 'p' { instr->flags |= IR3_INSTR_P; } | '.' 's' { instr->flags |= IR3_INSTR_S; } | '.' T_S2EN { instr->flags |= IR3_INSTR_S2EN; } +| '.' T_1D { instr->flags &= ~IR3_INSTR_INV_1D; } | '.' T_UNIFORM { } | '.' T_NONUNIFORM { instr->flags |= IR3_INSTR_NONUNIF; } | '.' T_BASE { instr->flags |= IR3_INSTR_B; instr->cat5.tex_base = $2; } @@ -1143,6 +1145,9 @@ cat5_instr: cat5_opc_dsxypp cat5_flags dst_reg ',' src_reg | cat5_opc cat5_flags cat5_type dst_reg ',' src_reg ',' cat5_samp_tex_all | cat5_opc cat5_flags cat5_type dst_reg ',' cat5_samp_tex | cat5_opc cat5_flags cat5_type dst_reg +| cat5_opc_isam cat5_flags cat5_type dst_reg ',' src_reg ',' src_reg ',' cat5_samp_tex_all +| cat5_opc_isam cat5_flags cat5_type dst_reg ',' src_reg ',' cat5_samp_tex_all +| cat5_opc_isam '.' 'v' cat5_flags cat5_type dst_reg ',' src_reg src_uoffset ',' cat5_samp_tex_all { instr->flags |= IR3_INSTR_V; } | T_OP_TCINV { new_instr(OPC_TCINV); } cat6_typed: '.' T_UNTYPED { instr->cat6.typed = 0; } @@ -1506,10 +1511,14 @@ src_reg_or_rel_or_imm: src_reg | relative | immediate -offset: { $$ = 0; } +uoffset: { $$ = 0; } | '+' integer { $$ = $2; } + +offset: uoffset | '-' integer { $$ = -$2; } +src_uoffset: uoffset { new_src(0, IR3_REG_IMMED)->uim_val = $1; if ($1) instr->flags |= IR3_INSTR_IMM_OFFSET; } + relative_gpr_src: 'r' '<' T_A0 offset '>' { new_src(0, IR3_REG_RELATIV)->array.offset = $4; } | T_HR '<' T_A0 offset '>' { new_src(0, IR3_REG_RELATIV | IR3_REG_HALF)->array.offset = $4; } diff --git a/src/freedreno/ir3/ir3_print.c b/src/freedreno/ir3/ir3_print.c index 60df5910f43..2022ad2cd3a 100644 --- a/src/freedreno/ir3/ir3_print.c +++ b/src/freedreno/ir3/ir3_print.c @@ -200,6 +200,8 @@ print_instr_name(struct log_stream *stream, struct ir3_instruction *instr, mesa_log_stream_printf(stream, ".p"); if (instr->flags & IR3_INSTR_S) mesa_log_stream_printf(stream, ".s"); + if (instr->flags & IR3_INSTR_V) + mesa_log_stream_printf(stream, ".v"); if (instr->flags & IR3_INSTR_A1EN) mesa_log_stream_printf(stream, ".a1en"); if (instr->flags & IR3_INSTR_U) diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index cea67be42a5..63219ea481b 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -181,9 +181,14 @@ static const struct test { INSTR_6XX(a048d107_e0080a07, "isaml.base3 (s32)(x)r1.w, r0.w, r1.y, s#0, a1.x"), INSTR_6XX(a1481606_e4803035, "saml.base0 (f32)(yz)r1.z, r6.z, r6.x, s#36, a1.x"), - INSTR_7XX(a0081f02_e2000001, "isam.base0 (f32)(xyzw)r0.z, r0.x, t#16, a1.x"), + INSTR_7XX(a0081f02_e2040001, "isam.base0 (f32)(xyzw)r0.z, r0.x, t#16, a1.x"), + INSTR_7XX(a0081f02_e2000001, "isam.base0.1d (f32)(xyzw)r0.z, r0.x, t#16, a1.x"), INSTR_7XX(a148310d_e028302c, "saml.base2 (u32)(x)r3.y, hr5.z, hr6.x, t#1, a1.x"), + INSTR_7XX(a00c3101_c2040001, "isam.v.base0 (u32)(x)r0.y, r0.x, s#0, t#1"), + INSTR_7XX(a00c3101_c2000001, "isam.v.base0.1d (u32)(x)r0.y, r0.x, s#0, t#1"), + INSTR_7XX(a02c3f06_c2041003, "isam.v.base0 (u32)(xyzw)r1.z, r0.y+8, s#0, t#1"), + /* dEQP-VK.subgroups.arithmetic.compute.subgroupadd_float */ INSTR_6XX(a7c03102_00100003, "brcst.active.w8 (u32)(x)r0.z, r0.y"), /* brcst.active.w8 (u32)(xOOO)r0.z, r0.y */ /* dEQP-VK.subgroups.quad.graphics.subgroupquadbroadcast_int */ diff --git a/src/freedreno/isa/ir3-cat5.xml b/src/freedreno/isa/ir3-cat5.xml index 9ca1567cc2a..a1f34f359d0 100644 --- a/src/freedreno/isa/ir3-cat5.xml +++ b/src/freedreno/isa/ir3-cat5.xml @@ -56,7 +56,7 @@ SOFTWARE. The "normal" case, ie. not s2en (indirect) and/or bindless - {SY}{JP}{NAME}{3D}{A}{O}{P}{S} {TYPE}({WRMASK}){DST_HALF}{DST}{SRC1}{SRC2}{SAMP}{TEX} + {SY}{JP}{NAME}{3D}{A}{O}{P}{SV}{1D} {TYPE}({WRMASK}){DST_HALF}{DST}{SRC1}{SRC2}{SAMP}{TEX} @@ -69,6 +69,7 @@ SOFTWARE. + - 0x + x @@ -94,7 +95,6 @@ SOFTWARE. 0 - @@ -111,7 +111,6 @@ SOFTWARE. src->cat5.tex_base >> 1 !!(src->flags & IR3_INSTR_3D) !!(src->flags & IR3_INSTR_A) - !!(src->flags & IR3_INSTR_S) !!(src->flags & (IR3_INSTR_S2EN | IR3_INSTR_B)) !!(src->flags & IR3_INSTR_O) extract_cat5_DESC_MODE(src) @@ -123,16 +122,20 @@ SOFTWARE. extract_cat5_SRC(src, 1) (src->srcs_count > 0) ? src->srcs[0] : NULL + + + + - + {S2EN_BINDLESS} The s2en (indirect) or bindless case - {SY}{JP}{NAME}{3D}{A}{O}{P}{S}{S2EN}{UNIFORM}{NONUNIFORM}{BASE} {TYPE}({WRMASK}){DST_HALF}{DST}{SRC1}{SRC2}{SRC3}{A1} + {SY}{JP}{NAME}{3D}{A}{O}{P}{SV}{S2EN}{UNIFORM}{NONUNIFORM}{BASE}{1D} {TYPE}({WRMASK}){DST_HALF}{DST}{SRC1}{SRC2}{SRC3}{A1} @@ -154,19 +157,37 @@ SOFTWARE. 00 + + + + 0 + + !!(src->flags & IR3_INSTR_S) !!(src->flags & IR3_INSTR_P) - + 00000 + + + + + + + + !!(src->flags & IR3_INSTR_V) + !!(src->flags & IR3_INSTR_INV_1D) + !!(src->flags & IR3_INSTR_IMM_OFFSET) + @@ -485,7 +506,12 @@ SOFTWARE. 101 - + + 0 + 0 + + + The subgroup is divided into (subgroup_size / CLUSTER_SIZE) clusters. For each cluster brcst.active.w does: @@ -539,7 +565,7 @@ SOFTWARE. - + @@ -614,10 +640,18 @@ SOFTWARE. + + {SRC2_IMM_OFFSET} + + {OFF} + + + 00000000 src + extract_reg_uim(src)