diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index 3ee917d9986..671559eb7ce 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -1000,6 +1000,9 @@ cat6_dst_offset: offset { instr->cat6.dst_offset = $1; } cat6_immed: integer { instr->cat6.iim_val = $1; } +cat6_immed_or_gpr: immediate +| src_gpr + cat6_src_shift: '<' '<' integer {$$ = $3;} | {$$ = 0;} @@ -1036,7 +1039,7 @@ cat6_a6xx_global_address: cat6_load: T_OP_LDG { new_instr(OPC_LDG); } cat6_type dst_reg ',' 'g' '[' src cat6_offset ']' ',' immediate | T_OP_LDG_A { new_instr(OPC_LDG_A); } cat6_type dst_reg ',' 'g' '[' cat6_a6xx_global_address ']' ',' immediate -| T_OP_LDG_K { new_instr(OPC_LDG_K); } cat6_type 'c' '[' const_dst ']' ',' 'g' '[' src cat6_offset ']' ',' immediate +| T_OP_LDG_K { new_instr(OPC_LDG_K); } cat6_type 'c' '[' const_dst ']' ',' 'g' '[' src cat6_offset ']' ',' cat6_immed_or_gpr | T_OP_LDP { new_instr(OPC_LDP); } cat6_type dst_reg ',' 'p' '[' src cat6_offset ']' ',' immediate | T_OP_LDL { new_instr(OPC_LDL); } cat6_type dst_reg ',' 'l' '[' src cat6_offset ']' ',' immediate | T_OP_LDLW { new_instr(OPC_LDLW); } cat6_type dst_reg ',' 'l' '[' src cat6_offset ']' ',' immediate diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index a1ef7ced3bf..0602946b6fe 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -462,6 +462,7 @@ static const struct test { INSTR_6XX(c0160010_00b001a1, "ldg.k.u32 c[16], g[r48.x+208], 1"), INSTR_6XX(c0160188_00b01261, "ldg.k.u32 c[a1.x+136], g[r48.x+2352], 1"), + INSTR_6XX(c0160010_3d3001a1, "ldg.k.u32 c[16], g[r48.x+208], r15.y"), /* Atomic: */ #if 0 diff --git a/src/freedreno/isa/ir3-cat6.xml b/src/freedreno/isa/ir3-cat6.xml index fce0f624f84..300633a6647 100644 --- a/src/freedreno/isa/ir3-cat6.xml +++ b/src/freedreno/isa/ir3-cat6.xml @@ -223,12 +223,18 @@ TODO rename UAV src to "UAV" so disasm_field_cb can find it easily? DST: offset into the const file as an immediate or value in a1.x. The a1.x+offset form is not supported (i.e., the offset is ignored). + + LOAD_SIZE: load size in units of vec4. Note that LOAD_SIZE_IM makes + the blob disassembler select between interpreting LOAD_SIZE as either + an immediate or a GPR. However, using a GPR does not work and the bits + are still interpreted as an immediate. We follow the blob here for + consistency. - {SY}{JP}{NAME}.{TYPE} c[{DST}], g[{SRC1}{OFF}], {SIZE} + {SY}{JP}{NAME}.{TYPE} c[{DST}], g[{SRC1}{OFF}], {LOAD_SIZE} 1 @@ -237,8 +243,10 @@ TODO rename UAV src to "UAV" so disasm_field_cb can find it easily? 0 - - 00xxx + + + + xxxxxxxx 1 @@ -246,12 +254,14 @@ TODO rename UAV src to "UAV" so disasm_field_cb can find it easily? 00000 + src src->srcs[1] extract_reg_uim(src->srcs[2]) - extract_reg_uim(src->srcs[3]) + src->srcs[3] + !!(src->srcs[3]->flags & IR3_REG_IMMED) @@ -1589,6 +1599,30 @@ TODO rename UAV src to "UAV" so disasm_field_cb can find it easily? + + + Load size source value that can be either immed or gpr + + + {LOAD_SIZE_IM} + + {LOAD_SIZE} + + + + + + r{GPR}.{SWIZ} + + + + + src->num >> 2 + src->num & 0x3 + extract_reg_uim(src) - 1 + + + Source value that can be either const reg or gpr