Module: Mesa Branch: main Commit: 1613d767c178017b8c7aad3bac702f271b64d34b URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=1613d767c178017b8c7aad3bac702f271b64d34b
Author: Danylo Piliaiev <[email protected]> Date: Thu Feb 23 17:50:47 2023 +0100 ir3/a7xx: Document "alias" instruction Signed-off-by: Danylo Piliaiev <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21498> --- src/freedreno/ir3/instr-a3xx.h | 2 + src/freedreno/ir3/ir3.h | 8 ++ src/freedreno/ir3/ir3_lexer.l | 7 ++ src/freedreno/ir3/ir3_parser.y | 19 +++++ src/freedreno/ir3/tests/disasm.c | 5 ++ src/freedreno/isa/ir3-cat6.xml | 2 +- src/freedreno/isa/ir3-cat7.xml | 154 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 196 insertions(+), 1 deletion(-) diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index 4d3e0a4ff20..78178f9ade7 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -371,6 +371,8 @@ typedef enum { OPC_LOCK = _OPC(7, 7), OPC_UNLOCK = _OPC(7, 8), + OPC_ALIAS = _OPC(7, 9), + /* meta instructions (category 8): */ #define OPC_META 8 /* placeholder instr to mark shader inputs: */ diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index aace5df184d..9c829b5611b 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -260,6 +260,12 @@ typedef enum { REDUCE_OP_XOR_B, } reduce_op_t; +typedef enum { + ALIAS_TEX = 0, + ALIAS_RT = 3, + ALIAS_MEM = 4, +} ir3_alias_scope; + typedef enum ir3_instruction_flags { /* (sy) flag is set on first instruction, and after sample * instructions (probably just on RAW hazard). @@ -393,6 +399,8 @@ struct ir3_instruction { unsigned r : 1; /* read */ unsigned l : 1; /* local */ unsigned g : 1; /* global */ + + ir3_alias_scope alias_scope; } cat7; /* for meta-instructions, just used to hold extra data * before instruction scheduling, etc diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l index 1c9d3b3cf02..84eed7b6b54 100644 --- a/src/freedreno/ir3/ir3_lexer.l +++ b/src/freedreno/ir3/ir3_lexer.l @@ -380,6 +380,8 @@ static int parse_reg(const char *str) "stc" return TOKEN(T_OP_STC); "stsc" return TOKEN(T_OP_STSC); +("b16"|"b32"){1} ir3_yylval.str = yytext; return T_INSTR_TYPE; + /* category 7: */ "bar" return TOKEN(T_OP_BAR); "fence" return TOKEN(T_OP_FENCE); @@ -390,6 +392,7 @@ static int parse_reg(const char *str) "dcflu.all" return TOKEN(T_OP_DCFLU); "lock" return TOKEN(T_OP_LOCK); "unlock" return TOKEN(T_OP_UNLOCK); +"alias" return TOKEN(T_OP_ALIAS); "f16" return TOKEN(T_TYPE_F16); "f32" return TOKEN(T_TYPE_F32); @@ -432,6 +435,10 @@ static int parse_reg(const char *str) "nonuniform" return T_NONUNIFORM; "imm" return T_IMM; +"tex" return T_MOD_TEX; +"mem" return T_MOD_MEM; +"rt" return T_MOD_RT; + "h" return 'h'; "=" return '='; "(" return '('; diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index 51a7be7605f..56e5cadd5b1 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -629,6 +629,7 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token <tok> T_OP_DCFLU %token <tok> T_OP_LOCK %token <tok> T_OP_UNLOCK +%token <tok> T_OP_ALIAS %token <u64> T_RAW @@ -679,6 +680,11 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token <num> T_P0 %token <num> T_W %token <str> T_CAT1_TYPE_TYPE +%token <str> T_INSTR_TYPE + +%token <tok> T_MOD_TEX +%token <tok> T_MOD_MEM +%token <tok> T_MOD_RT %type <num> integer offset %type <num> flut_immed @@ -1307,12 +1313,25 @@ cat7_data_cache: T_OP_DCCLN { new_instr(OPC_DCCLN); } | T_OP_DCINV { new_instr(OPC_DCINV); } | T_OP_DCFLU { new_instr(OPC_DCFLU); } +cat7_alias_src: src_reg_or_const +| immediate_cat1 + +cat7_alias_scope: T_MOD_TEX { instr->cat7.alias_scope = ALIAS_TEX; } +| T_MOD_MEM { instr->cat7.alias_scope = ALIAS_MEM; } +| T_MOD_RT { instr->cat7.alias_scope = ALIAS_RT; } + cat7_instr: cat7_barrier | cat7_data_cache | T_OP_SLEEP { new_instr(OPC_SLEEP); } | T_OP_ICINV { new_instr(OPC_ICINV); } | T_OP_LOCK { new_instr(OPC_LOCK); } | T_OP_UNLOCK { new_instr(OPC_UNLOCK); } +| T_OP_ALIAS { + /* TODO: handle T_INSTR_TYPE */ + new_instr(OPC_ALIAS); + } '.' cat7_alias_scope '.' T_INSTR_TYPE '.' integer dst_reg ',' cat7_alias_src { + new_src(0, IR3_REG_IMMED)->uim_val = $8; + } raw_instr: T_RAW {new_instr(OPC_META_RAW)->raw.value = $1;} diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 6e2f0075051..c1b85ab621d 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -439,6 +439,11 @@ static const struct test { INSTR_7XX(e3c20000_00000000, "lock"), + /* dEQP-VK.pipeline.monolithic.sampler.border_swizzle.r4g4b4a4_unorm_pack16.rg1a.opaque_white.gather_1.no_swizzle_hint */ + INSTR_7XX(e45401a0_bfba7736, "alias.tex.b32.1 r40.x, (-1.456763)"), + /* dEQP-VK.synchronization.op.single_queue.event.write_draw_indexed_read_image_geometry.image_128x128_r32g32b32a32_sfloat */ + INSTR_7XX(e44c0009_00000007, "alias.tex.b32.0 r2.y, c1.w"), + INSTR_6XX(ffffffff_ffffffff, "raw 0xFFFFFFFFFFFFFFFF"), /* clang-format on */ }; diff --git a/src/freedreno/isa/ir3-cat6.xml b/src/freedreno/isa/ir3-cat6.xml index 7a288d4e521..4f4a6eedcb0 100644 --- a/src/freedreno/isa/ir3-cat6.xml +++ b/src/freedreno/isa/ir3-cat6.xml @@ -446,7 +446,7 @@ SOFTWARE. <pattern pos="0" >x</pattern> <field low="1" high="8" name="SRC" type="#reg-gpr"/> <pattern low="9" high="13">xxxxx</pattern> <!-- DST_HI --> - <pattern low="14" high="22">xxxxxxxxxxxxxx</pattern> + <pattern low="14" high="22">xxxxxxxxx</pattern> <pattern pos="23" >1</pattern> <field low="24" high="26" name="SIZE" type="uint"/> <pattern low="27" high="31">xxxxx</pattern> diff --git a/src/freedreno/isa/ir3-cat7.xml b/src/freedreno/isa/ir3-cat7.xml index 88a4e72c17e..651fda84062 100644 --- a/src/freedreno/isa/ir3-cat7.xml +++ b/src/freedreno/isa/ir3-cat7.xml @@ -169,4 +169,158 @@ SOFTWARE. <pattern low="55" high="58">0111</pattern> </bitset> +<bitset name="#alias-immed-src" size="32"> + <override> + <expr> + {SRC_TYPE} == 0 /* b16 */ + </expr> + <display> + h({IMMED}) + </display> + <field name="IMMED" low="0" high="15" type="float"/> + </override> + <override> + <expr> + {SRC_TYPE} == 1 /* b32 */ + </expr> + <display> + ({IMMED}) + </display> + <field name="IMMED" low="0" high="31" type="float"/> + </override> + + <display> + {IMMED} + </display> + + <field name="IMMED" low="0" high="31" type="uint"/> + <encode type="struct ir3_register *"> + <map name="IMMED">extract_reg_uim(src)</map> + </encode> +</bitset> + +<bitset name="#alias-const-src" size="11"> + <display> + {HALF}{CONST} + </display> + <field name="CONST" low="0" high="10" type="#reg-const"/> + <derived name="HALF" type="bool" display="h"> + <expr> + ({SRC_TYPE} == 0) /* b16 */ + </expr> + </derived> + <encode type="struct ir3_register *"> + <map name="CONST">src</map> + </encode> +</bitset> + +<bitset name="#alias-gpr-src" size="8"> + <display> + {HALF}{SRC} + </display> + <field name="SRC" low="0" high="7" type="#reg-gpr"/> + <derived name="HALF" type="bool" display="h"> + <expr> + ({SRC_TYPE} == 0) /* b16 */ + </expr> + </derived> + <encode type="struct ir3_register *"> + <map name="SRC">src</map> + </encode> +</bitset> + +<enum name="#alias-scope"> + <doc> + TODO: Yes, something is wrong here, needs to be tested. + </doc> + <value val="0" display="tex"/> + <value val="2" display="tex"/> + <value val="3" display="rt"/> + <value val="4" display="mem"/> +</enum> + +<enum name="#alias-src-type"> + <doc> + These types are clearly used by the blob. + However, it seems that there may be f32/f16/i32/i16 + types but they are interwind with the _scope_ bitfield. + TODO: Check if it does matter. + </doc> + <value val="0" display="b16"/> + <value val="1" display="b32"/> +</enum> + +<enum name="#alias-src-reg-type"> + <value val="0" display="GPR"/> + <value val="1" display="CONST"/> + <value val="2" display="IMMED"/> +</enum> + +<bitset name="alias" extends="#instruction"> + <doc> + Add an entry to the scope-specific "alias table", when instruction + from that scope tries to access a source register it would search + its alias table first. + + This allows to reduce the amount of data passed around when reading + immediates/constants and reduce register pressure. In addition, + the alias table could be populated in the preamble further reducing + the amount of instructions being run. + + Used like this: + alias.tex.b32.1 r40.x, (-1.456763); + alias.tex.b32.0 r40.y, (0.056702); + gather4g.s2en.mode6.base0 (f32)(xyzw)r0.x, r40.x, 1; + Or this: + alias.tex.b32.0 r2.y, c1.w; + isam.s2en.mode6.base0.1d (f32)(xyzw)r46.z, r2.y, 0; + (sy)stib.f32.2d.4.mode4.base0 r46.z, r2.y, 1; + + Notice the lack of nops between alias and the instruction + that uses it. + </doc> + <gen min="700"/> + <display> + {SY}{JP}{NAME}.{SCOPE}.{SRC_TYPE}.{UNK} {DST}, {SRC} + </display> + + <override> + <expr>{SRC_REG_TYPE} == 0</expr> + <field name="SRC" low="0" high="7" type="#alias-gpr-src"> + <param name="SRC_TYPE"/> + </field> + <pattern low="8" high="31">000000000000000000000000</pattern> + </override> + <override> + <expr>{SRC_REG_TYPE} == 1</expr> + <field name="SRC" low="0" high="10" type="#alias-const-src"> + <param name="SRC_TYPE"/> + </field> + <pattern low="11" high="31">000000000000000000000</pattern> + </override> + + <field name="SRC" low="0" high="31" type="#alias-immed-src"> + <param name="SRC_TYPE"/> + </field> + <field low="32" high="39" name="DST" type="#reg-gpr"/> + <field low="40" high="43" name="UNK" type="uint"/> + <pattern pos="44" >x</pattern> <!-- blob tells that it is (ss) --> + <pattern low="45" high="46">xx</pattern> + <field low="47" high="49" name="SCOPE" type="#alias-scope"/> + <field low="50" high="50" name="SRC_TYPE" type="#alias-src-type"/> + <field low="51" high="52" name="SRC_REG_TYPE" type="#alias-src-reg-type"/> + <pattern low="53" high="54">1x</pattern> + <pattern low="55" high="58">1000</pattern> <!-- OPC --> + <field pos="59" name="JP" type="bool" display="(jp)"/> + <field pos="60" name="SY" type="bool" display="(sy)"/> + <pattern low="61" high="63">111</pattern> <!-- cat7 --> + <encode> + <map name="SRC">src->srcs[0]</map> + <map name="SRC_REG_TYPE">(src->srcs[0]->flags & IR3_REG_CONST) ? 1 : ((src->srcs[0]->flags & IR3_REG_IMMED) ? 2 : 0)</map> + <map name="SRC_TYPE">1</map> <!-- TODO --> + <map name="UNK">extract_reg_uim(src->srcs[1])</map> + <map name="SCOPE">src->cat7.alias_scope</map> + </encode> +</bitset> + </isa> \ No newline at end of file
