etnaviv: move functions that generate asm to own file
authorChristian Gmeiner <christian.gmeiner@gmail.com>
Mon, 29 Jun 2020 15:14:20 +0000 (17:14 +0200)
committerMarge Bot <eric+marge@anholt.net>
Thu, 2 Jul 2020 17:04:46 +0000 (17:04 +0000)
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Acked-by: Jonathan Marek <jonathan@marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5690>

src/gallium/drivers/etnaviv/Makefile.sources
src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c
src/gallium/drivers/etnaviv/etnaviv_compiler_nir.h
src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.c [new file with mode: 0644]
src/gallium/drivers/etnaviv/meson.build

index ea628304e62db15969a388b1f2bdf38566d1fb20..644ba60af1e57013f67c45cc85580df6c4bf7d3b 100644 (file)
@@ -18,6 +18,7 @@ C_SOURCES :=  \
        etnaviv_clear_blit.h \
        etnaviv_compiler.h \
        etnaviv_compiler_nir.c \
+       etnaviv_compiler_nir_emit.c \
        etnaviv_compiler_nir_emit.h \
        etnaviv_compiler_nir_liveness.c \
        etnaviv_compiler_tgsi.c \
index 0eace1a665f3e5e49d3f56c7799eeeaa8dc34d36..e5224b813ececf703426592aa45a5813fdb90e10 100644 (file)
@@ -89,248 +89,12 @@ etna_alu_to_scalar_filter_cb(const nir_instr *instr, const void *data)
    return false;
 }
 
