summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/ir3
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2014-09-28 22:00:34 -0400
committerRob Clark <[email protected]>2014-10-02 23:30:47 -0400
commit347bc197a6f245c1ac3954acfefd15995f34d0f5 (patch)
treed0520a75b91750d39695472c0ae9585d2eabcf18 /src/gallium/drivers/freedreno/ir3
parentad5db64e7edf4bf1323168b4f3059df7eedfac1f (diff)
freedreno/ir3: add ISSG support
Signed-off-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/ir3')
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
index 4250401e7e5..83c687f266f 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
@@ -1589,6 +1589,44 @@ trans_ucmp(const struct instr_translater *t,
put_dst(ctx, inst, dst);
}
+/*
+ * ISSG(a) = a < 0 ? -1 : a > 0 ? 1 : 0
+ * cmps.s.lt tmp_neg, a, 0 # 1 if a is negative
+ * cmps.s.gt tmp_pos, a, 0 # 1 if a is positive
+ * sub.u dst, tmp_pos, tmp_neg
+ */
+static void
+trans_issg(const struct instr_translater *t,
+ struct ir3_compile_context *ctx,
+ struct tgsi_full_instruction *inst)
+{
+ struct ir3_instruction *instr;
+ struct tgsi_dst_register *dst = get_dst(ctx, inst);
+ struct tgsi_src_register *a = &inst->Src[0].Register;
+ struct tgsi_dst_register neg_dst, pos_dst;
+ struct tgsi_src_register *neg_src, *pos_src;
+
+ neg_src = get_internal_temp(ctx, &neg_dst);
+ pos_src = get_internal_temp(ctx, &pos_dst);
+
+ /* cmps.s.lt neg, a, 0 */
+ instr = instr_create(ctx, 2, OPC_CMPS_S);
+ instr->cat2.condition = IR3_COND_LT;
+ vectorize(ctx, instr, &neg_dst, 2, a, 0, 0, IR3_REG_IMMED);
+
+ /* cmps.s.gt pos, a, 0 */
+ instr = instr_create(ctx, 2, OPC_CMPS_S);
+ instr->cat2.condition = IR3_COND_GT;
+ vectorize(ctx, instr, &pos_dst, 2, a, 0, 0, IR3_REG_IMMED);
+
+ /* sub.u dst, pos, neg */
+ instr = instr_create(ctx, 2, OPC_SUB_U);
+ vectorize(ctx, instr, dst, 2, pos_src, 0, neg_src, 0);
+
+ put_dst(ctx, inst, dst);
+}
+
+
/*
* Conditional / Flow control
@@ -2416,6 +2454,7 @@ static const struct instr_translater translaters[TGSI_OPCODE_LAST] = {
INSTR(ISLT, trans_icmp, .opc = OPC_CMPS_S),
INSTR(USLT, trans_icmp, .opc = OPC_CMPS_U),
INSTR(UCMP, trans_ucmp),
+ INSTR(ISSG, trans_issg),
INSTR(IF, trans_if, .opc = OPC_CMPS_F),
INSTR(UIF, trans_if, .opc = OPC_CMPS_U),
INSTR(ELSE, trans_else),