dst->u[3] = src0->u[3] * src1->u[3];
}
+static void
+micro_imul_hi(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src0,
+ const union tgsi_exec_channel *src1)
+{
+#define I64M(x, y) ((((int64_t)x) * ((int64_t)y)) >> 32)
+ dst->i[0] = I64M(src0->i[0], src1->i[0]);
+ dst->i[1] = I64M(src0->i[1], src1->i[1]);
+ dst->i[2] = I64M(src0->i[2], src1->i[2]);
+ dst->i[3] = I64M(src0->i[3], src1->i[3]);
+#undef I64M
+}
+
+static void
+micro_umul_hi(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src0,
+ const union tgsi_exec_channel *src1)
+{
+#define U64M(x, y) ((((uint64_t)x) * ((uint64_t)y)) >> 32)
+ dst->u[0] = U64M(src0->u[0], src1->u[0]);
+ dst->u[1] = U64M(src0->u[1], src1->u[1]);
+ dst->u[2] = U64M(src0->u[2], src1->u[2]);
+ dst->u[3] = U64M(src0->u[3], src1->u[3]);
+#undef U64M
+}
+
static void
micro_useq(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src0,
exec_vector_binary(mach, inst, micro_umul, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
break;
+ case TGSI_OPCODE_IMUL_HI:
+ exec_vector_binary(mach, inst, micro_imul_hi, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+ break;
+
+ case TGSI_OPCODE_UMUL_HI:
+ exec_vector_binary(mach, inst, micro_umul_hi, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
case TGSI_OPCODE_USEQ:
exec_vector_binary(mach, inst, micro_useq, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
break;
{ 1, 3, 1, 0, 0, 0, OTHR, "TEX2", TGSI_OPCODE_TEX2 },
{ 1, 3, 1, 0, 0, 0, OTHR, "TXB2", TGSI_OPCODE_TXB2 },
{ 1, 3, 1, 0, 0, 0, OTHR, "TXL2", TGSI_OPCODE_TXL2 },
+ { 1, 2, 0, 0, 0, 0, COMP, "IMUL_HI", TGSI_OPCODE_IMUL_HI },
+ { 1, 2, 0, 0, 0, 0, COMP, "UMUL_HI", TGSI_OPCODE_UMUL_HI },
};
const struct tgsi_opcode_info *
case TGSI_OPCODE_USLT:
case TGSI_OPCODE_USNE:
case TGSI_OPCODE_SVIEWINFO:
+ case TGSI_OPCODE_UMUL_HI:
return TGSI_TYPE_UNSIGNED;
case TGSI_OPCODE_ARL:
case TGSI_OPCODE_ARR:
case TGSI_OPCODE_UARL:
case TGSI_OPCODE_IABS:
case TGSI_OPCODE_ISSG:
+ case TGSI_OPCODE_IMUL_HI:
return TGSI_TYPE_SIGNED;
default:
return TGSI_TYPE_FLOAT;
case TGSI_OPCODE_CASE:
case TGSI_OPCODE_SAMPLE_I:
case TGSI_OPCODE_SAMPLE_I_MS:
+ case TGSI_OPCODE_UMUL_HI:
return TGSI_TYPE_UNSIGNED;
+ case TGSI_OPCODE_IMUL_HI:
case TGSI_OPCODE_I2F:
return TGSI_TYPE_SIGNED;
case TGSI_OPCODE_ARL:
OP13(UCMP)
+OP12(IMUL_HI)
+OP12(UMUL_HI)
+
#undef OP00
#undef OP01
#undef OP10
case TGSI_OPCODE_USHR:
case TGSI_OPCODE_USLT:
case TGSI_OPCODE_USNE:
+ case TGSI_OPCODE_IMUL_HI:
+ case TGSI_OPCODE_UMUL_HI:
/* Channel-wise operations */
read_mask = write_mask;
break;
dst.w = src0.w \times src1.w
+.. opcode:: IMUL_HI - Signed Integer Multiply High Bits
+
+ The high 32bits of the multiplication of 2 signed integers are returned.
+
+.. math::
+
+ dst.x = (src0.x \times src1.x) >> 32
+
+ dst.y = (src0.y \times src1.y) >> 32
+
+ dst.z = (src0.z \times src1.z) >> 32
+
+ dst.w = (src0.w \times src1.w) >> 32
+
+
+.. opcode:: UMUL_HI - Unsigned Integer Multiply High Bits
+
+ The high 32bits of the multiplication of 2 unsigned integers are returned.
+
+.. math::
+
+ dst.x = (src0.x \times src1.x) >> 32
+
+ dst.y = (src0.y \times src1.y) >> 32
+
+ dst.z = (src0.z \times src1.z) >> 32
+
+ dst.w = (src0.w \times src1.w) >> 32
+
+
.. opcode:: IDIV - Signed Integer Division
TBD: behavior for division by zero.
#define TGSI_OPCODE_TXB2 178
#define TGSI_OPCODE_TXL2 179
-#define TGSI_OPCODE_LAST 180
+#define TGSI_OPCODE_IMUL_HI 180
+#define TGSI_OPCODE_UMUL_HI 181
+
+#define TGSI_OPCODE_LAST 182
#define TGSI_SAT_NONE 0 /* do not saturate */
#define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */
--- /dev/null
+VERT
+DCL IN[0]
+DCL IN[1]
+DCL OUT[0], POSITION
+DCL OUT[1], COLOR
+DCL TEMP[0]
+DCL TEMP[1]
+IMM[0] INT32 {-2147483648, 2, 0, -1}
+MOV OUT[0], IN[0]
+IMUL_HI TEMP[0], IMM[0].xzzx, IMM[0].yzzy
+UMUL TEMP[0], TEMP[0], IMM[0].wwww
+I2F OUT[1], TEMP[0]
+END
--- /dev/null
+VERT
+DCL IN[0]
+DCL IN[1]
+DCL OUT[0], POSITION
+DCL OUT[1], COLOR
+DCL TEMP[0]
+IMM[0] INT32 {4, 1073741824, 0, 1}
+MOV OUT[0], IN[0]
+UMUL_HI TEMP[0], IMM[0].xzzx, IMM[0].yzzy
+I2F OUT[1], TEMP[0]
+END