From: Eric Anholt Date: Wed, 25 Apr 2018 20:51:47 +0000 (-0700) Subject: broadcom/vc5: Add QPU validation for register writes after thrend. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=dc4cb04ee516c5e17181cf04d932dcc2da533388;p=mesa.git 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. --- 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"); - } }