Mesa (master): freedreno/ir3: add MOD support

Rob Clark robclark at kemper.freedesktop.org
Fri Oct 3 03:31:24 UTC 2014


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

Author: Ilia Mirkin <imirkin at alum.mit.edu>
Date:   Wed Oct  1 01:03:31 2014 -0400

freedreno/ir3: add MOD support

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>

---

 src/gallium/drivers/freedreno/ir3/ir3_compiler.c |   20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
index b5fbe21..4250401 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
@@ -1995,10 +1995,10 @@ trans_umul(const struct instr_translater *t,
 }
 
 /*
- * IDIV / UDIV / UMOD
+ * IDIV / UDIV / MOD / UMOD
  *
  * See NV50LegalizeSSA::handleDIV for the origin of this implementation. For
- * UMOD, it becomes a - UDIV(a, modulus) * modulus.
+ * MOD/UMOD, it becomes a - [IU]DIV(a, modulus) * modulus.
  */
 static void
 trans_idiv(const struct instr_translater *t,
@@ -2014,9 +2014,12 @@ trans_idiv(const struct instr_translater *t,
 	struct tgsi_src_register *af_src, *bf_src, *q_src, *r_src, *a_src, *b_src;
 
 	struct tgsi_src_register negative_2, thirty_one;
+	type_t src_type;
 
-	type_t src_type = t->tgsi_opc == TGSI_OPCODE_IDIV ?
-		get_stype(ctx) : get_utype(ctx);
+	if (t->tgsi_opc == TGSI_OPCODE_IDIV || t->tgsi_opc == TGSI_OPCODE_MOD)
+		src_type = get_stype(ctx);
+	else
+		src_type = get_utype(ctx);
 
 	af_src = get_internal_temp(ctx, &af_dst);
 	bf_src = get_internal_temp(ctx, &bf_dst);
@@ -2028,7 +2031,7 @@ trans_idiv(const struct instr_translater *t,
 	get_immediate(ctx, &negative_2, -2);
 	get_immediate(ctx, &thirty_one, 31);
 
-	if (t->tgsi_opc == TGSI_OPCODE_UMOD)
+	if (t->tgsi_opc == TGSI_OPCODE_MOD || t->tgsi_opc == TGSI_OPCODE_UMOD)
 		premod_dst = &q_dst;
 
 	/* cov.[us]32f32 af, numerator */
@@ -2044,7 +2047,7 @@ trans_idiv(const struct instr_translater *t,
 	vectorize(ctx, instr, &bf_dst, 1, b, 0);
 
 	/* Get the absolute values for IDIV */
-	if (t->tgsi_opc == TGSI_OPCODE_IDIV) {
+	if (type_sint(src_type)) {
 		/* absneg.f af, (abs)af */
 		instr = instr_create(ctx, 2, OPC_ABSNEG_F);
 		vectorize(ctx, instr, &af_dst, 1, af_src, IR3_REG_ABS);
@@ -2151,7 +2154,7 @@ trans_idiv(const struct instr_translater *t,
 	instr->cat2.condition = IR3_COND_GE;
 	vectorize(ctx, instr, &r_dst, 2, r_src, 0, b_src, 0);
 
-	if (t->tgsi_opc != TGSI_OPCODE_IDIV) {
+	if (type_uint(src_type)) {
 		/* add.u dst, q, r */
 		instr = instr_create(ctx, 2, OPC_ADD_U);
 		vectorize(ctx, instr, premod_dst, 2, q_src, 0, r_src, 0);
@@ -2181,7 +2184,7 @@ trans_idiv(const struct instr_translater *t,
 		vectorize(ctx, instr, premod_dst, 3, b_src, 0, r_src, 0, q_src, 0);
 	}
 
-	if (t->tgsi_opc == TGSI_OPCODE_UMOD) {
+	if (t->tgsi_opc == TGSI_OPCODE_MOD || t->tgsi_opc == TGSI_OPCODE_UMOD) {
 		/* The division result will have ended up in q. */
 
 		/* mull.u r, q, b */
@@ -2365,6 +2368,7 @@ static const struct instr_translater translaters[TGSI_OPCODE_LAST] = {
 	INSTR(UMUL,         trans_umul),
 	INSTR(UDIV,         trans_idiv),
 	INSTR(IDIV,         trans_idiv),
+	INSTR(MOD,          trans_idiv),
 	INSTR(UMOD,         trans_idiv),
 	INSTR(SHL,          instr_cat2, .opc = OPC_SHL_B),
 	INSTR(USHR,         instr_cat2, .opc = OPC_SHR_B),




More information about the mesa-commit mailing list