ir3: add newly found shlg.b16 instruction

Example of blob's output:
  (nop3) shlg.b16 hr8.x, (r)8, (r)hr8.x, 12

It does: (src2 << src1) | src2

src1 and src2 could be GPRs, relative GPRs, relative consts,
or immidiates. However, they could not be plain const registers.

Blob does use it in conjuncture with "samgq" instruction.

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11760>
This commit is contained in:
Danylo Piliaiev 2021-07-07 14:40:52 +03:00 committed by Marge Bot
parent 543eb42c35
commit 1c6c200c0d
10 changed files with 95 additions and 18 deletions

View file

@ -4118,7 +4118,7 @@ shader-blocks:
:1:0002:0002[200a00c1x_094864d2x] no match: 200a00c1094864d2
:2:0003:0003[44109084x_4a201507x] no match: 441090844a201507
:4:0004:0004[882fadabx_14a391b1x] (jp)(sat)(rpt1)(ul)rsq hr42.w, (abs)(r)hc108.y ; dontcare bits in rsq: f800014a30000
:3:0005:0006[6060f068x_7106601ax] (ss)(ul)mad.u16 r26.x, (neg)hr6.z, (neg)hr48.y, (r)hc65.z ; dontcare bits in mad.u16: 2000
:3:0005:0006[6060f068x_7106601ax] no match: 6060f0687106601a
-----------------------------------------------
8192 (0x2000) bytes
000000: d81251c5 40846422 520c369a 938a16e2 |.Q.."d.@.6.R....|

View file

