ir3: Improve cat1 modifier disassembly

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>
This commit is contained in:
Connor Abbott
2021-04-16 14:07:44 +02:00
committed by Marge Bot
parent 4c5b696cc3
commit d48d43039a
8 changed files with 34 additions and 17 deletions

View File

@@ -355,6 +355,13 @@ static inline int type_sint(type_t type)
return (type == TYPE_S32) || (type == TYPE_S16) || (type == TYPE_S8); 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 { typedef union PACKED {
/* normal gpr or const src register: */ /* normal gpr or const src register: */
struct PACKED { struct PACKED {

View File

@@ -108,8 +108,6 @@ struct ir3_register {
IR3_REG_SNEG = 0x100, IR3_REG_SNEG = 0x100,
IR3_REG_SABS = 0x200, IR3_REG_SABS = 0x200,
IR3_REG_BNOT = 0x400, IR3_REG_BNOT = 0x400,
IR3_REG_EVEN = 0x800,
IR3_REG_POS_INF= 0x1000,
/* (ei) flag, end-input? Set on last bary, presumably to signal /* (ei) flag, end-input? Set on last bary, presumably to signal
* that the shader needs no more input: * that the shader needs no more input:
*/ */
@@ -264,6 +262,7 @@ struct ir3_instruction {
} cat0; } cat0;
struct { struct {
type_t src_type, dst_type; type_t src_type, dst_type;
round_t round;
} cat1; } cat1;
struct { struct {
enum { enum {

View File

@@ -37,7 +37,7 @@ is_fp16_conv(struct ir3_instruction *instr)
/* disallow conversions that cannot be folded into /* disallow conversions that cannot be folded into
* alu instructions: * alu instructions:
*/ */
if (dst->flags & (IR3_REG_EVEN | IR3_REG_POS_INF)) if (instr->cat1.round != ROUND_ZERO)
return false; return false;
if (dst->flags & (IR3_REG_RELATIV | IR3_REG_ARRAY)) if (dst->flags & (IR3_REG_RELATIV | IR3_REG_ARRAY))

View File

@@ -260,7 +260,7 @@ create_cov(struct ir3_context *ctx, struct ir3_instruction *src,
ir3_COV(ctx->block, src, src_type, dst_type); ir3_COV(ctx->block, src, src_type, dst_type);
if (op == nir_op_f2f16 || op == nir_op_f2f16_rtne) if (op == nir_op_f2f16 || op == nir_op_f2f16_rtne)
cov->regs[0]->flags |= IR3_REG_EVEN; cov->cat1.round = ROUND_EVEN;
return cov; return cov;
} }

View File

@@ -125,6 +125,7 @@ static int parse_w(const char *str)
"(ul)" return TOKEN(T_UL); "(ul)" return TOKEN(T_UL);
"(even)" return TOKEN(T_EVEN); "(even)" return TOKEN(T_EVEN);
"(pos_infinity)" return TOKEN(T_POS_INFINITY); "(pos_infinity)" return TOKEN(T_POS_INFINITY);
"(neg_infinity)" return TOKEN(T_NEG_INFINITY);
"(ei)" return TOKEN(T_EI); "(ei)" return TOKEN(T_EI);
"(jp)" return TOKEN(T_JP); "(jp)" return TOKEN(T_JP);
"(sat)" return TOKEN(T_SAT); "(sat)" return TOKEN(T_SAT);

View File

@@ -334,6 +334,7 @@ static void print_token(FILE *file, int type, YYSTYPE value)
/* dst register flags */ /* dst register flags */
%token <tok> T_EVEN %token <tok> T_EVEN
%token <tok> T_POS_INFINITY %token <tok> T_POS_INFINITY
%token <tok> T_NEG_INFINITY
%token <tok> T_EI %token <tok> T_EI
%token <num> T_WRMASK %token <num> T_WRMASK
@@ -1113,8 +1114,9 @@ reg: T_REGISTER { $$ = new_reg($1, 0); }
const: T_CONSTANT { $$ = new_reg($1, IR3_REG_CONST); } const: T_CONSTANT { $$ = new_reg($1, IR3_REG_CONST); }
dst_reg_flag: T_EVEN { rflags.flags |= IR3_REG_EVEN; } dst_reg_flag: T_EVEN { instr->cat1.round = ROUND_EVEN; }
| T_POS_INFINITY { rflags.flags |= IR3_REG_POS_INF; } | 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_EI { rflags.flags |= IR3_REG_EI; }
| T_WRMASK { rflags.wrmask = $1; } | T_WRMASK { rflags.wrmask = $1; }

View File

@@ -672,10 +672,12 @@ is_self_mov(struct ir3_instruction *instr)
if (instr->regs[0]->flags & IR3_REG_RELATIV) if (instr->regs[0]->flags & IR3_REG_RELATIV)
return false; return false;
if (instr->cat1.round != ROUND_ZERO)
return false;
if (instr->regs[1]->flags & (IR3_REG_CONST | IR3_REG_IMMED | if (instr->regs[1]->flags & (IR3_REG_CONST | IR3_REG_IMMED |
IR3_REG_RELATIV | IR3_REG_FNEG | IR3_REG_FABS | IR3_REG_RELATIV | IR3_REG_FNEG | IR3_REG_FABS |
IR3_REG_SNEG | IR3_REG_SABS | IR3_REG_BNOT | IR3_REG_SNEG | IR3_REG_SABS | IR3_REG_BNOT))
IR3_REG_EVEN | IR3_REG_POS_INF))
return false; return false;
return true; return true;

View File

@@ -60,16 +60,23 @@ SOFTWARE.
</encode> </encode>
</bitset> </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"> <bitset name="#instruction-cat1" extends="#instruction">
<field name="DST" low="32" high="39" type="#cat1-dst"> <field name="DST" low="32" high="39" type="#cat1-dst">
<param name="DST_REL"/> <param name="DST_REL"/>
</field> </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="SS" pos="44" type="bool" display="(ss)"/>
<field name="UL" pos="45" type="bool" display="(ul)"/> <field name="UL" pos="45" type="bool" display="(ul)"/>
<field name="DST_REL" pos="49" type="bool"/> <field name="DST_REL" pos="49" type="bool"/>
<field name="EVEN" pos="55" type="bool" display="(even)"/> <field name="ROUND" low="55" high="56" type="#round"/>
<field name="POS_INF" pos="56" type="bool" display="(pos_infinity)"/>
<field name="JP" pos="59" type="bool" display="(jp)"/> <field name="JP" pos="59" type="bool" display="(jp)"/>
<field name="SY" pos="60" type="bool" display="(sy)"/> <field name="SY" pos="60" type="bool" display="(sy)"/>
<pattern low="61" high="63">001</pattern> <!-- cat1 --> <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_TYPE">src->cat1.dst_type</map>
<map name="DST_REL">!!(src->regs[0]->flags &amp; IR3_REG_RELATIV)</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="SRC_TYPE">src->cat1.src_type</map>
<map name="EVEN">!!(src->regs[0]->flags &amp; IR3_REG_EVEN)</map> <map name="ROUND">src->cat1.round</map>
<map name="POS_INF">!!(src->regs[0]->flags &amp; IR3_REG_POS_INF)</map>
</encode> </encode>
</bitset> </bitset>
@@ -91,7 +97,7 @@ SOFTWARE.
({DST} == 0xf4 /* a0.x */) &amp;&amp; ({SRC_TYPE} == 4 /* s16 */) &amp;&amp; ({DST_TYPE} == 4) ({DST} == 0xf4 /* a0.x */) &amp;&amp; ({SRC_TYPE} == 4 /* s16 */) &amp;&amp; ({DST_TYPE} == 4)
</expr> </expr>
<display> <display>
{SY}{SS}{JP}{REPEAT}{UL}mova {EVEN}{POS_INF}a0.x, {SRC} {SY}{SS}{JP}{REPEAT}{UL}mova {ROUND}a0.x, {SRC}
</display> </display>
<assert low="32" high="39">11110100</assert> <!-- DST==a0.x --> <assert low="32" high="39">11110100</assert> <!-- DST==a0.x -->
<assert low="46" high="48">100</assert> <!-- DST_TYPE==s16 --> <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) ({DST} == 0xf5 /* a0.y */) &amp;&amp; ({SRC_TYPE} == 2 /* u16 */) &amp;&amp; ({DST_TYPE} == 2)
</expr> </expr>
<display> <display>
{SY}{SS}{JP}{REPEAT}{UL}mova1 {EVEN}{POS_INF}a1.x, {SRC} {SY}{SS}{JP}{REPEAT}{UL}mova1 {ROUND}a1.x, {SRC}
</display> </display>
<assert low="32" high="39">11110101</assert> <!-- DST==a0.y --> <assert low="32" high="39">11110101</assert> <!-- DST==a0.y -->
<assert low="46" high="48">010</assert> <!-- DST_TYPE==u16 --> <assert low="46" high="48">010</assert> <!-- DST_TYPE==u16 -->
@@ -113,11 +119,11 @@ SOFTWARE.
{SRC_TYPE} != {DST_TYPE} {SRC_TYPE} != {DST_TYPE}
</expr> </expr>
<display> <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> </display>
</override> </override>
<display> <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> </display>
<pattern low="57" high="58">00</pattern> <!-- OPC --> <pattern low="57" high="58">00</pattern> <!-- OPC -->
<derived name="HALF" type="bool" display="h"> <derived name="HALF" type="bool" display="h">