diff options
author | Eric Anholt <[email protected]> | 2014-07-16 08:12:27 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2014-08-08 18:59:47 -0700 |
commit | 4c53087c67a266d81653459baa08ece5c1b418d8 (patch) | |
tree | 105694f640c6a1b65d11dae94f06469e2b9dea4e /src/gallium/drivers | |
parent | eea1d36915cb97ee1a6eb6aeaf15dd5689f03148 (diff) |
vc4: Add support for CMP.
This took a couple of tries, and this is the squash of those attempts.
v2: Fix register file conflicts on the args in the
destination-is-accumulator case.
v3: Rebase on helper change and qir_inst4 change.
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/vc4/vc4_program.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qir.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qir.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qpu_emit.c | 40 |
4 files changed, 48 insertions, 1 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 0e415a8baf6..993ac41fc11 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -202,7 +202,11 @@ tgsi_to_qir_alu(struct tgsi_to_qir *trans, { struct qcompile *c = trans->c; struct qreg dst = qir_get_temp(c); - qir_emit(c, qir_inst(op, dst, src[0 * 4 + i], src[1 * 4 + i])); + qir_emit(c, qir_inst4(op, dst, + src[0 * 4 + i], + src[1 * 4 + i], + src[2 * 4 + i], + c->undef)); return dst; } @@ -325,6 +329,7 @@ emit_tgsi_instruction(struct tgsi_to_qir *trans, [TGSI_OPCODE_SNE] = { QOP_SNE, tgsi_to_qir_alu }, [TGSI_OPCODE_SGE] = { QOP_SGE, tgsi_to_qir_alu }, [TGSI_OPCODE_SLT] = { QOP_SLT, tgsi_to_qir_alu }, + [TGSI_OPCODE_CMP] = { QOP_CMP, tgsi_to_qir_alu }, [TGSI_OPCODE_MAD] = { 0, tgsi_to_qir_mad }, [TGSI_OPCODE_DP2] = { 0, tgsi_to_qir_dp2 }, [TGSI_OPCODE_DP3] = { 0, tgsi_to_qir_dp3 }, diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c index 02342f212c3..b8a8a7ca7dc 100644 --- a/src/gallium/drivers/vc4/vc4_qir.c +++ b/src/gallium/drivers/vc4/vc4_qir.c @@ -48,6 +48,7 @@ static const struct qir_op_info qir_op_info[] = { [QOP_SNE] = { "sne", 1, 2 }, [QOP_SGE] = { "sge", 1, 2 }, [QOP_SLT] = { "slt", 1, 2 }, + [QOP_CMP] = { "cmp", 1, 3 }, [QOP_FTOI] = { "ftoi", 1, 1 }, [QOP_RCP] = { "rcp", 1, 1 }, diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h index cd7133cdc88..76e46ff107f 100644 --- a/src/gallium/drivers/vc4/vc4_qir.h +++ b/src/gallium/drivers/vc4/vc4_qir.h @@ -55,6 +55,7 @@ enum qop { QOP_SNE, QOP_SGE, QOP_SLT, + QOP_CMP, QOP_FTOI, QOP_RCP, diff --git a/src/gallium/drivers/vc4/vc4_qpu_emit.c b/src/gallium/drivers/vc4/vc4_qpu_emit.c index b8a506eb174..da47539af0f 100644 --- a/src/gallium/drivers/vc4/vc4_qpu_emit.c +++ b/src/gallium/drivers/vc4/vc4_qpu_emit.c @@ -332,6 +332,46 @@ vc4_generate_code(struct qcompile *c) } break; + case QOP_CMP: + queue(c, qpu_inst(qpu_a_MOV(qpu_ra(QPU_W_NOP), + src[0]), + qpu_m_NOP())); + *last_inst(c) |= QPU_SF; + + if (dst.mux <= QPU_MUX_R3) { + fixup_raddr_conflict(c, src[1], &src[2]); + queue(c, qpu_inst(qpu_a_MOV(dst, src[1]), + qpu_m_MOV(dst, src[2]))); + *last_inst(c) = ((*last_inst(c) & ~(QPU_COND_ADD_MASK | + QPU_COND_MUL_MASK)) + | QPU_SET_FIELD(QPU_COND_NS, + QPU_COND_ADD) + | QPU_SET_FIELD(QPU_COND_NC, + QPU_COND_MUL)); + } else { + if (dst.mux == src[1].mux && + dst.addr == src[1].addr) { + queue(c, qpu_inst(qpu_a_MOV(dst, src[1]), + qpu_m_NOP())); + + queue(c, qpu_inst(qpu_a_MOV(dst, src[2]), + qpu_m_NOP())); + *last_inst(c) = ((*last_inst(c) & ~(QPU_COND_ADD_MASK)) + | QPU_SET_FIELD(QPU_COND_NC, + QPU_COND_ADD)); + } else { + queue(c, qpu_inst(qpu_a_MOV(dst, src[2]), + qpu_m_NOP())); + + queue(c, qpu_inst(qpu_a_MOV(dst, src[1]), + qpu_m_NOP())); + *last_inst(c) = ((*last_inst(c) & ~(QPU_COND_ADD_MASK)) + | QPU_SET_FIELD(QPU_COND_NS, + QPU_COND_ADD)); + } + } + break; + case QOP_SEQ: case QOP_SNE: case QOP_SGE: |