#if GEN_GEN >= 8 || GEN_IS_HASWELL
+/**
+ * Perform a predicated store (assuming the condition is already loaded
+ * in the MI_PREDICATE_RESULT register) of the value in src to the memory
+ * location specified by dst. Non-memory destinations are not supported.
+ *
+ * This function consumes one reference for each of src and dst.
+ */
+static inline void
+gen_mi_store_if(struct gen_mi_builder *b,
+ struct gen_mi_value dst,
+ struct gen_mi_value src)
+{
+ assert(!dst.invert && !src.invert);
+
+ gen_mi_builder_flush_math(b);
+
+ /* We can only predicate MI_STORE_REGISTER_MEM, so restrict the
+ * destination to be memory, and resolve the source to a temporary
+ * register if it isn't in one already.
+ */
+ assert(dst.type == GEN_MI_VALUE_TYPE_MEM64 ||
+ dst.type == GEN_MI_VALUE_TYPE_MEM32);
+
+ if (src.type != GEN_MI_VALUE_TYPE_REG32 ||
+ src.type != GEN_MI_VALUE_TYPE_REG64) {
+ struct gen_mi_value tmp = gen_mi_new_gpr(b);
+ _gen_mi_copy_no_unref(b, tmp, src);
+ src = tmp;
+ }
+
+ if (dst.type == GEN_MI_VALUE_TYPE_MEM64) {
+ gen_mi_builder_emit(b, GENX(MI_STORE_REGISTER_MEM), srm) {
+ srm.RegisterAddress = src.reg;
+ srm.MemoryAddress = dst.addr;
+ srm.PredicateEnable = true;
+ }
+ gen_mi_builder_emit(b, GENX(MI_STORE_REGISTER_MEM), srm) {
+ srm.RegisterAddress = src.reg + 4;
+ srm.MemoryAddress = __gen_address_offset(dst.addr, 4);
+ srm.PredicateEnable = true;
+ }
+ } else {
+ gen_mi_builder_emit(b, GENX(MI_STORE_REGISTER_MEM), srm) {
+ srm.RegisterAddress = src.reg;
+ srm.MemoryAddress = dst.addr;
+ srm.PredicateEnable = true;
+ }
+ }
+
+ gen_mi_value_unref(b, src);
+ gen_mi_value_unref(b, dst);
+}
+
static inline void
_gen_mi_builder_push_math(struct gen_mi_builder *b,
const uint32_t *dwords,