ir3/isa: fix load size encoding for ldg.k

The load size field starts at b23 instead of b24 and is 8 bits in size.
b23 makes the blob disassembler select between interpreting the load
size as an immediate or a GPR. However, using a GPR doesn't work as the
HW still seems to interpret the field as an immediate. We copy the
blob's behavior here for consistency.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40947>
This commit is contained in:
Job Noorman 2026-04-14 14:41:20 +02:00 committed by Marge Bot
parent e6529b54c0
commit a1272cabe0
3 changed files with 43 additions and 5 deletions

View file

@ -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

View file

@ -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

View file

@ -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.
</doc>
<gen min="600"/>
<display>
{SY}{JP}{NAME}.{TYPE} c[{DST}], g[{SRC1}{OFF}], {SIZE}
{SY}{JP}{NAME}.{TYPE} c[{DST}], g[{SRC1}{OFF}], {LOAD_SIZE}
</display>
<pattern pos="0" >1</pattern>
@ -237,8 +243,10 @@ TODO rename UAV src to "UAV" so disasm_field_cb can find it easily?
<param name="SRC1_CONST" as="SRC_CONST"/>
</field>
<pattern pos="22" >0</pattern>
<field low="23" high="26" name="SIZE" type="uint"/>
<pattern low="27" high="31">00xxx</pattern>
<field pos="23" name="LOAD_SIZE_IM" type="bool" />
<field low="24" high="31" name="LOAD_SIZE" type="#cat6-src-load-size">
<param name="LOAD_SIZE_IM"/>
</field>
<field low="32" high="40" name="DST" type="#const-dst"/>
<pattern low="41" high="48">xxxxxxxx</pattern>
<pattern pos="52" >1</pattern>
@ -246,12 +254,14 @@ TODO rename UAV src to "UAV" so disasm_field_cb can find it easily?
<pattern low="54" high="58">00000</pattern> <!-- OPC -->
<derived name="SRC1_CONST" expr="#false" type="bool"/>
<derived name="LOAD_SIZE" expr="#cat6-load-size" type="uint"/>
<encode>
<map name="DST">src</map>
<map name="SRC1">src->srcs[1]</map>
<map name="OFF">extract_reg_uim(src->srcs[2])</map>
<map name="SIZE">extract_reg_uim(src->srcs[3])</map>
<map name="LOAD_SIZE">src->srcs[3]</map>
<map name="LOAD_SIZE_IM">!!(src->srcs[3]->flags &amp; IR3_REG_IMMED)</map>
</encode>
</bitset>
@ -1589,6 +1599,30 @@ TODO rename UAV src to "UAV" so disasm_field_cb can find it easily?
</encode>
</bitset>
<bitset name="#cat6-src-load-size" size="8">
<doc>
Load size source value that can be either immed or gpr
</doc>
<override>
<expr>{LOAD_SIZE_IM}</expr>
<display>
{LOAD_SIZE}
</display>
<field name="LOAD_SIZE_MINUS_ONE" low="0" high="7" type="uint"/>
<derived name="LOAD_SIZE" expr="#cat6-load-size" type="uint"/>
</override>
<display>
r{GPR}.{SWIZ}
</display>
<field name="SWIZ" low="0" high="1" type="#swiz"/>
<field name="GPR" low="2" high="7" type="uint"/>
<encode type="struct ir3_register *">
<map name="GPR">src->num >> 2</map>
<map name="SWIZ">src->num &amp; 0x3</map>
<map name="LOAD_SIZE_MINUS_ONE">extract_reg_uim(src) - 1</map>
</encode>
</bitset>
<bitset name="#cat6-src-const-or-gpr" size="8">
<doc>
Source value that can be either const reg or gpr