vc4: Convert vc4_opt_dead_code to work in the presence of control flow.
[mesa.git] / src / gallium / drivers / vc4 / vc4_qpu_emit.c
index ae3590854b2a41b6f62ed864d851550e7c8f602c..2257dcce83be3f70c180c612abbe815d75f6fb2f 100644 (file)
@@ -40,6 +40,7 @@ vc4_dump_program(struct vc4_compile *c)
                 vc4_qpu_disasm(&c->qpu_insts[i], 1);
                 fprintf(stderr, "\n");
         }
+        fprintf(stderr, "\n");
 }
 
 static void
@@ -212,7 +213,7 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                 break;
         }
 
-        list_for_each_entry(struct qinst, qinst, &c->instructions, link) {
+        qir_for_each_inst_inorder(qinst, c) {
 #if 0
                 fprintf(stderr, "translating qinst to qpu: ");
                 qir_dump_inst(qinst);
@@ -266,6 +267,7 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                         int index = qinst->src[i].index;
                         switch (qinst->src[i].file) {
                         case QFILE_NULL:
+                        case QFILE_LOAD_IMM:
                                 src[i] = qpu_rn(0);
                                 break;
                         case QFILE_TEMP:
@@ -350,6 +352,7 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                 case QFILE_VARY:
                 case QFILE_UNIF:
                 case QFILE_SMALL_IMM:
+                case QFILE_LOAD_IMM:
                 case QFILE_FRAG_X:
                 case QFILE_FRAG_Y:
                 case QFILE_FRAG_REV_FLAG:
@@ -389,6 +392,11 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
 
                         break;
 
+                case QOP_LOAD_IMM:
+                        assert(qinst->src[0].file == QFILE_LOAD_IMM);
+                        queue(c, qpu_load_imm_ui(dst, qinst->src[0].index));
+                        break;
+
                 case QOP_MS_MASK:
                         src[1] = qpu_ra(QPU_R_MS_REV_FLAGS);
                         fixup_raddr_conflict(c, dst, &src[0], &src[1],
@@ -438,6 +446,15 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                         handle_r4_qpu_write(c, qinst, dst);
                         break;
 
+                case QOP_BRANCH:
+                        /* The branch target will be updated at QPU scheduling
+                         * time.
+                         */
+                        queue(c, (qpu_branch(qinst->cond, 0) |
+                                  QPU_BRANCH_REL));
+                        handled_qinst_cond = true;
+                        break;
+
                 default:
                         assert(qinst->op < ARRAY_SIZE(translate));
                         assert(translate[qinst->op].op != 0); /* NOPs */
@@ -509,6 +526,14 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
         if (qpu_inst_is_tlb(c->qpu_insts[c->qpu_inst_count - 1]))
                 qpu_serialize_one_inst(c, qpu_NOP());
 
+        /* Make sure there's no existing signal set (like for a small
+         * immediate)
+         */
+        if (QPU_GET_FIELD(c->qpu_insts[c->qpu_inst_count - 1],
+                          QPU_SIG) != QPU_SIG_NONE) {
+                qpu_serialize_one_inst(c, qpu_NOP());
+        }
+
         c->qpu_insts[c->qpu_inst_count - 1] =
                 qpu_set_sig(c->qpu_insts[c->qpu_inst_count - 1],
                             QPU_SIG_PROG_END);