Mesa (master): freedreno/ir3: Sync some new changes from envytools.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon May 4 18:39:10 UTC 2020


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

Author: Eric Anholt <eric at anholt.net>
Date:   Fri May  1 14:37:27 2020 -0700

freedreno/ir3: Sync some new changes from envytools.

With this I also brought in a few new control flow instruction disasm
tests that I'd made back when I wrote the disasm test, but which were too
far from correct to include until now.

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

---

 src/freedreno/ir3/disasm-a3xx.c      | 65 ++++++++++++++++++++++++++++--------
 src/freedreno/ir3/instr-a3xx.h       | 43 +++++++++++++++++++-----
 src/freedreno/ir3/ir3.c              | 15 ++-------
 src/freedreno/ir3/ir3.h              |  8 ++---
 src/freedreno/ir3/ir3_compiler_nir.c |  4 +--
 src/freedreno/ir3/ir3_delay.c        |  2 +-
 src/freedreno/ir3/ir3_legalize.c     |  8 ++---
 src/freedreno/ir3/ir3_parser.y       |  2 +-
 src/freedreno/ir3/ir3_postsched.c    |  2 +-
 src/freedreno/ir3/ir3_print.c        |  4 +--
 src/freedreno/ir3/tests/disasm.c     |  3 ++
 11 files changed, 107 insertions(+), 49 deletions(-)

