diff options
-rw-r--r-- | src/broadcom/compiler/qpu_validate.c | 34 |
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"); - } } |