ir3: Improve cat1 modifier disassembly
authorConnor Abbott <cwabbott0@gmail.com>
Fri, 16 Apr 2021 12:07:44 +0000 (14:07 +0200)
committerMarge Bot <eric+marge@anholt.net>
Mon, 19 Apr 2021 16:10:44 +0000 (16:10 +0000)
Remove bit that shouldn't be part of (rptN), and rewrite the handling of
(even) and (pos_infinity) to uncover a missing (neg_infinity) modifier.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10291>

src/freedreno/ir3/instr-a3xx.h
src/freedreno/ir3/ir3.h
src/freedreno/ir3/ir3_cf.c
src/freedreno/ir3/ir3_compiler_nir.c
src/freedreno/ir3/ir3_lexer.l
src/freedreno/ir3/ir3_parser.y
src/freedreno/ir3/ir3_postsched.c
src/freedreno/isa/ir3-cat1.xml

index 4fc1d51..b56983a 100644 (file)
@@ -355,6 +355,13 @@ static inline int type_sint(type_t type)
        return (type == TYPE_S32) || (type == TYPE_S16) || (type == TYPE_S8);
 }
 
+typedef enum {
+       ROUND_ZERO = 0,
+       ROUND_EVEN = 1,
+       ROUND_POS_INF = 2,
+       ROUND_NEG_INF = 3,
+} round_t;
+
 typedef union PACKED {
        /* normal gpr or const src register: */
        struct PACKED {
index bc11f89..87c8144 100644 (file)
@@ -108,8 +108,6 @@ struct ir3_register {
                IR3_REG_SNEG   = 0x100,
                IR3_REG_SABS   = 0x200,
                IR3_REG_BNOT   = 0x400,
-               IR3_REG_EVEN   = 0x800,
-               IR3_REG_POS_INF= 0x1000,
                /* (ei) flag, end-input?  Set on last bary, presumably to signal
                 * that the shader needs no more input:
                 */
@@ -264,6 +262,7 @@ struct ir3_instruction {
                } cat0;
                struct {
                        type_t src_type, dst_type;
+                       round_t round;
                } cat1;
                struct {
                        enum {
index 62014f8..d479bc1 100644 (file)
@@ -37,7 +37,7 @@ is_fp16_conv(struct ir3_instruction *instr)
        /* disallow conversions that cannot be folded into
         * alu instructions:
         */
-       if (dst->flags & (IR3_REG_EVEN | IR3_REG_POS_INF))
+       if (instr->cat1.round != ROUND_ZERO)
                return false;
 
        if (dst->flags & (IR3_REG_RELATIV | IR3_REG_ARRAY))
index b6a5e91..8065c30 100644 (file)
@@ -260,7 +260,7 @@ create_cov(struct ir3_context *ctx, struct ir3_instruction *src,
                ir3_COV(ctx->block, src, src_type, dst_type);
 
        if (op == nir_op_f2f16 || op == nir_op_f2f16_rtne)
-               cov->regs[0]->flags |= IR3_REG_EVEN;
+               cov->cat1.round = ROUND_EVEN;
 
        return cov;
 }
index 47edd07..568145a 100644 (file)
@@ -125,6 +125,7 @@ static int parse_w(const char *str)
 "(ul)"                            return TOKEN(T_UL);
 "(even)"                          return TOKEN(T_EVEN);
 "(pos_infinity)"                  return TOKEN(T_POS_INFINITY);
+"(neg_infinity)"                  return TOKEN(T_NEG_INFINITY);
 "(ei)"                            return TOKEN(T_EI);
 "(jp)"                            return TOKEN(T_JP);
 "(sat)"                           return TOKEN(T_SAT);
index 6498aec..fc684a5 100644 (file)
@@ -334,6 +334,7 @@ static void print_token(FILE *file, int type, YYSTYPE value)
 /* dst register flags */
 %token <tok> T_EVEN
 %token <tok> T_POS_INFINITY
+%token <tok> T_NEG_INFINITY
 %token <tok> T_EI
 %token <num> T_WRMASK
 
@@ -1113,8 +1114,9 @@ reg:               T_REGISTER     { $$ = new_reg($1, 0); }
 
 const:             T_CONSTANT     { $$ = new_reg($1, IR3_REG_CONST); }
 
-dst_reg_flag:      T_EVEN         { rflags.flags |= IR3_REG_EVEN; }
-|                  T_POS_INFINITY { rflags.flags |= IR3_REG_POS_INF; }
+dst_reg_flag:      T_EVEN         { instr->cat1.round = ROUND_EVEN; }
+|                  T_POS_INFINITY { instr->cat1.round = ROUND_POS_INF; }
+|                  T_NEG_INFINITY { instr->cat1.round = ROUND_NEG_INF; }
 |                  T_EI           { rflags.flags |= IR3_REG_EI; }
 |                  T_WRMASK       { rflags.wrmask = $1; }
 
index f2ff6a0..614f1bf 100644 (file)
@@ -672,10 +672,12 @@ is_self_mov(struct ir3_instruction *instr)
        if (instr->regs[0]->flags & IR3_REG_RELATIV)
                return false;
 
+       if (instr->cat1.round != ROUND_ZERO)
+               return false;
+
        if (instr->regs[1]->flags & (IR3_REG_CONST | IR3_REG_IMMED |
                        IR3_REG_RELATIV | IR3_REG_FNEG | IR3_REG_FABS |
-                       IR3_REG_SNEG | IR3_REG_SABS | IR3_REG_BNOT |
-                       IR3_REG_EVEN | IR3_REG_POS_INF))
+                       IR3_REG_SNEG | IR3_REG_SABS | IR3_REG_BNOT))
                return false;
 
        return true;
index e55c735..671ccd4 100644 (file)
@@ -60,16 +60,23 @@ SOFTWARE.
        </encode>
 </bitset>
 
+<enum name="#round">
+       <value val="0" display=""/>
+       <value val="1" display="(even)"/>
+       <value val="2" display="(pos_infinity)"/>
+       <value val="3" display="(neg_infinity)"/>
+</enum>
+
 <bitset name="#instruction-cat1" extends="#instruction">
        <field name="DST" low="32" high="39" type="#cat1-dst">
                <param name="DST_REL"/>
        </field>
-       <field name="REPEAT" low="40" high="42" type="#rptN"/>
+       <field name="REPEAT" low="40" high="41" type="#rptN"/>
+       <pattern pos="42">0</pattern>
        <field name="SS" pos="44" type="bool" display="(ss)"/>
        <field name="UL" pos="45" type="bool" display="(ul)"/>
        <field name="DST_REL" pos="49" type="bool"/>
-       <field name="EVEN" pos="55" type="bool" display="(even)"/>
-       <field name="POS_INF" pos="56" type="bool" display="(pos_infinity)"/>
+       <field name="ROUND" low="55" high="56" type="#round"/>
        <field name="JP" pos="59" type="bool" display="(jp)"/>
        <field name="SY" pos="60" type="bool" display="(sy)"/>
        <pattern low="61" high="63">001</pattern>  <!-- cat1 -->
@@ -80,8 +87,7 @@ SOFTWARE.
                <map name="DST_TYPE">src->cat1.dst_type</map>
                <map name="DST_REL">!!(src->regs[0]->flags &amp; IR3_REG_RELATIV)</map>
                <map name="SRC_TYPE">src->cat1.src_type</map>
-               <map name="EVEN">!!(src->regs[0]->flags &amp; IR3_REG_EVEN)</map>
-               <map name="POS_INF">!!(src->regs[0]->flags &amp; IR3_REG_POS_INF)</map>
+               <map name="ROUND">src->cat1.round</map>
        </encode>
 </bitset>
 
@@ -91,7 +97,7 @@ SOFTWARE.
                        ({DST} == 0xf4 /* a0.x */) &amp;&amp; ({SRC_TYPE} == 4 /* s16 */) &amp;&amp; ({DST_TYPE} == 4)
                </expr>
                <display>
-                       {SY}{SS}{JP}{REPEAT}{UL}mova {EVEN}{POS_INF}a0.x, {SRC}
+                       {SY}{SS}{JP}{REPEAT}{UL}mova {ROUND}a0.x, {SRC}
                </display>
                <assert low="32" high="39">11110100</assert>  <!-- DST==a0.x -->
                <assert low="46" high="48">100</assert>       <!-- DST_TYPE==s16 -->
@@ -102,7 +108,7 @@ SOFTWARE.
                        ({DST} == 0xf5 /* a0.y */) &amp;&amp; ({SRC_TYPE} == 2 /* u16 */) &amp;&amp; ({DST_TYPE} == 2)
                </expr>
                <display>
-                       {SY}{SS}{JP}{REPEAT}{UL}mova1 {EVEN}{POS_INF}a1.x, {SRC}
+                       {SY}{SS}{JP}{REPEAT}{UL}mova1 {ROUND}a1.x, {SRC}
                </display>
                <assert low="32" high="39">11110101</assert>  <!-- DST==a0.y -->
                <assert low="46" high="48">010</assert>       <!-- DST_TYPE==u16 -->
@@ -113,11 +119,11 @@ SOFTWARE.
                        {SRC_TYPE} != {DST_TYPE}
                </expr>
                <display>
-                       {SY}{SS}{JP}{REPEAT}{UL}cov.{SRC_TYPE}{DST_TYPE} {EVEN}{POS_INF}{DST_HALF}{DST}, {SRC}
+                       {SY}{SS}{JP}{REPEAT}{UL}cov.{SRC_TYPE}{DST_TYPE} {ROUND}{DST_HALF}{DST}, {SRC}
                </display>
        </override>
        <display>
-               {SY}{SS}{JP}{REPEAT}{UL}mov.{SRC_TYPE}{DST_TYPE} {EVEN}{POS_INF}{DST_HALF}{DST}, {SRC}
+               {SY}{SS}{JP}{REPEAT}{UL}mov.{SRC_TYPE}{DST_TYPE} {ROUND}{DST_HALF}{DST}, {SRC}
        </display>
        <pattern low="57" high="58">00</pattern>  <!-- OPC -->
        <derived name="HALF" type="bool" display="h">