%token <tok> T_OP_DCFLU
%token <tok> T_OP_LOCK
%token <tok> T_OP_UNLOCK
+%token <tok> T_OP_ALIAS
%token <u64> T_RAW
%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
| 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;}
<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