-static void
-emit_inst(struct etna_compile *c, struct etna_inst *inst)
-{
-   c->code[c->inst_ptr++] = *inst;
-}
-
-/* to map nir srcs should to etna_inst srcs */
-enum {
-   SRC_0_1_2 = (0 << 0) | (1 << 2) | (2 << 4),
-   SRC_0_1_X = (0 << 0) | (1 << 2) | (3 << 4),
-   SRC_0_X_X = (0 << 0) | (3 << 2) | (3 << 4),
-   SRC_0_X_1 = (0 << 0) | (3 << 2) | (1 << 4),
-   SRC_0_1_0 = (0 << 0) | (1 << 2) | (0 << 4),
-   SRC_X_X_0 = (3 << 0) | (3 << 2) | (0 << 4),
-   SRC_0_X_0 = (0 << 0) | (3 << 2) | (0 << 4),
-};
-
-/* info to translate a nir op to etna_inst */
-struct etna_op_info {
-   uint8_t opcode; /* INST_OPCODE_ */
-   uint8_t src; /* SRC_ enum  */
-   uint8_t cond; /* INST_CONDITION_ */
-   uint8_t type; /* INST_TYPE_ */
-};
-
-static const struct etna_op_info etna_ops[] = {
-   [0 ... nir_num_opcodes - 1] = {0xff},
-#undef TRUE
-#undef FALSE
-#define OPCT(nir, op, src, cond, type) [nir_op_##nir] = { \
-   INST_OPCODE_##op, \
-   SRC_##src, \
-   INST_CONDITION_##cond, \
-   INST_TYPE_##type \
-}
-#define OPC(nir, op, src, cond) OPCT(nir, op, src, cond, F32)
-#define IOPC(nir, op, src, cond) OPCT(nir, op, src, cond, S32)
-#define UOPC(nir, op, src, cond) OPCT(nir, op, src, cond, U32)
-#define OP(nir, op, src) OPC(nir, op, src, TRUE)
-#define IOP(nir, op, src) IOPC(nir, op, src, TRUE)
-#define UOP(nir, op, src) UOPC(nir, op, src, TRUE)
-   OP(mov, MOV, X_X_0), OP(fneg, MOV, X_X_0), OP(fabs, MOV, X_X_0), OP(fsat, MOV, X_X_0),
-   OP(fmul, MUL, 0_1_X), OP(fadd, ADD, 0_X_1), OP(ffma, MAD, 0_1_2),
-   OP(fdot2, DP2, 0_1_X), OP(fdot3, DP3, 0_1_X), OP(fdot4, DP4, 0_1_X),
-   OPC(fmin, SELECT, 0_1_0, GT), OPC(fmax, SELECT, 0_1_0, LT),
-   OP(ffract, FRC, X_X_0), OP(frcp, RCP, X_X_0), OP(frsq, RSQ, X_X_0),
-   OP(fsqrt, SQRT, X_X_0), OP(fsin, SIN, X_X_0), OP(fcos, COS, X_X_0),
-   OP(fsign, SIGN, X_X_0), OP(ffloor, FLOOR, X_X_0), OP(fceil, CEIL, X_X_0),
-   OP(flog2, LOG, X_X_0), OP(fexp2, EXP, X_X_0),
-   OPC(seq, SET, 0_1_X, EQ), OPC(sne, SET, 0_1_X, NE), OPC(sge, SET, 0_1_X, GE), OPC(slt, SET, 0_1_X, LT),
-   OPC(fcsel, SELECT, 0_1_2, NZ),
-   OP(fdiv, DIV, 0_1_X),
-   OP(fddx, DSX, 0_X_0), OP(fddy, DSY, 0_X_0),
-
-   /* type convert */
-   IOP(i2f32, I2F, 0_X_X),
-   UOP(u2f32, I2F, 0_X_X),
-   IOP(f2i32, F2I, 0_X_X),
-   UOP(f2u32, F2I, 0_X_X),
-   UOP(b2f32, AND, 0_X_X), /* AND with fui(1.0f) */
-   UOP(b2i32, AND, 0_X_X), /* AND with 1 */
-   OPC(f2b32, CMP, 0_X_X, NE), /* != 0.0 */
-   UOPC(i2b32, CMP, 0_X_X, NE), /* != 0 */
-
-   /* arithmetic */
-   IOP(iadd, ADD, 0_X_1),
-   IOP(imul, IMULLO0, 0_1_X),
-   /* IOP(imad, IMADLO0, 0_1_2), */
-   IOP(ineg, ADD, X_X_0), /* ADD 0, -x */
-   IOP(iabs, IABS, X_X_0),
-   IOP(isign, SIGN, X_X_0),
-   IOPC(imin, SELECT, 0_1_0, GT),
-   IOPC(imax, SELECT, 0_1_0, LT),
-   UOPC(umin, SELECT, 0_1_0, GT),
-   UOPC(umax, SELECT, 0_1_0, LT),
-
-   /* select */
-   UOPC(b32csel, SELECT, 0_1_2, NZ),
-
-   /* compare with int result */
-    OPC(feq32, CMP, 0_1_X, EQ),
-    OPC(fne32, CMP, 0_1_X, NE),
-    OPC(fge32, CMP, 0_1_X, GE),
-    OPC(flt32, CMP, 0_1_X, LT),
-   IOPC(ieq32, CMP, 0_1_X, EQ),
-   IOPC(ine32, CMP, 0_1_X, NE),
-   IOPC(ige32, CMP, 0_1_X, GE),
-   IOPC(ilt32, CMP, 0_1_X, LT),
-   UOPC(uge32, CMP, 0_1_X, GE),
-   UOPC(ult32, CMP, 0_1_X, LT),
-
-   /* bit ops */
-   IOP(ior,  OR,  0_X_1),
-   IOP(iand, AND, 0_X_1),
-   IOP(ixor, XOR, 0_X_1),
-   IOP(inot, NOT, X_X_0),
-   IOP(ishl, LSHIFT, 0_X_1),
-   IOP(ishr, RSHIFT, 0_X_1),
-   UOP(ushr, RSHIFT, 0_X_1),
-};
-
 static void
 etna_emit_block_start(struct etna_compile *c, unsigned block)
 {
    c->block_ptr[block] = c->inst_ptr;
 }
 
