Mesa (master): nv50: quick fix for insn src negation

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Mon Oct 19 16:25:44 UTC 2009


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

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Tue Oct 13 15:09:13 2009 +0200

nv50: quick fix for insn src negation

We only have a per nv50_reg negation flag, if an
nv50_reg is used more than once in a TGSI op with
different sign modes, we'd generate wrong code.

We probably can't do much better without more
invasive changes.

---

 src/gallium/drivers/nv50/nv50_program.c |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 89e0ac8..1bd6f71 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -1293,9 +1293,12 @@ convert_to_long(struct nv50_pc *pc, struct nv50_program_exec *e)
 	e->inst[1] |= q;
 }
 
+/* Some operations support an optional negation flag. */
 static boolean
 negate_supported(const struct tgsi_full_instruction *insn, int i)
 {
+	int s;
+
 	switch (insn->Instruction.Opcode) {
 	case TGSI_OPCODE_DDY:
 	case TGSI_OPCODE_DP3:
@@ -1305,12 +1308,29 @@ negate_supported(const struct tgsi_full_instruction *insn, int i)
 	case TGSI_OPCODE_ADD:
 	case TGSI_OPCODE_SUB:
 	case TGSI_OPCODE_MAD:
-		return TRUE;
+		break;
 	case TGSI_OPCODE_POW:
-		return (i == 1) ? TRUE : FALSE;
+		if (i == 1)
+			break;
+		return FALSE;
 	default:
 		return FALSE;
 	}
+
+	/* Watch out for possible multiple uses of an nv50_reg, we
+	 * can't use nv50_reg::neg in these cases.
+	 */
+	for (s = 0; s < insn->Instruction.NumSrcRegs; ++s) {
+		if (s == i)
+			continue;
+		if ((insn->FullSrcRegisters[s].SrcRegister.Index ==
+		     insn->FullSrcRegisters[i].SrcRegister.Index) &&
+		    (insn->FullSrcRegisters[s].SrcRegister.File ==
+		     insn->FullSrcRegisters[i].SrcRegister.File))
+			return FALSE;
+	}
+
+	return TRUE;
 }
 
 /* Return a read mask for source registers deduced from opcode & write mask. */
@@ -1956,6 +1976,7 @@ nv50_program_tx_insn(struct nv50_pc *pc,
 		for (c = 0; c < 4; c++) {
 			if (!src[i][c])
 				continue;
+			src[i][c]->neg = 0;
 			if (src[i][c]->index == -1 && src[i][c]->type == P_IMMD)
 				FREE(src[i][c]);
 		}




More information about the mesa-commit mailing list