broadcom/vc5: Add QPU validation for register writes after thrend.

The next shader gets to start writing the register file during these
slots, so make sure we don't stomp over them.

The only case of hitting this that I could imagine would be dead writes.
This commit is contained in:
Eric Anholt 2018-04-25 13:51:47 -07:00
parent 8adf813f83
commit dc4cb04ee5

View file

@ -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");
}
}