intel/mi: Add a new gen_mi_store_if() helper.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 1 Apr 2019 23:33:08 +0000 (16:33 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 25 Jul 2019 18:42:55 +0000 (18:42 +0000)
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 <caio.oliveira@intel.com>
src/intel/common/gen_mi_builder.h

index 61d44eda5ae73c106073801ec7e7ede64df0c5ed..3590acb7b626a21c018bfdb6f8c12cc0d2af50ff 100644 (file)
@@ -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,