diff --git a/src/intel/compiler/brw/brw_eu_emit.c b/src/intel/compiler/brw/brw_eu_emit.c index c730f61471c..fe394c31706 100644 --- a/src/intel/compiler/brw/brw_eu_emit.c +++ b/src/intel/compiler/brw/brw_eu_emit.c @@ -918,6 +918,7 @@ ALU2(ADDC) ALU2(SUBB) ALU3(ADD3) ALU1(MOV) +ALU2(MUL) brw_eu_inst * brw_ADD(struct brw_codegen *p, struct brw_reg dest, @@ -962,38 +963,6 @@ brw_AVG(struct brw_codegen *p, struct brw_reg dest, return brw_alu2(p, BRW_OPCODE_AVG, dest, src0, src1); } -brw_eu_inst * -brw_MUL(struct brw_codegen *p, struct brw_reg dest, - struct brw_reg src0, struct brw_reg src1) -{ - /* 6.32.38: mul */ - if (src0.type == BRW_TYPE_D || - src0.type == BRW_TYPE_UD || - src1.type == BRW_TYPE_D || - src1.type == BRW_TYPE_UD) { - assert(dest.type != BRW_TYPE_F); - } - - if (src0.type == BRW_TYPE_F || - (src0.file == IMM && - src0.type == BRW_TYPE_VF)) { - assert(src1.type != BRW_TYPE_UD); - assert(src1.type != BRW_TYPE_D); - } - - if (src1.type == BRW_TYPE_F || - (src1.file == IMM && - src1.type == BRW_TYPE_VF)) { - assert(src0.type != BRW_TYPE_UD); - assert(src0.type != BRW_TYPE_D); - } - - assert(!brw_reg_is_arf(src0, BRW_ARF_ACCUMULATOR)); - assert(!brw_reg_is_arf(src1, BRW_ARF_ACCUMULATOR)); - - return brw_alu2(p, BRW_OPCODE_MUL, dest, src0, src1); -} - brw_eu_inst * brw_LINE(struct brw_codegen *p, struct brw_reg dest, struct brw_reg src0, struct brw_reg src1) diff --git a/src/intel/compiler/brw/brw_eu_validate.c b/src/intel/compiler/brw/brw_eu_validate.c index 3cc3cbebabb..885b185a2b9 100644 --- a/src/intel/compiler/brw/brw_eu_validate.c +++ b/src/intel/compiler/brw/brw_eu_validate.c @@ -1846,6 +1846,15 @@ instruction_restrictions(const struct brw_isa_info *isa, const enum brw_reg_type src1_type = inst->src[1].type; const enum brw_reg_type dst_type = inst->dst.type; + ERROR_IF(brw_type_is_float(dst_type) && + (brw_type_is_int(src0_type) || + brw_type_is_int(src1_type)), + "MUL can't mix floats and integer sources."); + + ERROR_IF((brw_type_is_int(src0_type) && src0_is_acc(inst)) || + (brw_type_is_int(src1_type) && src1_is_acc(inst)), + "In MUL, Integer source operands cannot be accumulators."); + /* Page 966 (page 982 of the PDF) of Broadwell PRM volume 2a says: * * When multiplying a DW and any lower precision integer, the DW diff --git a/src/intel/compiler/brw/test_eu_validate.cpp b/src/intel/compiler/brw/test_eu_validate.cpp index 547137d3e0c..2f2866ae896 100644 --- a/src/intel/compiler/brw/test_eu_validate.cpp +++ b/src/intel/compiler/brw/test_eu_validate.cpp @@ -3932,3 +3932,40 @@ TEST_P(validation_test, srnd_type_and_immediate_restrictions) EXPECT_FALSE(validate(p)); clear_instructions(p); } + +TEST_P(validation_test, mul_dont_mix_floats_and_ints) +{ + brw_reg a = brw_ud8_grf(10, 0); + brw_reg b = brw_ud8_grf(20, 0); + brw_reg c = brw_ud8_grf(30, 0); + + brw_MUL(p, retype(a, BRW_TYPE_F), + retype(b, BRW_TYPE_UD), + retype(c, BRW_TYPE_UD)); + EXPECT_FALSE(validate(p)); + clear_instructions(p); + + brw_MUL(p, retype(a, BRW_TYPE_F), + retype(b, BRW_TYPE_F), + retype(c, BRW_TYPE_UD)); + EXPECT_FALSE(validate(p)); + clear_instructions(p); + + brw_MUL(p, retype(a, BRW_TYPE_F), + retype(b, BRW_TYPE_UD), + brw_imm_vf(0)); + EXPECT_FALSE(validate(p)); + clear_instructions(p); +} + +TEST_P(validation_test, mul_dont_accept_int_accumulator_src) +{ + brw_reg a = brw_ud8_grf(10, 0); + brw_reg c = brw_ud8_grf(30, 0); + + brw_MUL(p, retype(a, BRW_TYPE_UD), + retype(acc0, BRW_TYPE_UD), + retype(c, BRW_TYPE_UD)); + EXPECT_FALSE(validate(p)); + clear_instructions(p); +}