Mesa (main): ir3: add newly found shlg.b16 instruction

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 9 13:17:50 UTC 2021


Module: Mesa
Branch: main
Commit: 1c6c200c0d79329174d19ae694d11f762819eeba
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1c6c200c0d79329174d19ae694d11f762819eeba

Author: Danylo Piliaiev <dpiliaiev at igalia.com>
Date:   Wed Jul  7 14:40:52 2021 +0300

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 at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11760>

---

 src/freedreno/.gitlab-ci/reference/crash.log |  2 +-
 src/freedreno/ir3/disasm-a3xx.c              |  1 +
 src/freedreno/ir3/instr-a3xx.h               |  1 +
 src/freedreno/ir3/ir3.c                      | 11 +++-
 src/freedreno/ir3/ir3.h                      |  2 +
 src/freedreno/ir3/ir3_lexer.l                |  1 +
 src/freedreno/ir3/ir3_parser.y               |  6 +++
 src/freedreno/ir3/tests/disasm.c             |  3 ++
 src/freedreno/isa/encode.c                   |  6 +--
 src/freedreno/isa/ir3-cat3.xml               | 80 +++++++++++++++++++++++-----
 10 files changed, 95 insertions(+), 18 deletions(-)

diff --git a/src/freedreno/.gitlab-ci/reference/crash.log b/src/freedreno/.gitlab-ci/reference/crash.log
index bf9eba41180..bd197b41b43 100644
--- a/src/freedreno/.gitlab-ci/reference/crash.log
+++ b/src/freedreno/.gitlab-ci/reference/crash.log
@@ -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. at .6.R....|
diff --git a/src/freedreno/ir3/disasm-a3xx.c b/src/freedreno/ir3/disasm-a3xx.c
index 3be1a3ef9f0..d9b5d2167dd 100644
--- a/src/freedreno/ir3/disasm-a3xx.c
+++ b/src/freedreno/ir3/disasm-a3xx.c
@@ -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),
diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h
index 3400d35f03f..e66911679b6 100644
--- a/src/freedreno/ir3/instr-a3xx.h
+++ b/src/freedreno/ir3/instr-a3xx.h
@@ -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),
diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c
index b706ee163fd..e47f1df22bd 100644
--- a/src/freedreno/ir3/ir3.c
+++ b/src/freedreno/ir3/ir3.c
@@ -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;
diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h
index 3e0b4f0420b..16986b6c2e2 100644
--- a/src/freedreno/ir3/ir3.h
+++ b/src/freedreno/ir3/ir3.h
@@ -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;
 	}
diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l
index c5b263af910..cdee9ab9c26 100644
--- a/src/freedreno/ir3/ir3_lexer.l
+++ b/src/freedreno/ir3/ir3_lexer.l
@@ -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);
diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y
index ffc0f76b778..a2bf67dbcdc 100644
--- a/src/freedreno/ir3/ir3_parser.y
+++ b/src/freedreno/ir3/ir3_parser.y
@@ -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; }
diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c
index 31fcf97bf4a..604e96904fa 100644
--- a/src/freedreno/ir3/tests/disasm.c
+++ b/src/freedreno/ir3/tests/disasm.c
@@ -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"),
diff --git a/src/freedreno/isa/encode.c b/src/freedreno/isa/encode.c
index 470c7d38fa3..3dd0f6ab2fd 100644
--- a/src/freedreno/isa/encode.c
+++ b/src/freedreno/isa/encode.c
@@ -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;
 	}
diff --git a/src/freedreno/isa/ir3-cat3.xml b/src/freedreno/isa/ir3-cat3.xml
index f59e0aa099e..5e638e1543e 100644
--- a/src/freedreno/isa/ir3-cat3.xml
+++ b/src/freedreno/isa/ir3-cat3.xml
@@ -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 & 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 << 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"/>



More information about the mesa-commit mailing list