diff --git a/src/freedreno/ir3/disasm-a3xx.c b/src/freedreno/ir3/disasm-a3xx.c
index 54ed027f55c..697219ce405 100644
--- a/src/freedreno/ir3/disasm-a3xx.c
+++ b/src/freedreno/ir3/disasm-a3xx.c
@@ -203,26 +203,54 @@ static void print_src(struct disasm_ctx *ctx, struct reginfo *info)
 
 static void print_instr_cat0(struct disasm_ctx *ctx, instr_t *instr)
 {
+	static const struct {
+		const char *suffix;
+		int nsrc;
+		bool idx;
+	} brinfo[7] = {
+		[BRANCH_PLAIN] = { "r",   1, false },
+		[BRANCH_OR]    = { "rao", 2, false },
+		[BRANCH_AND]   = { "raa", 2, false },
+		[BRANCH_CONST] = { "rac", 0, true  },
+		[BRANCH_ANY]   = { "any", 1, false },
+		[BRANCH_ALL]   = { "all", 1, false },
+		[BRANCH_X]     = { "rax", 0, false },
+	};
 	instr_cat0_t *cat0 = &instr->cat0;
 
-	switch (cat0->opc) {
+	switch (instr_opc(instr, ctx->gpu_id)) {
 	case OPC_KILL:
-	case OPC_IF:
-		fprintf(ctx->out, " %sp0.%c", cat0->inv ? "!" : "",
-				component[cat0->comp]);
+	case OPC_PREDT:
+	case OPC_PREDF:
+		fprintf(ctx->out, " %sp0.%c", cat0->inv0 ? "!" : "",
+				component[cat0->comp0]);
 		break;
-	case OPC_BR:
-		fprintf(ctx->out, " %sp0.%c, #%d", cat0->inv ? "!" : "",
-				component[cat0->comp], cat0->a3xx.immed);
+	case OPC_B:
+		fprintf(ctx->out, "%s", brinfo[cat0->brtype].suffix);
+		if (brinfo[cat0->brtype].idx) {
+			fprintf(ctx->out, ".%u", cat0->idx);
+		}
+		if (brinfo[cat0->brtype].nsrc >= 1) {
+			fprintf(ctx->out, " %sp0.%c,", cat0->inv0 ? "!" : "",
+					component[cat0->comp0]);
+		}
+		if (brinfo[cat0->brtype].nsrc >= 2) {
+			fprintf(ctx->out, " %sp0.%c,", cat0->inv1 ? "!" : "",
+					component[cat0->comp1]);
+		}
+		fprintf(ctx->out, " #%d", cat0->a3xx.immed);
 		break;
 	case OPC_JUMP:
 	case OPC_CALL:
+	case OPC_BKT:
+	case OPC_GETONE:
+	case OPC_SHPS:
 		fprintf(ctx->out, " #%d", cat0->a3xx.immed);
 		break;
 	}
 
-	if ((debug & PRINT_VERBOSE) && (cat0->dummy2|cat0->dummy3|cat0->dummy4))
-		fprintf(ctx->out, "\t{0: %x,%x,%x}", cat0->dummy2, cat0->dummy3, cat0->dummy4);
+	if ((debug & PRINT_VERBOSE) && (cat0->dummy3|cat0->dummy4))
+		fprintf(ctx->out, "\t{0: %x,%x}", cat0->dummy3, cat0->dummy4);
 }
 
 static void print_instr_cat1(struct disasm_ctx *ctx, instr_t *instr)
@@ -1065,7 +1093,7 @@ static const struct opc_info {
 #define OPC(cat, opc, name) [(opc)] = { (cat), (opc), #name, print_instr_cat##cat }
 	/* category 0: */
 	OPC(0, OPC_NOP,          nop),
-	OPC(0, OPC_BR,           br),
+	OPC(0, OPC_B,            b),
 	OPC(0, OPC_JUMP,         jump),
 	OPC(0, OPC_CALL,         call),
 	OPC(0, OPC_RET,          ret),
@@ -1076,9 +1104,18 @@ static const struct opc_info {
 	OPC(0, OPC_CHMASK,       chmask),
 	OPC(0, OPC_CHSH,         chsh),
 	OPC(0, OPC_FLOW_REV,     flow_rev),
-	OPC(0, OPC_IF,           if),
-	OPC(0, OPC_ELSE,         else),
-	OPC(0, OPC_ENDIF,        endif),
+	OPC(0, OPC_PREDT,        predt),
+	OPC(0, OPC_PREDF,        predf),
+	OPC(0, OPC_PREDE,        prede),
+	OPC(0, OPC_BKT,          bkt),
+	OPC(0, OPC_STKS,         stks),
+	OPC(0, OPC_STKR,         stkr),
+	OPC(0, OPC_XSET,         xset),
+	OPC(0, OPC_XCLR,         xclr),
+	OPC(0, OPC_GETONE,       getone),
+	OPC(0, OPC_DBG,          dbg),
+	OPC(0, OPC_SHPS,         shps),
+	OPC(0, OPC_SHPE,         shpe),
 
 	/* category 1: */
 	OPC(1, OPC_MOV, ),
@@ -1292,6 +1329,8 @@ static bool print_instr(struct disasm_ctx *ctx, uint32_t *dwords, int n)
 	}
 	if (instr->jmp_tgt)
 		fprintf(ctx->out, "(jp)");
+	if ((instr->opc_cat == 0) && instr->cat0.eq)
+		fprintf(ctx->out, "(eq)");
 	if (instr_sat(instr))
 		fprintf(ctx->out, "(sat)");
 	if (ctx->repeat)
diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h
index 565b296739f..23b21eb653d 100644
--- a/src/freedreno/ir3/instr-a3xx.h
+++ b/src/freedreno/ir3/instr-a3xx.h
@@ -39,7 +39,7 @@
 typedef enum {
 	/* category 0: */
 	OPC_NOP             = _OPC(0, 0),
-	OPC_BR              = _OPC(0, 1),
+	OPC_B               = _OPC(0, 1),
 	OPC_JUMP            = _OPC(0, 2),
 	OPC_CALL            = _OPC(0, 3),
 	OPC_RET             = _OPC(0, 4),
@@ -51,9 +51,19 @@ typedef enum {
 	OPC_CHSH            = _OPC(0, 10),
 	OPC_FLOW_REV        = _OPC(0, 11),
 
-	OPC_IF              = _OPC(0, 13),
-	OPC_ELSE            = _OPC(0, 14),
-	OPC_ENDIF           = _OPC(0, 15),
+	OPC_BKT             = _OPC(0, 16),
+	OPC_STKS            = _OPC(0, 17),
+	OPC_STKR            = _OPC(0, 18),
+	OPC_XSET            = _OPC(0, 19),
+	OPC_XCLR            = _OPC(0, 20),
+	OPC_GETONE          = _OPC(0, 21),
+	OPC_DBG             = _OPC(0, 22),
+	OPC_SHPS            = _OPC(0, 23),   /* shader prologue start */
+	OPC_SHPE            = _OPC(0, 24),   /* shader prologue end */
+
+	OPC_PREDT           = _OPC(0, 29),   /* predicated true */
+	OPC_PREDF           = _OPC(0, 30),   /* predicated false */
+	OPC_PREDE           = _OPC(0, 31),   /* predicated end */
 
 	/* category 1: */
 	OPC_MOV             = _OPC(1, 0),
@@ -311,6 +321,16 @@ static inline int reg_special(reg_t reg)
 	return (reg.num == REG_A0) || (reg.num == REG_P0);
 }
 
+typedef enum {
+	BRANCH_PLAIN = 0,   /* br */
+	BRANCH_OR    = 1,   /* brao */
+	BRANCH_AND   = 2,   /* braa */
+	BRANCH_CONST = 3,   /* brac */
+	BRANCH_ANY   = 4,   /* bany */
+	BRANCH_ALL   = 5,   /* ball */
+	BRANCH_X     = 6,   /* brax ??? */
+} brtype_t;
+
 typedef struct PACKED {
 	/* dword0: */
 	union PACKED {
@@ -328,13 +348,18 @@ typedef struct PACKED {
 	};
 
 	/* dword1: */
-	uint32_t dummy2   : 8;
+	uint32_t idx      : 5;  /* brac.N index */
+	uint32_t brtype   : 3;  /* branch type, see brtype_t */
 	uint32_t repeat   : 3;
 	uint32_t dummy3   : 1;
 	uint32_t ss       : 1;
-	uint32_t dummy4   : 7;
-	uint32_t inv      : 1;
-	uint32_t comp     : 2;
+	uint32_t inv1     : 1;
+	uint32_t comp1    : 2;
+	uint32_t eq       : 1;
+	uint32_t opc_hi   : 1;  /* at least one bit */
+	uint32_t dummy4   : 2;
+	uint32_t inv0     : 1;
+	uint32_t comp0    : 2;  /* component for first src */
 	uint32_t opc      : 4;
 	uint32_t jmp_tgt  : 1;
 	uint32_t sync     : 1;
@@ -963,7 +988,7 @@ static inline bool is_cat6_legacy(instr_t *instr, unsigned gpu_id)
 static inline uint32_t instr_opc(instr_t *instr, unsigned gpu_id)
 {
 	switch (instr->opc_cat) {
-	case 0:  return instr->cat0.opc;
+	case 0:  return instr->cat0.opc | instr->cat0.opc_hi << 4;
 	case 1:  return 0;
 	case 2:  return instr->cat2.opc;
 	case 3:  return instr->cat3.opc;
diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c
index cb7418bf2e0..8c30bf98298 100644
--- a/src/freedreno/ir3/ir3.c
+++ b/src/freedreno/ir3/ir3.c
@@ -141,23 +141,14 @@ static int emit_cat0(struct ir3_instruction *instr, void *ptr,
 	}
 	cat0->repeat   = instr->repeat;
 	cat0->ss       = !!(instr->flags & IR3_INSTR_SS);
-	cat0->inv      = instr->cat0.inv;
-	cat0->comp     = instr->cat0.comp;
+	cat0->inv0     = instr->cat0.inv;
+	cat0->comp0    = instr->cat0.comp;
 	cat0->opc      = instr->opc;
+	cat0->opc_hi   = instr->opc >= 16;
 	cat0->jmp_tgt  = !!(instr->flags & IR3_INSTR_JP);
 	cat0->sync     = !!(instr->flags & IR3_INSTR_SY);
 	cat0->opc_cat  = 0;
 
-	switch (instr->opc) {
-	case OPC_IF:
-	case OPC_ELSE:
-	case OPC_ENDIF:
-		cat0->dummy4 = 16;
-		break;
-	default:
-		break;
-	}
-
 	return 0;
 }
 
diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h
index 0f3bb54f316..4e7550f5e8d 100644
--- a/src/freedreno/ir3/ir3.h
+++ b/src/freedreno/ir3/ir3.h
@@ -1423,15 +1423,15 @@ ir3_##name(struct ir3_block *block,                                      \
 #define INSTR4(name)        __INSTR4(0, name, OPC_##name)
 
 /* cat0 instructions: */
-INSTR1(BR)
+INSTR1(B)
 INSTR0(JUMP)
 INSTR1(KILL)
 INSTR0(END)
 INSTR0(CHSH)
 INSTR0(CHMASK)
-INSTR1(IF)
-INSTR0(ELSE)
-INSTR0(ENDIF)
+INSTR1(PREDT)
+INSTR0(PREDF)
+INSTR0(PREDE)
 
 /* cat2 instructions, most 2 src but some 1 src: */
 INSTR2(ADD_F)
diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index bd65f91e780..b3d0556a03e 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -1536,7 +1536,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
 
 	case nir_intrinsic_end_patch_ir3:
 		assert(ctx->so->type == MESA_SHADER_TESS_CTRL);
-		struct ir3_instruction *end = ir3_ENDIF(b);
+		struct ir3_instruction *end = ir3_PREDE(b);
 		array_insert(b, b->keeps, end);
 
 		end->barrier_class = IR3_BARRIER_EVERYTHING;
@@ -1933,7 +1933,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
 		/* condition always goes in predicate register: */
 		cond->regs[0]->num = regid(REG_P0, 0);
 
-		kill = ir3_IF(b, cond, 0);
+		kill = ir3_PREDT(b, cond, 0);
 
 		kill->barrier_class = IR3_BARRIER_EVERYTHING;
 		kill->barrier_conflict = IR3_BARRIER_EVERYTHING;
diff --git a/src/freedreno/ir3/ir3_delay.c b/src/freedreno/ir3/ir3_delay.c
index 3fc4d911f14..15434fdedd1 100644
--- a/src/freedreno/ir3/ir3_delay.c
+++ b/src/freedreno/ir3/ir3_delay.c
@@ -123,7 +123,7 @@ count_instruction(struct ir3_instruction *n)
 	 * be eliminated later in resolve_jumps().. really should do that
 	 * earlier so we don't have this constraint.
 	 */
-	return is_alu(n) || (is_flow(n) && (n->opc != OPC_JUMP) && (n->opc != OPC_BR));
+	return is_alu(n) || (is_flow(n) && (n->opc != OPC_JUMP) && (n->opc != OPC_B));
 }
 
 /**
diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c
index d0b0dd83b46..2b1f3b94d8b 100644
--- a/src/freedreno/ir3/ir3_legalize.c
+++ b/src/freedreno/ir3/ir3_legalize.c
@@ -138,7 +138,7 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block)
 			regmask_init(&state->needs_sy);
 		}
 
-		if (last_n && (last_n->opc == OPC_IF)) {
+		if (last_n && (last_n->opc == OPC_PREDT)) {
 			n->flags |= IR3_INSTR_SS;
 			regmask_init(&state->needs_ss_war);
 			regmask_init(&state->needs_ss);
@@ -574,12 +574,12 @@ block_sched(struct ir3 *ir)
 			/* create "else" branch first (since "then" block should
 			 * frequently/always end up being a fall-thru):
 			 */
-			br = ir3_BR(block, block->condition, 0);
+			br = ir3_B(block, block->condition, 0);
 			br->cat0.inv = true;
 			br->cat0.target = block->successors[1];
 
 			/* "then" branch: */
-			br = ir3_BR(block, block->condition, 0);
+			br = ir3_B(block, block->condition, 0);
 			br->cat0.target = block->successors[0];
 
 		} else if (block->successors[0]) {
@@ -633,7 +633,7 @@ kill_sched(struct ir3 *ir, struct ir3_shader_variant *so)
 			if (instr->opc != OPC_KILL)
 				continue;
 
-			struct ir3_instruction *br = ir3_instr_create(block, OPC_BR);
+			struct ir3_instruction *br = ir3_instr_create(block, OPC_B);
 			br->regs[1] = instr->regs[1];
 			br->cat0.target =
 				list_last_entry(&ir->block_list, struct ir3_block, node);
diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y
index c9cede4b725..08779380b12 100644
--- a/src/freedreno/ir3/ir3_parser.y
+++ b/src/freedreno/ir3/ir3_parser.y
@@ -596,7 +596,7 @@ cat0_src:          '!' T_P0        { instr->cat0.inv = true; instr->cat0.comp =
 cat0_immed:        '#' integer     { instr->cat0.immed = $2; }
 
 cat0_instr:        T_OP_NOP        { new_instr(OPC_NOP); }
-|                  T_OP_BR         { new_instr(OPC_BR); }    cat0_src ',' cat0_immed
+|                  T_OP_BR         { new_instr(OPC_B); }    cat0_src ',' cat0_immed
 |                  T_OP_JUMP       { new_instr(OPC_JUMP); }  cat0_immed
 |                  T_OP_CALL       { new_instr(OPC_CALL); }  cat0_immed
 |                  T_OP_RET        { new_instr(OPC_RET); }
diff --git a/src/freedreno/ir3/ir3_postsched.c b/src/freedreno/ir3/ir3_postsched.c
index 521078a04c9..496c1d211b8 100644
--- a/src/freedreno/ir3/ir3_postsched.c
+++ b/src/freedreno/ir3/ir3_postsched.c
@@ -582,7 +582,7 @@ sched_block(struct ir3_postsched_ctx *ctx, struct ir3_block *block)
 	foreach_instr_safe (instr, &ctx->unscheduled_list) {
 		switch (instr->opc) {
 		case OPC_NOP:
-		case OPC_BR:
+		case OPC_B:
 		case OPC_JUMP:
 			list_delinit(&instr->node);
 			break;
diff --git a/src/freedreno/ir3/ir3_print.c b/src/freedreno/ir3/ir3_print.c
index 1b6908edefb..034bcd8248e 100644
--- a/src/freedreno/ir3/ir3_print.c
+++ b/src/freedreno/ir3/ir3_print.c
@@ -264,8 +264,8 @@ print_instr(struct ir3_instruction *instr, int lvl)
 
 	if (is_flow(instr) && instr->cat0.target) {
 		/* the predicate register src is implied: */
-		if (instr->opc == OPC_BR) {
-			printf(" %sp0.x", instr->cat0.inv ? "!" : "");
+		if (instr->opc == OPC_B) {
+			printf("r %sp0.x", instr->cat0.inv ? "!" : "");
 		}
 		printf(", target=block%u", block_id(instr->cat0.target));
 	}
diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c
index 81916c69e5a..ba6af205834 100644
--- a/src/freedreno/ir3/tests/disasm.c
+++ b/src/freedreno/ir3/tests/disasm.c
@@ -41,6 +41,9 @@ static const struct test {
 	INSTR_6XX(03000000_00000000, "end"),
 	INSTR_6XX(00800000_00000004, "br p0.x, #4"),
 	INSTR_6XX(00900000_00000003, "br !p0.x, #3"),
+	INSTR_6XX(03820000_00000015, "shps #21"), /* emit */
+	INSTR_6XX(04021000_00000000, "(ss)shpe"), /* cut */
+	INSTR_6XX(02820000_00000014, "getone #20"), /* kill p0.x */
 
 	/* cat1 */
 	INSTR_6XX(20244000_00000020, "mov.f32f32 r0.x, c8.x"),



More information about the mesa-commit mailing list