Mesa (master): freedreno/ir3: sync disasm changes from envytools

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Nov 9 03:07:48 UTC 2019


Module: Mesa
Branch: master
Commit: 5f45818673ec9edeafd60b79231c22e161793b91
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5f45818673ec9edeafd60b79231c22e161793b91

Author: Rob Clark <robdclark at chromium.org>
Date:   Mon Nov  4 11:33:54 2019 -0800

freedreno/ir3: sync disasm changes from envytools

Signed-off-by: Rob Clark <robdclark at chromium.org>

---

 src/freedreno/ir3/disasm-a3xx.c | 109 +++++++++++++++++++++++++++++++---------
 src/freedreno/ir3/instr-a3xx.h  |   9 +++-
 2 files changed, 94 insertions(+), 24 deletions(-)

diff --git a/src/freedreno/ir3/disasm-a3xx.c b/src/freedreno/ir3/disasm-a3xx.c
index 85a9c9e5d71..1cd82876edb 100644
--- a/src/freedreno/ir3/disasm-a3xx.c
+++ b/src/freedreno/ir3/disasm-a3xx.c
@@ -36,6 +36,7 @@
 enum debug_t {
 	PRINT_RAW      = 0x1,    /* dump raw hexdump */
 	PRINT_VERBOSE  = 0x2,
+	EXPAND_REPEAT  = 0x4,
 };
 
 static enum debug_t debug;
@@ -81,6 +82,8 @@ struct disasm_ctx {
 
 	/* current instruction repeat flag: */
 	unsigned repeat;
+	/* current instruction repeat indx/offset (for --expand): */
+	unsigned repeatidx;
 };
 
 static void print_reg(struct disasm_ctx *ctx, reg_t reg, bool full, bool r,
@@ -122,15 +125,31 @@ static void print_reg(struct disasm_ctx *ctx, reg_t reg, bool full, bool r,
 	}
 }
 
+static unsigned regidx(reg_t reg)
+{
+	return (4 * reg.num) + reg.comp;
+}
+
+static reg_t idxreg(unsigned idx)
+{
+	return (reg_t){
+		.comp = idx & 0x3,
+		.num  = idx >> 2,
+	};
+}
 
 static void print_reg_dst(struct disasm_ctx *ctx, reg_t reg, bool full, bool addr_rel)
 {
+	reg = idxreg(regidx(reg) + ctx->repeatidx);
 	print_reg(ctx, reg, full, false, false, false, false, false, addr_rel);
 }
 
 static void print_reg_src(struct disasm_ctx *ctx, reg_t reg, bool full, bool r,
 		bool c, bool im, bool neg, bool abs, bool addr_rel)
 {
+	if (r)
+		reg = idxreg(regidx(reg) + ctx->repeatidx);
+
 	print_reg(ctx, reg, full, r, c, im, neg, abs, addr_rel);
 }
 
@@ -770,14 +789,13 @@ static void print_instr_cat6_a3xx(struct disasm_ctx *ctx, instr_t *instr)
 		/* note: dst might actually be a src (ie. address to store to) */
 		print_src(ctx, &dst);
 		if (cat6->dst_off && cat6->g) {
-			struct reginfo dstoff_reg = {};
+			struct reginfo dstoff_reg = {0};
 			dstoff_reg.reg = (reg_t) cat6->c.off;
-			dstoff_reg.full = true;
+			dstoff_reg.full  = true;
 			fprintf(ctx->out, "+");
 			print_src(ctx, &dstoff_reg);
-		} else if (dstoff) {
+		} else if (dstoff)
 			fprintf(ctx->out, "%+d", dstoff);
-		}
 		if (sd)
 			fprintf(ctx->out, "]");
 		fprintf(ctx->out, ", ");
@@ -989,6 +1007,9 @@ static const struct opc_info {
 	OPC(4, OPC_SIN,          sin),
 	OPC(4, OPC_COS,          cos),
 	OPC(4, OPC_SQRT,         sqrt),
+	OPC(4, OPC_HRSQ,         hrsq),
+	OPC(4, OPC_HLOG2,        hlog2),
+	OPC(4, OPC_HEXP2,        hexp2),
 
 	/* category 5: */
 	OPC(5, OPC_ISAM,         isam),
@@ -1069,11 +1090,35 @@ const char *ir3_instr_name(struct ir3_instruction *instr)
 	return opcs[instr->opc].name;
 }
 
