From 05586f9bc1c5649298675361556936e684ad68eb Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Sat, 27 Sep 2014 17:34:51 -0700 Subject: [PATCH] i965/fs: Set MUL source type to W/UW in 64-bit mul macro on Gen8. Reviewed-by: Ian Romanick --- src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 23 +++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index 89ac7e28828..6b4104556ba 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -654,8 +654,29 @@ fs_visitor::visit(ir_expression *ir) struct brw_reg acc = retype(brw_acc_reg(dispatch_width), this->result.type); - emit(MUL(acc, op[0], op[1])); + fs_inst *mul = emit(MUL(acc, op[0], op[1])); emit(MACH(this->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 (brw->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; + } else { + mul->src[1].type = BRW_REGISTER_TYPE_UW; + } + } + break; } case ir_binop_div: -- 2.30.2