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 63e1ee543053af32013d42b18672afc1f784479b..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:
@@ -300,6 +302,22 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                                 last_vpm_read_index = qinst->src[i].index;
                                 src[i] = qpu_ra(QPU_R_VPM);
                                 break;
+
+                        case QFILE_FRAG_X:
+                                src[i] = qpu_ra(QPU_R_XY_PIXEL_COORD);
+                                break;
+                        case QFILE_FRAG_Y:
+                                src[i] = qpu_rb(QPU_R_XY_PIXEL_COORD);
+                                break;
+                        case QFILE_FRAG_REV_FLAG:
+                                src[i] = qpu_rb(QPU_R_MS_REV_FLAGS);
+                                break;
+
+                        case QFILE_TLB_COLOR_WRITE:
+                        case QFILE_TLB_COLOR_WRITE_MS:
+                        case QFILE_TLB_Z_WRITE:
+                        case QFILE_TLB_STENCIL_SETUP:
+                                unreachable("bad qir src file");
                         }
                 }
 
@@ -314,9 +332,30 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                 case QFILE_VPM:
                         dst = qpu_ra(QPU_W_VPM);
                         break;
+
+                case QFILE_TLB_COLOR_WRITE:
+                        dst = qpu_tlbc();
+                        break;
+
+                case QFILE_TLB_COLOR_WRITE_MS:
+                        dst = qpu_tlbc_ms();
+                        break;
+
+                case QFILE_TLB_Z_WRITE:
+                        dst = qpu_ra(QPU_W_TLB_Z);
+                        break;
+
+                case QFILE_TLB_STENCIL_SETUP:
+                        dst = qpu_ra(QPU_W_TLB_STENCIL_SETUP);
+                        break;
+
                 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:
                         assert(!"not reached");
                         break;
                 }
@@ -353,19 +392,9 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
 
                         break;
 
-                case QOP_FRAG_X:
-                        queue(c, qpu_a_ITOF(dst,
-                                            qpu_ra(QPU_R_XY_PIXEL_COORD)));
-                        break;
-
-                case QOP_FRAG_Y:
-                        queue(c, qpu_a_ITOF(dst,
-                                            qpu_rb(QPU_R_XY_PIXEL_COORD)));
-                        break;
-
-                case QOP_FRAG_REV_FLAG:
-                        queue(c, qpu_a_ITOF(dst,
-                                            qpu_rb(QPU_R_MS_REV_FLAGS)));
+                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:
@@ -383,19 +412,6 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                          */
                         break;
 
-                case QOP_TLB_STENCIL_SETUP:
-                        assert(!unpack);
-                        queue(c, qpu_a_MOV(qpu_ra(QPU_W_TLB_STENCIL_SETUP),
-                                           src[0]) | unpack);
-                        break;
-
-                case QOP_TLB_Z_WRITE:
-                        queue(c, qpu_a_MOV(qpu_ra(QPU_W_TLB_Z),
-                                           src[0]) | unpack);
-                        set_last_cond_add(c, qinst->cond);
-                        handled_qinst_cond = true;
-                        break;
-
                 case QOP_TLB_COLOR_READ:
                         queue(c, qpu_NOP());
                         *last_inst(c) = qpu_set_sig(*last_inst(c),
@@ -403,18 +419,6 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
                         handle_r4_qpu_write(c, qinst, dst);
                         break;
 
-                case QOP_TLB_COLOR_WRITE:
-                        queue(c, qpu_a_MOV(qpu_tlbc(), src[0]) | unpack);
-                        set_last_cond_add(c, qinst->cond);
-                        handled_qinst_cond = true;
-                        break;
-
-                case QOP_TLB_COLOR_WRITE_MS:
-                        queue(c, qpu_a_MOV(qpu_tlbc_ms(), src[0]));
-                        set_last_cond_add(c, qinst->cond);
-                        handled_qinst_cond = true;
-                        break;
-
                 case QOP_VARY_ADD_C:
                         queue(c, qpu_a_FADD(dst, src[0], qpu_r5()) | unpack);
                         break;
@@ -442,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 */
@@ -513,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);