diff options
Diffstat (limited to 'src/intel/common/gen_mi_builder.h')
-rw-r--r-- | src/intel/common/gen_mi_builder.h | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/intel/common/gen_mi_builder.h b/src/intel/common/gen_mi_builder.h index 61d44eda5ae..3590acb7b62 100644 --- a/src/intel/common/gen_mi_builder.h +++ b/src/intel/common/gen_mi_builder.h @@ -503,6 +503,59 @@ gen_mi_memcpy(struct gen_mi_builder *b, __gen_address_type dst, #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, |