summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/broadcom/compiler/qpu_validate.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/broadcom/compiler/qpu_validate.c b/src/broadcom/compiler/qpu_validate.c
index 4ef587c1d52..492f2e64d09 100644
--- a/src/broadcom/compiler/qpu_validate.c
+++ b/src/broadcom/compiler/qpu_validate.c
@@ -41,7 +41,15 @@ struct v3d_qpu_validate_state {
int last_sfu_write;
int last_branch_ip;
int last_thrsw_ip;
+
+ /* Set when we've found the last-THRSW signal, or if we were started
+ * in single-segment mode.
+ */
bool last_thrsw_found;
+
+ /* Set when we've found the THRSW after the last THRSW */
+ bool thrend_found;
+
int thrsw_count;
};
@@ -204,6 +212,9 @@ qpu_validate_inst(struct v3d_qpu_validate_state *state, struct qinst *qinst)
if (in_branch_delay_slots(state))
fail_instr(state, "THRSW in a branch delay slot.");
+ if (state->last_thrsw_found)
+ state->thrend_found = true;
+
if (state->last_thrsw_ip == state->ip - 1) {
/* If it's the second THRSW in a row, then it's just a
* last-thrsw signal.
@@ -221,6 +232,23 @@ qpu_validate_inst(struct v3d_qpu_validate_state *state, struct qinst *qinst)
}
}
+ if (state->thrend_found &&
+ state->last_thrsw_ip - state->ip <= 2 &&
+ inst->type == V3D_QPU_INSTR_TYPE_ALU) {
+ if ((inst->alu.add.op != V3D_QPU_A_NOP &&
+ !inst->alu.add.magic_write)) {
+ fail_instr(state, "RF write after THREND");
+ }
+
+ if ((inst->alu.mul.op != V3D_QPU_M_NOP &&
+ !inst->alu.mul.magic_write)) {
+ fail_instr(state, "RF write after THREND");
+ }
+
+ if (v3d_qpu_sig_writes_address(devinfo, &inst->sig))
+ fail_instr(state, "RF write after THREND");
+ }
+
if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH) {
if (in_branch_delay_slots(state))
fail_instr(state, "branch in a branch delay slot.");
@@ -262,6 +290,8 @@ qpu_validate(struct v3d_compile *c)
.last_thrsw_ip = -10,
.last_branch_ip = -10,
.ip = 0,
+
+ .last_thrsw_found = !c->last_thrsw,
};
vir_for_each_block(block, c) {
@@ -273,8 +303,6 @@ qpu_validate(struct v3d_compile *c)
"thread switch found without last-THRSW in program");
}
- if (state.thrsw_count == 0 ||
- (state.last_thrsw_found && state.thrsw_count == 1)) {
+ if (!state.thrend_found)
fail_instr(&state, "No program-end THRSW found");
- }
}