i965/fs: Fix 32-bit integer multiplication.
The MUL opcode does a 16bit * 32bit multiply, and we need to do the MACH to get the top 16bit * 32bit added in. Fixes fs-op-mult-int-*, fs-op-mult-ivec* Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -630,6 +630,11 @@ fs_visitor::generate_code()
|
||||
case BRW_OPCODE_MUL:
|
||||
brw_MUL(p, dst, src[0], src[1]);
|
||||
break;
|
||||
case BRW_OPCODE_MACH:
|
||||
brw_set_acc_write_control(p, 1);
|
||||
brw_MACH(p, dst, src[0], src[1]);
|
||||
brw_set_acc_write_control(p, 0);
|
||||
break;
|
||||
|
||||
case BRW_OPCODE_FRC:
|
||||
brw_FRC(p, dst, src[0]);
|
||||
|
@@ -287,7 +287,23 @@ fs_visitor::visit(ir_expression *ir)
|
||||
break;
|
||||
|
||||
case ir_binop_mul:
|
||||
emit(BRW_OPCODE_MUL, this->result, op[0], op[1]);
|
||||
if (ir->type->is_integer()) {
|
||||
/* For integer multiplication, the MUL uses the low 16 bits
|
||||
* of one of the operands (src0 on gen6, src1 on gen7). The
|
||||
* MACH accumulates in the contribution of the upper 16 bits
|
||||
* of that operand.
|
||||
*
|
||||
* FINISHME: Emit just the MUL if we know an operand is small
|
||||
* enough.
|
||||
*/
|
||||
struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_D);
|
||||
|
||||
emit(BRW_OPCODE_MUL, acc, op[0], op[1]);
|
||||
emit(BRW_OPCODE_MACH, reg_null_d, op[0], op[1]);
|
||||
emit(BRW_OPCODE_MOV, this->result, fs_reg(acc));
|
||||
} else {
|
||||
emit(BRW_OPCODE_MUL, this->result, op[0], op[1]);
|
||||
}
|
||||
break;
|
||||
case ir_binop_div:
|
||||
assert(!"not reached: should be handled by ir_div_to_mul_rcp");
|
||||
|
Reference in New Issue
Block a user