ir3/a7xx: Document "alias" instruction
authorDanylo Piliaiev <dpiliaiev@igalia.com>
Thu, 23 Feb 2023 16:50:47 +0000 (17:50 +0100)
committerMarge Bot <emma+marge@anholt.net>
Thu, 27 Apr 2023 21:06:47 +0000 (21:06 +0000)
Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21498>

src/freedreno/ir3/instr-a3xx.h
src/freedreno/ir3/ir3.h
src/freedreno/ir3/ir3_lexer.l
src/freedreno/ir3/ir3_parser.y
src/freedreno/ir3/tests/disasm.c
src/freedreno/isa/ir3-cat6.xml
src/freedreno/isa/ir3-cat7.xml

index 4d3e0a4..78178f9 100644 (file)
@@ -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: */
index aace5df..9c829b5 100644 (file)
@@ -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
index 1c9d3b3..84eed7b 100644 (file)
@@ -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 '(';
index 51a7be7..56e5cad 100644 (file)
@@ -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;}
 
index 6e2f007..c1b85ab 100644 (file)
@@ -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 */
 };
index 7a288d4..4f4a6ee 100644 (file)
@@ -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>
index 88a4e72..651fda8 100644 (file)
@@ -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 &amp; IR3_REG_CONST) ? 1 : ((src->srcs[0]->flags &amp; 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