diff options
-rw-r--r-- | src/broadcom/compiler/vir_to_qpu.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/broadcom/compiler/vir_to_qpu.c b/src/broadcom/compiler/vir_to_qpu.c index 11a7ef91031..568a004803b 100644 --- a/src/broadcom/compiler/vir_to_qpu.c +++ b/src/broadcom/compiler/vir_to_qpu.c @@ -138,6 +138,60 @@ set_src(struct v3d_qpu_instr *instr, enum v3d_qpu_mux *mux, struct qpu_reg src) } } +static bool +is_no_op_mov(struct qinst *qinst) +{ + static const struct v3d_qpu_sig no_sig = {0}; + + /* Make sure it's just a lone MOV. */ + if (qinst->qpu.type != V3D_QPU_INSTR_TYPE_ALU || + qinst->qpu.alu.mul.op != V3D_QPU_M_MOV || + qinst->qpu.alu.add.op != V3D_QPU_A_NOP || + memcmp(&qinst->qpu.sig, &no_sig, sizeof(no_sig)) != 0) { + return false; + } + + /* Check if it's a MOV from a register to itself. */ + enum v3d_qpu_waddr waddr = qinst->qpu.alu.mul.waddr; + if (qinst->qpu.alu.mul.magic_write) { + if (waddr < V3D_QPU_WADDR_R0 || waddr > V3D_QPU_WADDR_R4) + return false; + + if (qinst->qpu.alu.mul.a != + V3D_QPU_MUX_R0 + (waddr - V3D_QPU_WADDR_R0)) { + return false; + } + } else { + int raddr; + + switch (qinst->qpu.alu.mul.a) { + case V3D_QPU_MUX_A: + raddr = qinst->qpu.raddr_a; + break; + case V3D_QPU_MUX_B: + raddr = qinst->qpu.raddr_b; + break; + default: + return false; + } + if (raddr != waddr) + return false; + } + + /* No packing or flags updates, or we need to execute the + * instruction. + */ + if (qinst->qpu.alu.mul.a_unpack != V3D_QPU_UNPACK_NONE || + qinst->qpu.alu.mul.output_pack != V3D_QPU_PACK_NONE || + qinst->qpu.flags.mc != V3D_QPU_COND_NONE || + qinst->qpu.flags.mpf != V3D_QPU_PF_NONE || + qinst->qpu.flags.muf != V3D_QPU_UF_NONE) { + return false; + } + + return true; +} + static void v3d_generate_code_block(struct v3d_compile *c, struct qblock *block, @@ -145,7 +199,7 @@ v3d_generate_code_block(struct v3d_compile *c, { int last_vpm_read_index = -1; - vir_for_each_inst(qinst, block) { + vir_for_each_inst_safe(qinst, block) { #if 0 fprintf(stderr, "translating qinst to qpu: "); vir_dump_inst(c, qinst); @@ -289,6 +343,11 @@ v3d_generate_code_block(struct v3d_compile *c, qinst->qpu.alu.mul.waddr = dst.index; qinst->qpu.alu.mul.magic_write = dst.magic; + + if (is_no_op_mov(qinst)) { + vir_remove_instruction(c, qinst); + continue; + } } } else { assert(qinst->qpu.type == V3D_QPU_INSTR_TYPE_BRANCH); |