[Mesa-dev] [PATCH 2/2] r600g: replace raw opcodes with names in the is_alu_trans/vector

Vadim Girlin vadimgirlin at gmail.com
Tue Jan 24 03:32:52 PST 2012


Signed-off-by: Vadim Girlin <vadimgirlin at gmail.com>
---
 src/gallium/drivers/r600/r600_asm.c |   92 ++++++++++++++++++++++++++++++-----
 1 files changed, 80 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index a888704..8fce5a1 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -468,44 +468,112 @@ static int is_alu_mova_inst(struct r600_bytecode *bc, struct r600_bytecode_alu *
 	}
 }
 
-#define RANGE(a, b) ((alu->inst>=(a))&&(alu->inst<=(b)))
+static int is_opcode_in_range(unsigned opcode, unsigned min, unsigned max)
+{
+	return min <= opcode && opcode <= max;
+}
 
-/* alu instructions that can only execute on the vector unit */
+/* ALU instructions that can only execute on the vector unit:
+ *
+ * opcode ranges:
+ * R6xx/R7xx:
+ *   op3 : [0x08 - 0x0B]
+ *   op2 : 0x07, [0x15 - 0x18], [0x1B - 0x1D], [0x50 - 0x53], [0x7A - 0x7E]
+ *
+ * EVERGREEN:
+ *   op3: [0x04 - 0x11]
+ *   op2: [0xA0 - 0xE2]
+ */
 static int is_alu_vec_unit_inst(struct r600_bytecode *bc, struct r600_bytecode_alu *alu)
 {
 	switch (bc->chip_class) {
 	case R600:
 	case R700:
-		return alu->is_op3 ? RANGE(0x08, 0x0B) : RANGE(0x07, 0x07) |
-				RANGE(0x15, 0x18) | RANGE(0x1B, 0x1D) |
-				RANGE(0x50, 0x53) | RANGE(0x7A, 0x7E);
+		if (alu->is_op3)
+			return is_opcode_in_range(alu->inst,
+					V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_64,
+					V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_64_D2);
+		else
+			return (alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FREXP_64) ||
+					is_opcode_in_range(alu->inst,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT) ||
+					is_opcode_in_range(alu->inst,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL_64,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT32_TO_FLT64) ||
+					is_opcode_in_range(alu->inst,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4) ||
+					is_opcode_in_range(alu->inst,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LDEXP_64,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_64);
+
 	case EVERGREEN:
-		return alu->is_op3 ? RANGE(0x04, 0x11) : RANGE(0xA0, 0xE2);
+		if (alu->is_op3)
+			return is_opcode_in_range(alu->inst,
+					EG_V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_BFE_UINT,
+					EG_V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_LDS_IDX_OP);
+		else
+			return is_opcode_in_range(alu->inst,
+					EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_BFM_INT,
+					EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INTERP_LOAD_P20);
 	case CAYMAN:
+	default:
 		assert(0);
 		return 0;
 	}
 }
 
-/* alu instructions that can only execute on the trans unit */
+/* ALU instructions that can only execute on the trans unit:
+ *
+ * opcode ranges:
+ * R600:
+ *   op3: 0x0C
+ *   op2: [0x60 - 0x79]
+ *
+ * R700:
+ *   op3: 0x0C
+ *   op2: [0x60 - 0x6F], [0x73 - 0x79]
+ *
+ * EVERGREEN:
+ *   op3: 0x1F
+ *   op2: [0x81 - 0x9C]
+ */
 static int is_alu_trans_unit_inst(struct r600_bytecode *bc, struct r600_bytecode_alu *alu)
 {
 
 	switch (bc->chip_class) {
 	case R600:
-		return alu->is_op3 ? RANGE(0x0C, 0x0C) : RANGE(0x60, 0x79);
+		if (alu->is_op3)
+			return alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT;
+		else
+			return is_opcode_in_range(alu->inst,
+					V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_GPR_INT,
+					V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_UINT);
 	case R700:
-		return alu->is_op3 ? RANGE(0x0C, 0x0C) : RANGE(0x60, 0x6F) | RANGE(0x73, 0x79);
+		if (alu->is_op3)
+			return alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT;
+		else
+			return is_opcode_in_range(alu->inst,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_GPR_INT,
+						V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS) ||
+					is_opcode_in_range(alu->inst,
+							V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT,
+							V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_UINT);
 	case EVERGREEN:
-		return alu->is_op3 ? RANGE(0x1F, 0x1F) : RANGE(0x81, 0x9C);
+		if (alu->is_op3)
+			return alu->inst == EG_V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT;
+		else
+			return is_opcode_in_range(alu->inst,
+					EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE,
+					EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT);
 	case CAYMAN:
+	default:
 		assert(0);
 		return 0;
 	}
 }
 
-#undef RANGE
-
 /* alu instructions that can execute on any unit */
 static int is_alu_any_unit_inst(struct r600_bytecode *bc, struct r600_bytecode_alu *alu)
 {
-- 
1.7.7.6



More information about the mesa-dev mailing list