From: Kenneth Graunke Date: Mon, 1 Apr 2019 23:33:08 +0000 (-0700) Subject: intel/mi: Add a new gen_mi_store_if() helper. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=74063ee61aadd1371a9b395ffd5d5d308ee2d4ee;p=mesa.git intel/mi: Add a new gen_mi_store_if() helper. This performs predicated MI_STORE_REGISTER_MEM commands, assuming that the condition is already loaded into MI_PREDICATE_DATA. Reviewed-by: Caio Marcelo de Oliveira Filho --- 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,