From fd5c94b8c7dbf4574848b64533975f535727d1c8 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Mon, 4 Nov 2024 11:58:08 +0100 Subject: [PATCH] ir3: Fix cat5 parsing with a1.x src present Such instructions were failing to be parsed: sam.s2en.uniform.base1 (f32)(xyz)r1.w, r0.z, r1.y, a1.x saml.s2en.uniform.base1 (f32)(xyzw)r13.x, r0.w, r13.w, r11.w, a1.x isam.v.s2en.uniform.base0 (u32)(xyzw)r1.y, r0.x+3, r2.y Also fix fixup_cat5_s2en which incorrectly rotated instruction sources. Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/ir3/ir3_parser.y | 43 +++++++++++++++++++------------- src/freedreno/ir3/tests/disasm.c | 3 +++ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index e9969f248a4..1b1120ea5fb 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -205,16 +205,19 @@ static void fixup_cat5_s2en(void) * is first, rather than last. So we have to detect this case and * fix things up. */ - struct ir3_register *s2en_src = instr->srcs[instr->srcs_count - 1]; + + uint32_t s2en_off = instr->srcs_count - 1; + if (instr->flags & IR3_INSTR_A1EN) + s2en_off = instr->srcs_count - 2; + + struct ir3_register *s2en_src = instr->srcs[s2en_off]; if (instr->flags & IR3_INSTR_B) assert(!(s2en_src->flags & IR3_REG_HALF)); else assert(s2en_src->flags & IR3_REG_HALF); - for (int i = 0; i < instr->srcs_count - 1; i++) { - instr->srcs[i+1] = instr->srcs[i]; - } + memmove(instr->srcs + 1, instr->srcs, s2en_off * sizeof(instr->srcs[0])); instr->srcs[0] = s2en_src; } @@ -731,7 +734,7 @@ static void print_token(FILE *file, int type, YYSTYPE value) %type integer offset uoffset %type flut_immed %type float -%type src dst const cat0_src1 cat0_src2 +%type dst const src_gpr src_a0 src_a1 src_p0 cat0_src1 cat0_src2 %type cat1_opc %type cat2_opc_1src cat2_opc_2src_cnd cat2_opc_2src %type cat3_opc @@ -1148,9 +1151,9 @@ cat5_flags: cat5_samp: T_SAMP { instr->cat5.samp = $1; } cat5_tex: T_TEX { instr->cat5.tex = $1; } cat5_type: '(' type ')' { instr->cat5.type = $2; } -cat5_a1: src_reg { instr->flags |= IR3_INSTR_A1EN; } +cat5_a1: src_a1 { instr->flags |= IR3_INSTR_A1EN; } -cat5_samp_tex: src_reg +cat5_samp_tex: src_gpr | cat5_samp ',' cat5_tex | cat5_samp | cat5_tex @@ -1158,15 +1161,16 @@ cat5_samp_tex: src_reg cat5_samp_tex_all: cat5_samp_tex | cat5_samp ',' cat5_a1 | cat5_tex ',' cat5_a1 +| src_gpr ',' cat5_a1 -cat5_instr: cat5_opc_dsxypp cat5_flags dst_reg ',' src_reg -| cat5_opc cat5_flags cat5_type dst_reg ',' src_reg ',' src_reg ',' cat5_samp_tex_all -| cat5_opc cat5_flags cat5_type dst_reg ',' src_reg ',' cat5_samp_tex_all +cat5_instr: cat5_opc_dsxypp cat5_flags dst_reg ',' src_gpr +| cat5_opc cat5_flags cat5_type dst_reg ',' src_gpr ',' src_gpr ',' cat5_samp_tex_all +| cat5_opc cat5_flags cat5_type dst_reg ',' src_gpr ',' 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; } +| cat5_opc_isam cat5_flags cat5_type dst_reg ',' src_gpr ',' src_gpr ',' cat5_samp_tex_all +| cat5_opc_isam cat5_flags cat5_type dst_reg ',' src_gpr ',' cat5_samp_tex_all +| cat5_opc_isam '.' 'v' cat5_flags cat5_type dst_reg ',' src_gpr 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; } @@ -1489,10 +1493,15 @@ meta_print: meta_print_start meta_print_regs { } } -src: T_REGISTER { $$ = new_src($1, 0); } -| T_A0 { $$ = new_src((61 << 3), IR3_REG_HALF); } -| T_A1 { $$ = new_src((61 << 3) + 1, IR3_REG_HALF); } -| T_P0 { $$ = new_src((62 << 3) + $1, IR3_REG_PREDICATE); } +src_gpr: T_REGISTER { $$ = new_src($1, 0); } +src_a0: T_A0 { $$ = new_src((61 << 3), IR3_REG_HALF); } +src_a1: T_A1 { $$ = new_src((61 << 3) + 1, IR3_REG_HALF); } +src_p0: T_P0 { $$ = new_src((62 << 3) + $1, IR3_REG_PREDICATE); } + +src: src_gpr +| src_a0 +| src_a1 +| src_p0 dst: T_REGISTER { $$ = new_dst($1, 0); } | T_A0 { $$ = new_dst((61 << 3), IR3_REG_HALF); } diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 2d7f75be4ff..7c4c0718178 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -165,6 +165,8 @@ static const struct test { INSTR_6XX(a048d107_cc080a07, "isaml.base3 (s32)(x)r1.w, r0.w, r1.y, s#0, t#6"), 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_6XX(a0c89707_20a00005, "sam.s2en.uniform.base1 (f32)(xyz)r1.w, r0.z, r1.y, a1.x"), + INSTR_6XX(a1489f34_25e06e07, "saml.s2en.uniform.base1 (f32)(xyzw)r13.x, r0.w, r13.w, r11.w, 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"), @@ -173,6 +175,7 @@ static const struct test { 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"), + INSTR_7XX(a02c3f05_a1240601, "isam.v.s2en.uniform.base0 (u32)(xyzw)r1.y, r0.x+3, r2.y"), /* 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 */