ir3: add encoding for isam.v

isam.v is a version of isam that can load multiple components from IBOs.
It uses some bits that are used for different purposes in other tex
instructions:
- bit 50 (.v): .s elsewhere
- bit 53 (indicates whether an immediate offset is used): .p elsewhere
- bit 18 (.1d when not set, has to be set for .v): 0 elsewhere

For this reason, the bitset hierarchy for cat5 had to be reordered a
bit.

The immediate offset is encoded as an extra (immed) source register and
an instruction flag (to be able to make the distinction between offset
zero and no offset, although this might not be useful).

This also adds a flag for the .1d field. Since this bit is active-low,
this flag has inverted semantics: setting it will make .1d inactive.
Note that some existing disassembler tests for isam had to be updated
because the bit is never set and this is now disassembled as .1d. This
matches the blob's disassembler.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28664>
This commit is contained in:
Job Noorman 2024-04-10 10:43:38 +02:00 committed by Marge Bot
parent c2dbc4a00a
commit 455ebcccfb
7 changed files with 77 additions and 15 deletions

View File

@ -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<a0.x + 268>, (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<a0.x + -309>, (neg)hr57.y, (neg)(r)(last)hr55.w
:6:0053:0066[dda7eb4fx_f96f6ddfx] no match: dda7eb4ff96f6ddf

View File

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

View File

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

View File

@ -716,7 +716,7 @@ static void print_token(FILE *file, int type, YYSTYPE value)
%token <tok> T_MOD_MEM
%token <tok> T_MOD_RT
%type <num> integer offset
%type <num> integer offset uoffset
%type <num> flut_immed
%type <flt> float
%type <reg> 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; }

View File

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

View File

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

View File