-static void
-etna_emit_alu(struct etna_compile *c, nir_op op, struct etna_inst_dst dst,
-              struct etna_inst_src src[3], bool saturate)
-{
-   struct etna_op_info ei = etna_ops[op];
-   unsigned swiz_scalar = INST_SWIZ_BROADCAST(ffs(dst.write_mask) - 1);
-
-   if (ei.opcode == 0xff)
-      compile_error(c, "Unhandled ALU op: %s\n", nir_op_infos[op].name);
-
-   struct etna_inst inst = {
-      .opcode = ei.opcode,
-      .type = ei.type,
-      .cond = ei.cond,
-      .dst = dst,
-      .sat = saturate,
-   };
-
-   switch (op) {
-   case nir_op_fdiv:
-   case nir_op_flog2:
-   case nir_op_fsin:
-   case nir_op_fcos:
-      if (c->specs->has_new_transcendentals)
-         inst.tex.amode = 1;
-      /* fall through */
-   case nir_op_frsq:
-   case nir_op_frcp:
-   case nir_op_fexp2:
-   case nir_op_fsqrt:
-   case nir_op_imul:
-      /* scalar instructions we want src to be in x component */
-      src[0].swiz = inst_swiz_compose(src[0].swiz, swiz_scalar);
-      src[1].swiz = inst_swiz_compose(src[1].swiz, swiz_scalar);
-      break;
-   /* deal with instructions which don't have 1:1 mapping */
-   case nir_op_b2f32:
-      inst.src[2] = etna_immediate_float(1.0f);
-      break;
-   case nir_op_b2i32:
-      inst.src[2] = etna_immediate_int(1);
-      break;
-   case nir_op_f2b32:
-      inst.src[1] = etna_immediate_float(0.0f);
-      break;
-   case nir_op_i2b32:
-      inst.src[1] = etna_immediate_int(0);
-      break;
-   case nir_op_ineg:
-      inst.src[0] = etna_immediate_int(0);
-      src[0].neg = 1;
-      break;
-   default:
-      break;
-   }
-
-   /* set the "true" value for CMP instructions */
-   if (inst.opcode == INST_OPCODE_CMP)
-      inst.src[2] = etna_immediate_int(-1);
-
-   for (unsigned j = 0; j < 3; j++) {
-      unsigned i = ((ei.src >> j*2) & 3);
-      if (i < 3)
-         inst.src[j] = src[i];
-   }
-
-   emit_inst(c, &inst);
-}
-
-static void
-etna_emit_tex(struct etna_compile *c, nir_texop op, unsigned texid, unsigned dst_swiz,
-              struct etna_inst_dst dst, struct etna_inst_src coord,
-              struct etna_inst_src lod_bias, struct etna_inst_src compare)
-{
-   struct etna_inst inst = {
-      .dst = dst,
-      .tex.id = texid + (is_fs(c) ? 0 : c->specs->vertex_sampler_offset),
-      .tex.swiz = dst_swiz,
-      .src[0] = coord,
-   };
-
-   if (lod_bias.use)
-      inst.src[1] = lod_bias;
-
-   if (compare.use)
-      inst.src[2] = compare;
-
-   switch (op) {
-   case nir_texop_tex: inst.opcode = INST_OPCODE_TEXLD; break;
-   case nir_texop_txb: inst.opcode = INST_OPCODE_TEXLDB; break;
-   case nir_texop_txl: inst.opcode = INST_OPCODE_TEXLDL; break;
-   default:
-      compile_error(c, "Unhandled NIR tex type: %d\n", op);
-   }
-
-   emit_inst(c, &inst);
-}
-
-static void
-etna_emit_jump(struct etna_compile *c, unsigned block, struct etna_inst_src condition)
-{
-   if (!condition.use) {
-      emit_inst(c, &(struct etna_inst) {.opcode = INST_OPCODE_BRANCH, .imm = block });
-      return;
-   }
-
-   struct etna_inst inst = {
-      .opcode = INST_OPCODE_BRANCH,
-      .cond = INST_CONDITION_NOT,
-      .type = INST_TYPE_U32,
-      .src[0] = condition,
-      .imm = block,
-   };
-   inst.src[0].swiz = INST_SWIZ_BROADCAST(inst.src[0].swiz & 3);
-   emit_inst(c, &inst);
-}
-
-static void
-etna_emit_discard(struct etna_compile *c, struct etna_inst_src condition)
-{
-   if (!condition.use) {
-      emit_inst(c, &(struct etna_inst) { .opcode = INST_OPCODE_TEXKILL });
-      return;
-   }
-
-   struct etna_inst inst = {
-      .opcode = INST_OPCODE_TEXKILL,
-      .cond = INST_CONDITION_NZ,
-      .type = (c->specs->halti < 2) ? INST_TYPE_F32 : INST_TYPE_U32,
-      .src[0] = condition,
-   };
-   inst.src[0].swiz = INST_SWIZ_BROADCAST(inst.src[0].swiz & 3);
-   emit_inst(c, &inst);
-}
-
 static void
 etna_emit_output(struct etna_compile *c, nir_variable *var, struct etna_inst_src src)
 {
index 5c8bafde9b86063a663bd30e31d8a102cb161608..8ad67cb6a7ec407c1182c15993048ec3a6320a82 100644 (file)
@@ -235,4 +235,25 @@ struct live_def {
 unsigned
 etna_live_defs(nir_function_impl *impl, struct live_def *defs, unsigned *live_map);
 
+static inline void
+emit_inst(struct etna_compile *c, struct etna_inst *inst)
+{
+   c->code[c->inst_ptr++] = *inst;
+}
+
+void
+etna_emit_alu(struct etna_compile *c, nir_op op, struct etna_inst_dst dst,
+              struct etna_inst_src src[3], bool saturate);
+
+void
+etna_emit_tex(struct etna_compile *c, nir_texop op, unsigned texid, unsigned dst_swiz,
+              struct etna_inst_dst dst, struct etna_inst_src coord,
+              struct etna_inst_src lod_bias, struct etna_inst_src compare);
+
+void
+etna_emit_jump(struct etna_compile *c, unsigned block, struct etna_inst_src condition);
+
+void
+etna_emit_discard(struct etna_compile *c, struct etna_inst_src condition);
+
 #endif
diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.c b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.c
new file mode 100644 (file)
index 0000000..23eb9c2
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2019 Zodiac Inflight Innovations
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Jonathan Marek <jonathan@marek.ca>
+ */
+
+#include "etnaviv_compiler_nir.h"
+
+/* to map nir srcs should to etna_inst srcs */
+enum {
+   SRC_0_1_2 = (0 << 0) | (1 << 2) | (2 << 4),
+   SRC_0_1_X = (0 << 0) | (1 << 2) | (3 << 4),
+   SRC_0_X_X = (0 << 0) | (3 << 2) | (3 << 4),
+   SRC_0_X_1 = (0 << 0) | (3 << 2) | (1 << 4),
+   SRC_0_1_0 = (0 << 0) | (1 << 2) | (0 << 4),
+   SRC_X_X_0 = (3 << 0) | (3 << 2) | (0 << 4),
+   SRC_0_X_0 = (0 << 0) | (3 << 2) | (0 << 4),
+};
+
+/* info to translate a nir op to etna_inst */
+struct etna_op_info {
+   uint8_t opcode; /* INST_OPCODE_ */
+   uint8_t src; /* SRC_ enum  */
+   uint8_t cond; /* INST_CONDITION_ */
+   uint8_t type; /* INST_TYPE_ */
+};
+
+static const struct etna_op_info etna_ops[] = {
+   [0 ... nir_num_opcodes - 1] = {0xff},
+#undef TRUE
+#undef FALSE
+#define OPCT(nir, op, src, cond, type) [nir_op_##nir] = { \
+   INST_OPCODE_##op, \
+   SRC_##src, \
+   INST_CONDITION_##cond, \
+   INST_TYPE_##type \
+}
+#define OPC(nir, op, src, cond) OPCT(nir, op, src, cond, F32)
+#define IOPC(nir, op, src, cond) OPCT(nir, op, src, cond, S32)
+#define UOPC(nir, op, src, cond) OPCT(nir, op, src, cond, U32)
+#define OP(nir, op, src) OPC(nir, op, src, TRUE)
+#define IOP(nir, op, src) IOPC(nir, op, src, TRUE)
+#define UOP(nir, op, src) UOPC(nir, op, src, TRUE)
+   OP(mov, MOV, X_X_0), OP(fneg, MOV, X_X_0), OP(fabs, MOV, X_X_0), OP(fsat, MOV, X_X_0),
+   OP(fmul, MUL, 0_1_X), OP(fadd, ADD, 0_X_1), OP(ffma, MAD, 0_1_2),
+   OP(fdot2, DP2, 0_1_X), OP(fdot3, DP3, 0_1_X), OP(fdot4, DP4, 0_1_X),
+   OPC(fmin, SELECT, 0_1_0, GT), OPC(fmax, SELECT, 0_1_0, LT),
+   OP(ffract, FRC, X_X_0), OP(frcp, RCP, X_X_0), OP(frsq, RSQ, X_X_0),
+   OP(fsqrt, SQRT, X_X_0), OP(fsin, SIN, X_X_0), OP(fcos, COS, X_X_0),
+   OP(fsign, SIGN, X_X_0), OP(ffloor, FLOOR, X_X_0), OP(fceil, CEIL, X_X_0),
+   OP(flog2, LOG, X_X_0), OP(fexp2, EXP, X_X_0),
+   OPC(seq, SET, 0_1_X, EQ), OPC(sne, SET, 0_1_X, NE), OPC(sge, SET, 0_1_X, GE), OPC(slt, SET, 0_1_X, LT),
+   OPC(fcsel, SELECT, 0_1_2, NZ),
+   OP(fdiv, DIV, 0_1_X),
+   OP(fddx, DSX, 0_X_0), OP(fddy, DSY, 0_X_0),
+
+   /* type convert */
+   IOP(i2f32, I2F, 0_X_X),
+   UOP(u2f32, I2F, 0_X_X),
+   IOP(f2i32, F2I, 0_X_X),
+   UOP(f2u32, F2I, 0_X_X),
+   UOP(b2f32, AND, 0_X_X), /* AND with fui(1.0f) */
+   UOP(b2i32, AND, 0_X_X), /* AND with 1 */
+   OPC(f2b32, CMP, 0_X_X, NE), /* != 0.0 */
+   UOPC(i2b32, CMP, 0_X_X, NE), /* != 0 */
+
+   /* arithmetic */
+   IOP(iadd, ADD, 0_X_1),
+   IOP(imul, IMULLO0, 0_1_X),
+   /* IOP(imad, IMADLO0, 0_1_2), */
+   IOP(ineg, ADD, X_X_0), /* ADD 0, -x */
+   IOP(iabs, IABS, X_X_0),
+   IOP(isign, SIGN, X_X_0),
+   IOPC(imin, SELECT, 0_1_0, GT),
+   IOPC(imax, SELECT, 0_1_0, LT),
+   UOPC(umin, SELECT, 0_1_0, GT),
+   UOPC(umax, SELECT, 0_1_0, LT),
+
+   /* select */
+   UOPC(b32csel, SELECT, 0_1_2, NZ),
+
+   /* compare with int result */
+    OPC(feq32, CMP, 0_1_X, EQ),
+    OPC(fne32, CMP, 0_1_X, NE),
+    OPC(fge32, CMP, 0_1_X, GE),
+    OPC(flt32, CMP, 0_1_X, LT),
+   IOPC(ieq32, CMP, 0_1_X, EQ),
+   IOPC(ine32, CMP, 0_1_X, NE),
+   IOPC(ige32, CMP, 0_1_X, GE),
+   IOPC(ilt32, CMP, 0_1_X, LT),
+   UOPC(uge32, CMP, 0_1_X, GE),
+   UOPC(ult32, CMP, 0_1_X, LT),
+
+   /* bit ops */
+   IOP(ior,  OR,  0_X_1),
+   IOP(iand, AND, 0_X_1),
+   IOP(ixor, XOR, 0_X_1),
+   IOP(inot, NOT, X_X_0),
+   IOP(ishl, LSHIFT, 0_X_1),
+   IOP(ishr, RSHIFT, 0_X_1),
+   UOP(ushr, RSHIFT, 0_X_1),
+};
+
+void
+etna_emit_alu(struct etna_compile *c, nir_op op, struct etna_inst_dst dst,
+              struct etna_inst_src src[3], bool saturate)
+{
+   struct etna_op_info ei = etna_ops[op];
+   unsigned swiz_scalar = INST_SWIZ_BROADCAST(ffs(dst.write_mask) - 1);
+
+   if (ei.opcode == 0xff)
+      compile_error(c, "Unhandled ALU op: %s\n", nir_op_infos[op].name);
+
+   struct etna_inst inst = {
+      .opcode = ei.opcode,
+      .type = ei.type,
+      .cond = ei.cond,
+      .dst = dst,
+      .sat = saturate,
+   };
+
+   switch (op) {
+   case nir_op_fdiv:
+   case nir_op_flog2:
+   case nir_op_fsin:
+   case nir_op_fcos:
+      if (c->specs->has_new_transcendentals)
+         inst.tex.amode = 1;
+      /* fall through */
+   case nir_op_frsq:
+   case nir_op_frcp:
+   case nir_op_fexp2:
+   case nir_op_fsqrt:
+   case nir_op_imul:
+      /* scalar instructions we want src to be in x component */
+      src[0].swiz = inst_swiz_compose(src[0].swiz, swiz_scalar);
+      src[1].swiz = inst_swiz_compose(src[1].swiz, swiz_scalar);
+      break;
+   /* deal with instructions which don't have 1:1 mapping */
+   case nir_op_b2f32:
+      inst.src[2] = etna_immediate_float(1.0f);
+      break;
+   case nir_op_b2i32:
+      inst.src[2] = etna_immediate_int(1);
+      break;
+   case nir_op_f2b32:
+      inst.src[1] = etna_immediate_float(0.0f);
+      break;
+   case nir_op_i2b32:
+      inst.src[1] = etna_immediate_int(0);
+      break;
+   case nir_op_ineg:
+      inst.src[0] = etna_immediate_int(0);
+      src[0].neg = 1;
+      break;
+   default:
+      break;
+   }
+
+   /* set the "true" value for CMP instructions */
+   if (inst.opcode == INST_OPCODE_CMP)
+      inst.src[2] = etna_immediate_int(-1);
+
+   for (unsigned j = 0; j < 3; j++) {
+      unsigned i = ((ei.src >> j*2) & 3);
+      if (i < 3)
+         inst.src[j] = src[i];
+   }
+
+   emit_inst(c, &inst);
+}
+
+void
+etna_emit_tex(struct etna_compile *c, nir_texop op, unsigned texid, unsigned dst_swiz,
+              struct etna_inst_dst dst, struct etna_inst_src coord,
+              struct etna_inst_src lod_bias, struct etna_inst_src compare)
+{
+   struct etna_inst inst = {
+      .dst = dst,
+      .tex.id = texid + (is_fs(c) ? 0 : c->specs->vertex_sampler_offset),
+      .tex.swiz = dst_swiz,
+      .src[0] = coord,
+   };
+
+   if (lod_bias.use)
+      inst.src[1] = lod_bias;
+
+   if (compare.use)
+      inst.src[2] = compare;
+
+   switch (op) {
+   case nir_texop_tex: inst.opcode = INST_OPCODE_TEXLD; break;
+   case nir_texop_txb: inst.opcode = INST_OPCODE_TEXLDB; break;
+   case nir_texop_txl: inst.opcode = INST_OPCODE_TEXLDL; break;
+   default:
+      compile_error(c, "Unhandled NIR tex type: %d\n", op);
+   }
+
+   emit_inst(c, &inst);
+}
+
+void
+etna_emit_jump(struct etna_compile *c, unsigned block, struct etna_inst_src condition)
+{
+   if (!condition.use) {
+      emit_inst(c, &(struct etna_inst) {.opcode = INST_OPCODE_BRANCH, .imm = block });
+      return;
+   }
+
+   struct etna_inst inst = {
+      .opcode = INST_OPCODE_BRANCH,
+      .cond = INST_CONDITION_NOT,
+      .type = INST_TYPE_U32,
+      .src[0] = condition,
+      .imm = block,
+   };
+   inst.src[0].swiz = INST_SWIZ_BROADCAST(inst.src[0].swiz & 3);
+   emit_inst(c, &inst);
+}
+
+void
+etna_emit_discard(struct etna_compile *c, struct etna_inst_src condition)
+{
+   if (!condition.use) {
+      emit_inst(c, &(struct etna_inst) { .opcode = INST_OPCODE_TEXKILL });
+      return;
+   }
+
+   struct etna_inst inst = {
+      .opcode = INST_OPCODE_TEXKILL,
+      .cond = INST_CONDITION_NZ,
+      .type = (c->specs->halti < 2) ? INST_TYPE_F32 : INST_TYPE_U32,
+      .src[0] = condition,
+   };
+   inst.src[0].swiz = INST_SWIZ_BROADCAST(inst.src[0].swiz & 3);
+   emit_inst(c, &inst);
+}
index 737264f087a4eb8e4ce0670e078590403cde962c..cf775afe194da2d9c55d981fa9c32c377f099c43 100644 (file)
@@ -37,6 +37,7 @@ files_etnaviv = files(
   'etnaviv_clear_blit.h',
   'etnaviv_compiler.h',
   'etnaviv_compiler_nir.c',
+  'etnaviv_compiler_nir_emit.c',
   'etnaviv_compiler_nir_emit.h',
   'etnaviv_compiler_nir_liveness.c',
   'etnaviv_compiler_tgsi.c',