freedreno/ir3/parser: Fixup stg parsing and add more tests
authorRob Clark <robdclark@chromium.org>
Mon, 4 Jan 2021 19:30:32 +0000 (11:30 -0800)
committerMarge Bot <eric+marge@anholt.net>
Wed, 6 Jan 2021 16:46:52 +0000 (16:46 +0000)
The offset can also be a register, in which case we need to shuffle
around the src order.  Add a few more test vectors to cover each
permutation (no offset, immed offset, gpr offset).

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8175>

src/freedreno/ir3/ir3_parser.y
src/freedreno/ir3/tests/disasm.c

index 20f1a83..5545abc 100644 (file)
@@ -905,11 +905,9 @@ cat6_dim:          '.' T_1D  { instr->cat6.d = 1; }
 
 cat6_type:         '.' type  { instr->cat6.type = $2; }
 cat6_offset:       offset    { new_reg(0, IR3_REG_IMMED)->iim_val = $1; }
-// TODO in at least some cases (like stg) the dst_offset can actually be a
-//      GPR.. but cleaning that up w/ the existing struct based instruction
-//      encoding is messy, so for now just use cat6.dst_offset like the
-//      nir->ir3 frontend does
 cat6_dst_offset:   offset    { instr->cat6.dst_offset = $1; }
+|                  '+' reg   { instr->flags |= IR3_INSTR_G; }
+
 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
@@ -923,7 +921,15 @@ cat6_load:         T_OP_LDG  { new_instr(OPC_LDG); }  cat6_type dst_reg ',' 'g'
 // 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
 
-cat6_store:        T_OP_STG  { new_instr(OPC_STG); dummy_dst(); }  cat6_type 'g' '[' reg cat6_dst_offset ']' ',' reg ',' immediate
+cat6_store:        T_OP_STG  { new_instr(OPC_STG); dummy_dst(); }  cat6_type 'g' '[' reg cat6_dst_offset ']' ',' reg ',' immediate {
+                       /* fixup src order, the offset reg is expected last currently */
+                       if (instr->flags & IR3_INSTR_G) {
+                           struct ir3_register *offset = instr->regs[2];
+                           instr->regs[2] = instr->regs[3];
+                           instr->regs[3] = instr->regs[4];
+                           instr->regs[4] = offset;
+                       }
+                   }
 |                  T_OP_STP  { new_instr(OPC_STP); dummy_dst(); }  cat6_type 'p' '[' reg cat6_dst_offset ']' ',' reg ',' immediate
 |                  T_OP_STL  { new_instr(OPC_STL); dummy_dst(); }  cat6_type 'l' '[' reg cat6_dst_offset ']' ',' reg ',' immediate
 |                  T_OP_STLW { new_instr(OPC_STLW); dummy_dst(); } cat6_type 'l' '[' reg cat6_dst_offset ']' ',' reg ',' immediate
index 807d0ac..b2775f3 100644 (file)
@@ -136,6 +136,10 @@ static const struct test {
        INSTR_6XX(c0c00000_00000000, "stg.f16 g[hr0.x], hr0.x, hr0.x"),
        /* dEQP-GLES31.functional.tessellation.invariance.outer_edge_symmetry.isolines_equal_spacing_ccw */
        INSTR_6XX(c0d20906_02800004, "stg.f32 g[r1.x+r1.z], r0.z, 2"), /* stg.a.f32 g[r1.x+(r1.z<<2)], r0.z, 2 */
+       INSTR_6XX(c0da052e_01800042, "stg.s32 g[r0.z+r11.z], r8.y, 1"), /* stg.a.s32 g[r0.z+(r11.z<<2)], r8.y, 1 */
+       INSTR_6XX(c0ca0505_03800042, "stg.s32 g[r0.z+5], r8.y, 3"),
+       INSTR_6XX(c0ca0500_03800042, "stg.s32 g[r0.z], r8.y, 3"),
+       INSTR_6XX(c0ca0531_03800242, "stg.s32 g[r0.z+305], r8.y, 3"),
 
        /* TODO: We don't support disasm of stc yet and produce a stgb instead
         * (same as their disasm does for other families.  They're used as part