@ -56,7 +56,7 @@ SOFTWARE.
The "normal" case, ie. not s2en (indirect) and/or bindless
</doc>
<display>
{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}
</display>
<derived name="DST_HALF" expr="#type-half" type="bool" display="h"/>
<field name="FULL" pos="0" type="bool"/>
@ -69,6 +69,7 @@ SOFTWARE.
<param name="NUM_SRC"/>
<param name="HALF"/>
<param name="O"/>
<param name="SRC2_IMM_OFFSET"/>
</field>
<!--
TODO remainder of first 32b differ depending on s2en/bindless..
@ -77,7 +78,7 @@ SOFTWARE.
Note b17 seems to show up in some blob traces (samgpN), need
to figure out what this bit does
-->
<pattern low="17" high="18">0x</pattern>
<pattern pos="17">x</pattern>
<field name="SAMP" low="21" high="24" type="#cat5-samp">
<param name="HAS_SAMP"/>
@ -94,7 +95,6 @@ SOFTWARE.
<assert pos="47">0</assert> <!-- BASE_LO -->
<field name="3D" pos="48" type="bool" display=".3d"/>
<field name="A" pos="49" type="bool" display=".a"/>
<field name="S" pos="50" type="bool" display=".s"/>
<field name="S2EN_BINDLESS" pos="51" type="bool"/>
<field name="O" pos="52" type="bool" display=".o"/>
<!-- OPC -->
@ -111,7 +111,6 @@ SOFTWARE.
<map name="BASE_HI">src->cat5.tex_base >> 1</map>
<map name="3D">!!(src->flags &amp; IR3_INSTR_3D)</map>
<map name="A">!!(src->flags &amp; IR3_INSTR_A)</map>
<map name="S">!!(src->flags &amp; IR3_INSTR_S)</map>
<map name="S2EN_BINDLESS">!!(src->flags &amp; (IR3_INSTR_S2EN | IR3_INSTR_B))</map>
<map name="O">!!(src->flags &amp; IR3_INSTR_O)</map>
<map name="DESC_MODE">extract_cat5_DESC_MODE(src)</map>
@ -123,16 +122,20 @@ SOFTWARE.
<map name="SRC2">extract_cat5_SRC(src, 1)</map>
<map name="SRC3">(src->srcs_count > 0) ? src->srcs[0] : NULL</map>
</encode>
<derived name="SRC2_IMM_OFFSET" expr="#false" type="bool"/>
<derived name="P" expr="#false" type="bool" display=""/>
<derived name="1D" expr="#false" type="bool" display=""/>
</bitset>
<bitset name="#instruction-cat5-tex" extends="#instruction-cat5">
<bitset name="#instruction-cat5-tex-base" extends="#instruction-cat5">
<override>
<expr>{S2EN_BINDLESS}</expr>
<doc>
The s2en (indirect) or bindless case
</doc>
<display>
{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}
</display>
<field name="BASE_HI" low="19" high="20" type="uint"/>
<field name="SRC3" low="21" high="28" type="#cat5-src3">
@ -154,19 +157,37 @@ SOFTWARE.
</override>
<assert low="19" high="20">00</assert> <!-- BASE_HI -->
</bitset>
<bitset name="#instruction-cat5-tex" extends="#instruction-cat5-tex-base">
<pattern pos="18">0</pattern>
<field name="SV" pos="50" type="bool" display=".s"/>
<field name="P" pos="53" type="bool" display=".p"/>
<encode>
<map name="SV">!!(src->flags &amp; IR3_INSTR_S)</map>
<map name="P">!!(src->flags &amp; IR3_INSTR_P)</map>
</encode>
</bitset>
<bitset name="isam" extends="#instruction-cat5-tex">
<bitset name="isam" extends="#instruction-cat5-tex-base">
<pattern low="54" high="58">00000</pattern>
<derived name="NUM_SRC" expr="#one" type="uint"/>
<derived name="HAS_SAMP" expr="#true" type="bool"/>
<derived name="HAS_TEX" expr="#true" type="bool"/>
<derived name="HAS_TYPE" expr="#true" type="bool"/>
<!-- Not sure what this field does exactly but isam.v does not work
without it set. The blob disassembles it as .1d when not set. -->
<field name="1D" pos="18" type="bool_inv" display=".1d"/>
<field name="SV" pos="50" type="bool" display=".v"/>
<field name="SRC2_IMM_OFFSET" pos="53" type="bool"/>
<encode>
<map name="SV">!!(src->flags &amp; IR3_INSTR_V)</map>
<map name="1D">!!(src->flags &amp; IR3_INSTR_INV_1D)</map>
<map name="SRC2_IMM_OFFSET">!!(src->flags &amp; IR3_INSTR_IMM_OFFSET)</map>
</encode>
</bitset>
<bitset name="isaml" extends="#instruction-cat5-tex">
@ -485,7 +506,12 @@ SOFTWARE.
<pattern low="61" high="63">101</pattern> <!-- cat5 -->
</bitset>
<bitset name="brcst.active" extends="#instruction-cat5">
<bitset name="#instruction-cat5-brcst" extends="#instruction-cat5">
<pattern pos="18">0</pattern>
<pattern pos="50">0</pattern>
</bitset>
<bitset name="brcst.active" extends="#instruction-cat5-brcst">
<doc>
The subgroup is divided into (subgroup_size / CLUSTER_SIZE)
clusters. For each cluster brcst.active.w does:
@ -539,7 +565,7 @@ SOFTWARE.
</encode>
</bitset>
<bitset name="#instruction-cat5-quad-shuffle" extends="#instruction-cat5">
<bitset name="#instruction-cat5-quad-shuffle" extends="#instruction-cat5-brcst">
<gen min="600"/>
<display>
@ -614,10 +640,18 @@ SOFTWARE.
</display>
<field name="SRC" low="0" high="7" type="#reg-gpr"/>
</override>
<override>
<expr>{SRC2_IMM_OFFSET}</expr>
<display>
{OFF}
</display>
<field name="OFF" low="0" high="7" type="uoffset"/>
</override>
<display/>
<assert low="0" high="7">00000000</assert>
<encode type="struct ir3_register *">
<map name="SRC">src</map>
<map name="OFF">extract_reg_uim(src)</map>
</encode>
</bitset>