@ -264,6 +264,7 @@ static const struct opc_info {
OPC(3, OPC_SEL_F32, sel.f32),
OPC(3, OPC_SAD_S16, sad.s16),
OPC(3, OPC_SAD_S32, sad.s32),
OPC(3, OPC_SHLG_B16, shlg.b16),
/* category 4: */
OPC(4, OPC_RCP, rcp),

View file

@ -192,6 +192,7 @@ typedef enum {
OPC_SEL_F32 = _OPC(3, 13),
OPC_SAD_S16 = _OPC(3, 14),
OPC_SAD_S32 = _OPC(3, 15),
OPC_SHLG_B16 = _OPC(3, 16),
/* category 4: */
OPC_RCP = _OPC(4, 0),

View file

@ -799,7 +799,16 @@ ir3_valid_flags(struct ir3_instruction *instr, unsigned n,
break;
case 3:
valid_flags = ir3_cat3_absneg(instr->opc) |
IR3_REG_CONST | IR3_REG_RELATIV | IR3_REG_SHARED;
IR3_REG_RELATIV | IR3_REG_SHARED;
if (instr->opc == OPC_SHLG_B16) {
valid_flags |= IR3_REG_IMMED;
/* shlg.b16 can be RELATIV+CONST but not CONST: */
if (flags & IR3_REG_RELATIV)
valid_flags |= IR3_REG_CONST;
} else {
valid_flags |= IR3_REG_CONST;
}
if (flags & ~valid_flags)
return false;

View file

@ -1243,6 +1243,8 @@ static inline unsigned ir3_cat3_absneg(opc_t opc)
case OPC_SEL_B16:
case OPC_SEL_B32:
case OPC_SHLG_B16:
default:
return 0;
}

View file

@ -251,6 +251,7 @@ static int parse_w(const char *str)
"sel.f32" return TOKEN(T_OP_SEL_F32);
"sad.s16" return TOKEN(T_OP_SAD_S16);
"sad.s32" return TOKEN(T_OP_SAD_S32);
"shlg.b16" return TOKEN(T_OP_SHLG_B16);
/* category 4: */
"rcp" return TOKEN(T_OP_RCP);

View file

@ -480,6 +480,7 @@ static void print_token(FILE *file, int type, YYSTYPE value)
%token <tok> T_OP_SEL_F32
%token <tok> T_OP_SAD_S16
%token <tok> T_OP_SAD_S32
%token <tok> T_OP_SHLG_B16
/* category 4: */
%token <tok> T_OP_RCP
@ -913,6 +914,7 @@ cat3_opc: T_OP_MAD_U16 { new_instr(OPC_MAD_U16); }
| T_OP_SAD_S32 { new_instr(OPC_SAD_S32); }
cat3_instr: cat3_opc dst_reg ',' src_reg_or_const_or_rel ',' src_reg_or_const ',' src_reg_or_const_or_rel
| T_OP_SHLG_B16 { new_instr(OPC_SHLG_B16); } dst_reg ',' src_reg_or_rel_or_imm ',' src_reg_or_const ',' src_reg_or_rel_or_imm
cat4_opc: T_OP_RCP { new_instr(OPC_RCP); }
| T_OP_RSQ { new_instr(OPC_RSQ); }
@ -1194,6 +1196,10 @@ src_reg_or_const_or_rel_or_imm: src_reg_or_const_or_rel
| src_reg_flags immediate
| immediate
src_reg_or_rel_or_imm: src_reg
| relative
| immediate
offset: { $$ = 0; }
| '+' integer { $$ = $2; }
| '-' integer { $$ = -$2; }

View file

@ -118,6 +118,9 @@ static const struct test {
INSTR_6XX(63820005_10315030, "mad.f32 r1.y, (neg)c12.x, r1.x, c12.y"),
INSTR_6XX(62050009_00091000, "mad.u24 r2.y, c0.x, r2.z, r2.y"),
INSTR_6XX(61828008_00081033, "madsh.m16 r2.x, c12.w, r1.y, r2.x"),
INSTR_6XX(65900820_100cb008, "(nop3) shlg.b16 hr8.x, 8, hr8.x, 12"), /* (nop3) shlg.b16 hr8.x, (r)8, (r)hr8.x, 12; */
INSTR_6XX(65ae085c_0002a001, "(nop3) shlg.b16 hr23.x, hr0.y, hr23.x, hr0.z"), /* not seen in blob */
INSTR_6XX(65900820_0c0aac05, "(nop3) shlg.b16 hr8.x, hc<a0.x + 5>, hr8.x, hc<a0.x + 10>"), /* not seen in blob */
/* cat4 */
INSTR_6XX(8010000a_00000003, "rcp r2.z, r0.w"),

View file

@ -271,7 +271,7 @@ __multisrc_case(struct encode_state *s, struct ir3_register *reg)
typedef enum {
REG_CAT3_SRC_GPR,
REG_CAT3_SRC_CONST,
REG_CAT3_SRC_CONST_OR_IMMED,
REG_CAT3_SRC_RELATIVE_GPR,
REG_CAT3_SRC_RELATIVE_CONST,
} reg_cat3_src_t;
@ -285,8 +285,8 @@ __cat3_src_case(struct encode_state *s, struct ir3_register *reg)
} else {
return REG_CAT3_SRC_RELATIVE_GPR;
}
} else if (reg->flags & IR3_REG_CONST) {
return REG_CAT3_SRC_CONST;
} else if (reg->flags & (IR3_REG_CONST | IR3_REG_IMMED)) {
return REG_CAT3_SRC_CONST_OR_IMMED;
} else {
return REG_CAT3_SRC_GPR;
}

View file

@ -49,7 +49,17 @@ SOFTWARE.
</encode>
</bitset>
<bitset name="#cat3-src-const" extends="#cat3-src">
<bitset name="#cat3-src-const-or-immed" extends="#cat3-src">
<override>
<expr>{IMMED_ENCODING}</expr>
<display>
{IMMED}
</display>
<field name="IMMED" low="0" high="11" type="uint"/>
<pattern pos="12">1</pattern>
</override>
<display>
{HALF}c{CONST}.{SWIZ}
</display>
@ -59,6 +69,7 @@ SOFTWARE.
<encode>
<map name="CONST">src->num >> 2</map>
<map name="SWIZ">src->num &amp; 0x3</map>
<map name="IMMED">src->uim_val</map>
</encode>
</bitset>
@ -85,7 +96,7 @@ SOFTWARE.
<pattern pos="10">1</pattern>
</bitset>
<bitset name="#instruction-cat3" extends="#instruction">
<bitset name="#instruction-cat3-base" extends="#instruction">
<override expr="#cat2-cat3-nop-encoding">
<display>
{SY}{SS}{JP}{SAT}(nop{NOP}) {UL}{NAME} {DST_HALF}{DST}, {SRC1_NEG}{SRC1}, {SRC2_NEG}{HALF}{SRC2}, {SRC3_NEG}{SRC3}
@ -95,19 +106,8 @@ SOFTWARE.
<display>
{SY}{SS}{JP}{SAT}{REPEAT}{UL}{NAME} {DST_HALF}{DST}, {SRC1_NEG}{SRC1_R}{SRC1}, {SRC2_NEG}{SRC2_R}{HALF}{SRC2}, {SRC3_NEG}{SRC3_R}{SRC3}
</display>
<field name="SRC1" low="0" high="12" type="#cat3-src">
<param name="HALF"/>
</field>
<!--
Note b13 triggers some different disasm, so possibly this
becomes OPC_HI ?
-->
<pattern pos="13">x</pattern>
<field name="SRC1_NEG" pos="14" type="bool" display="(neg)"/>
<field name="SRC2_R" pos="15" type="bool" display="(r)"/>
<field name="SRC3" low="16" high="28" type="#cat3-src">
<param name="HALF"/>
</field>
<field name="SRC3_R" pos="29" type="bool" display="(r)"/>
<field name="SRC2_NEG" pos="30" type="bool" display="(neg)"/>
<field name="SRC3_NEG" pos="31" type="bool" display="(neg)"/>
@ -146,6 +146,60 @@ SOFTWARE.
</encode>
</bitset>
<bitset name="#instruction-cat3" extends="#instruction-cat3-base">
<pattern pos="13">0</pattern>
<derived name="IMMED_ENCODING" expr="#false" type="bool" display="h"/>
<field name="SRC1" low="0" high="12" type="#cat3-src">
<param name="HALF"/>
<param name="IMMED_ENCODING"/>
</field>
<field name="SRC3" low="16" high="28" type="#cat3-src">
<param name="HALF"/>
<param name="IMMED_ENCODING"/>
</field>
</bitset>
<bitset name="#instruction-cat3-alt" extends="#instruction-cat3-base">
<doc>
The difference is that this cat3 version does not support plain
const registers as src1/src3 but does support inmidiate values.
On the other hand it still supports relative gpr and consts.
</doc>
<pattern pos="13">1</pattern>
<derived name="IMMED_ENCODING" expr="#true" type="bool" display="h"/>
<field name="SRC1" low="0" high="12" type="#cat3-src">
<param name="HALF"/>
<param name="IMMED_ENCODING"/>
</field>
<field name="SRC3" low="16" high="28" type="#cat3-src">
<param name="HALF"/>
<param name="IMMED_ENCODING"/>
</field>
<encode>
<map name="SRC3">src->srcs[2]</map>
<map name="DST_CONV">false</map>
</encode>
</bitset>
<!-- TODO find shlg.b32 -->
<bitset name="shlg.b16" extends="#instruction-cat3-alt">
<doc>
(src2 &lt;&lt; src1) | src3
</doc>
<!-- TODO check older gens -->
<gen min="600"/>
<pattern low="55" high="58">1011</pattern> <!-- OPC -->
<derived name="FULL" expr="#false" type="bool"/>
</bitset>
<bitset name="mad.u16" extends="#instruction-cat3">
<pattern low="55" high="58">0000</pattern> <!-- OPC -->
<derived name="FULL" expr="#false" type="bool"/>