+static void print_single_instr(struct disasm_ctx *ctx, instr_t *instr)
+{
+	const char *name = GETINFO(instr)->name;
+	uint32_t opc = instr_opc(instr, ctx->gpu_id);
+
+	if (name) {
+		fprintf(ctx->out, "%s", name);
+		GETINFO(instr)->print(ctx, instr);
+	} else {
+		fprintf(ctx->out, "unknown(%d,%d)", instr->opc_cat, opc);
+
+		switch (instr->opc_cat) {
+		case 0: print_instr_cat0(ctx, instr); break;
+		case 1: print_instr_cat1(ctx, instr); break;
+		case 2: print_instr_cat2(ctx, instr); break;
+		case 3: print_instr_cat3(ctx, instr); break;
+		case 4: print_instr_cat4(ctx, instr); break;
+		case 5: print_instr_cat5(ctx, instr); break;
+		case 6: print_instr_cat6(ctx, instr); break;
+		case 7: print_instr_cat7(ctx, instr); break;
+		}
+	}
+}
+
 static bool print_instr(struct disasm_ctx *ctx, uint32_t *dwords, int n)
 {
 	instr_t *instr = (instr_t *)dwords;
 	uint32_t opc = instr_opc(instr, ctx->gpu_id);
-	const char *name;
+	unsigned nop = 0;
 
 	if (debug & PRINT_VERBOSE)
 		fprintf(ctx->out, "%s%04d[%08xx_%08xx] ", levels[ctx->level], n, dwords[1], dwords[0]);
@@ -1085,36 +1130,46 @@ static bool print_instr(struct disasm_ctx *ctx, uint32_t *dwords, int n)
 
 	ctx->repeat = instr_repeat(instr);
 
-	if (instr->sync)
+	if (instr->sync) {
 		fprintf(ctx->out, "(sy)");
-	if (instr->ss && ((instr->opc_cat <= 4) || (instr->opc_cat == 7)))
+	}
+	if (instr->ss && ((instr->opc_cat <= 4) || (instr->opc_cat == 7))) {
 		fprintf(ctx->out, "(ss)");
+	}
 	if (instr->jmp_tgt)
 		fprintf(ctx->out, "(jp)");
 	if (instr_sat(instr))
 		fprintf(ctx->out, "(sat)");
-	if (ctx->repeat) {
+	if (ctx->repeat)
 		fprintf(ctx->out, "(rpt%d)", ctx->repeat);
-	} else if ((instr->opc_cat == 2) && (instr->cat2.src1_r || instr->cat2.src2_r)) {
-		unsigned nop = (instr->cat2.src2_r * 2) + instr->cat2.src1_r;
-		fprintf(ctx->out, "(nop%d)", nop);
-	} else if ((instr->opc_cat == 3) && (instr->cat3.src1_r || instr->cat3.src2_r)) {
-		unsigned nop = (instr->cat3.src2_r * 2) + instr->cat3.src1_r;
+	else if ((instr->opc_cat == 2) && (instr->cat2.src1_r || instr->cat2.src2_r))
+		nop = (instr->cat2.src2_r * 2) + instr->cat2.src1_r;
+	else if ((instr->opc_cat == 3) && (instr->cat3.src1_r || instr->cat3.src2_r))
+		nop = (instr->cat3.src2_r * 2) + instr->cat3.src1_r;
+	if (nop)
 		fprintf(ctx->out, "(nop%d)", nop);
-	}
+
 	if (instr->ul && ((2 <= instr->opc_cat) && (instr->opc_cat <= 4)))
 		fprintf(ctx->out, "(ul)");
 
-	name = GETINFO(instr)->name;
+	print_single_instr(ctx, instr);
+	fprintf(ctx->out, "\n");
 
-	if (name) {
-		fprintf(ctx->out, "%s", name);
-		GETINFO(instr)->print(ctx, instr);
-	} else {
-		fprintf(ctx->out, "unknown(%d,%d)", instr->opc_cat, opc);
-	}
+	if ((instr->opc_cat <= 4) && (debug & EXPAND_REPEAT)) {
+		int i;
+		for (i = 0; i < nop; i++) {
+			fprintf(ctx->out, "%s%04d[                   ] ", levels[ctx->level], n);
+			fprintf(ctx->out, "nop\n");
+		}
+		for (i = 0; i < ctx->repeat; i++) {
+			ctx->repeatidx = i + 1;
+			fprintf(ctx->out, "%s%04d[                   ] ", levels[ctx->level], n);
 
-	fprintf(ctx->out, "\n");
+			print_single_instr(ctx, instr);
+			fprintf(ctx->out, "\n");
+		}
+		ctx->repeatidx = 0;
+	}
 
 	return (instr->opc_cat == 0) && (opc == OPC_END);
 }
@@ -1123,6 +1178,7 @@ int disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned
 {
 	struct disasm_ctx ctx;
 	int i;
+	int nop_count = 0;
 
 	assert((sizedwords % 2) == 0);
 
@@ -1131,8 +1187,15 @@ int disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned
 	ctx.level = level;
 	ctx.gpu_id = gpu_id;
 
-	for (i = 0; i < sizedwords; i += 2)
+	for (i = 0; i < sizedwords; i += 2) {
 		print_instr(&ctx, &dwords[i], i/2);
+		if (dwords[i] == 0 && dwords[i + 1] == 0)
+			nop_count++;
+		else
+			nop_count = 0;
+		if (nop_count > 3)
+			break;
+	}
 
 	return 0;
 }
diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h
index 9f460c9cdce..30f5e37953c 100644
--- a/src/freedreno/ir3/instr-a3xx.h
+++ b/src/freedreno/ir3/instr-a3xx.h
@@ -136,7 +136,14 @@ typedef enum {
 	OPC_SIN             = _OPC(4, 4),
 	OPC_COS             = _OPC(4, 5),
 	OPC_SQRT            = _OPC(4, 6),
-	// 7-63 - invalid
+	/* NOTE that these are 8+opc from their highp equivs, so it's possible
+	 * that the high order bit in the opc field has been repurposed for
+	 * half-precision use?  But note that other ops (rcp/lsin/cos/sqrt)
+	 * still use the same opc as highp
+	 */
+	OPC_HRSQ            = _OPC(4, 9),
+	OPC_HLOG2           = _OPC(4, 10),
+	OPC_HEXP2           = _OPC(4, 11),
 
 	/* category 5: */
 	OPC_ISAM            = _OPC(5, 0),




More information about the mesa-commit mailing list