diff --git a/src/intel/compiler/brw_eu.h b/src/intel/compiler/brw_eu.h index fbcb9a03060..bc1f4d0cebe 100644 --- a/src/intel/compiler/brw_eu.h +++ b/src/intel/compiler/brw_eu.h @@ -1281,6 +1281,12 @@ void brw_CMP(struct brw_codegen *p, struct brw_reg src0, struct brw_reg src1); +void brw_CMPN(struct brw_codegen *p, + struct brw_reg dest, + unsigned conditional, + struct brw_reg src0, + struct brw_reg src1); + void brw_untyped_atomic(struct brw_codegen *p, struct brw_reg dst, diff --git a/src/intel/compiler/brw_eu_emit.c b/src/intel/compiler/brw_eu_emit.c index 939fd60d3d4..354331de569 100644 --- a/src/intel/compiler/brw_eu_emit.c +++ b/src/intel/compiler/brw_eu_emit.c @@ -1986,6 +1986,36 @@ void brw_CMP(struct brw_codegen *p, } } +void brw_CMPN(struct brw_codegen *p, + struct brw_reg dest, + unsigned conditional, + struct brw_reg src0, + struct brw_reg src1) +{ + const struct gen_device_info *devinfo = p->devinfo; + brw_inst *insn = next_insn(p, BRW_OPCODE_CMPN); + + brw_inst_set_cond_modifier(devinfo, insn, conditional); + brw_set_dest(p, insn, dest); + brw_set_src0(p, insn, src0); + brw_set_src1(p, insn, src1); + + /* Page 166 of the Ivy Bridge PRM Volume 4 part 3 (Execution Unit ISA) + * says: + * + * If the destination is the null register, the {Switch} instruction + * option must be used. + * + * Page 77 of the Haswell PRM Volume 2b contains the same text. + */ + if (devinfo->gen == 7) { + if (dest.file == BRW_ARCHITECTURE_REGISTER_FILE && + dest.nr == BRW_ARF_NULL) { + brw_inst_set_thread_control(devinfo, insn, BRW_THREAD_SWITCH); + } + } +} + /*********************************************************************** * Helpers for the various SEND message types: */ diff --git a/src/intel/compiler/brw_fs_generator.cpp b/src/intel/compiler/brw_fs_generator.cpp index a0c47f98cd8..d74839b9f54 100644 --- a/src/intel/compiler/brw_fs_generator.cpp +++ b/src/intel/compiler/brw_fs_generator.cpp @@ -2128,6 +2128,18 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width, } brw_CMP(p, dst, inst->conditional_mod, src[0], src[1]); break; + case BRW_OPCODE_CMPN: + if (inst->exec_size >= 16 && devinfo->gen == 7 && !devinfo->is_haswell && + dst.file == BRW_ARCHITECTURE_REGISTER_FILE) { + /* For unknown reasons the WaCMPInstFlagDepClearedEarly workaround + * implemented in the compiler is not sufficient. Overriding the + * type when the destination is the null register is necessary but + * not sufficient by itself. + */ + dst.type = BRW_REGISTER_TYPE_D; + } + brw_CMPN(p, dst, inst->conditional_mod, src[0], src[1]); + break; case BRW_OPCODE_SEL: brw_SEL(p, dst, src[0], src[1]); break; diff --git a/src/intel/compiler/brw_vec4_generator.cpp b/src/intel/compiler/brw_vec4_generator.cpp index 38c841fbaf2..a2e84397921 100644 --- a/src/intel/compiler/brw_vec4_generator.cpp +++ b/src/intel/compiler/brw_vec4_generator.cpp @@ -1594,6 +1594,9 @@ generate_code(struct brw_codegen *p, case BRW_OPCODE_CMP: brw_CMP(p, dst, inst->conditional_mod, src[0], src[1]); break; + case BRW_OPCODE_CMPN: + brw_CMPN(p, dst, inst->conditional_mod, src[0], src[1]); + break; case BRW_OPCODE_SEL: brw_SEL(p, dst, src[0], src[1]); break;