From 0c06d019bcf626b289ae94ca791dc25c216c1e5c Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Fri, 24 Apr 2015 11:28:05 -0700 Subject: [PATCH] i965/fs: Fix code emission for imul_high in NIR. Copy over from brw_fs_visitor.cpp. Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index 9564764..523e56d 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; } -- 2.7.4