summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2015-04-24 11:28:05 -0700
committerMatt Turner <[email protected]>2015-04-27 14:44:32 -0700
commit0c06d019bcf626b289ae94ca791dc25c216c1e5c (patch)
treed6889501fb280f90280f88144a66616132ce7abc
parentecf428aa5945c5e1941b6bf496a381c7a09cdda2 (diff)
i965/fs: Fix code emission for imul_high in NIR.
Copy over from brw_fs_visitor.cpp. Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_nir.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 95647642c8a..523e56db627 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -827,8 +827,30 @@ fs_visitor::nir_emit_alu(nir_alu_instr *instr)
struct brw_reg acc = retype(brw_acc_reg(dispatch_width), result.type);
- emit(MUL(acc, op[0], op[1]));
+ fs_inst *mul = emit(MUL(acc, op[0], op[1]));
emit(MACH(result, op[0], op[1]));
+
+ /* Until Gen8, integer multiplies read 32-bits from one source, and
+ * 16-bits from the other, and relying on the MACH instruction to
+ * generate the high bits of the result.
+ *
+ * On Gen8, the multiply instruction does a full 32x32-bit multiply,
+ * but in order to do a 64x64-bit multiply we have to simulate the
+ * previous behavior and then use a MACH instruction.
+ *
+ * FINISHME: Don't use source modifiers on src1.
+ */
+ if (devinfo->gen >= 8) {
+ assert(mul->src[1].type == BRW_REGISTER_TYPE_D ||
+ mul->src[1].type == BRW_REGISTER_TYPE_UD);
+ if (mul->src[1].type == BRW_REGISTER_TYPE_D) {
+ mul->src[1].type = BRW_REGISTER_TYPE_W;
+ mul->src[1].stride = 2;
+ } else {
+ mul->src[1].type = BRW_REGISTER_TYPE_UW;
+ mul->src[1].stride = 2;
+ }
+ }
break;
}