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;
};
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.
}
}
+ 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.");
.last_thrsw_ip = -10,
.last_branch_ip = -10,
.ip = 0,
+
+ .last_thrsw_found = !c->last_thrsw,
};
vir_for_each_block(block, 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");
- }
}