aboutsummaryrefslogtreecommitdiffstats
path: root/src/panfrost/bifrost
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2020-04-28 12:27:34 -0400
committerMarge Bot <[email protected]>2020-04-28 17:17:48 +0000
commitc94d41ad7c92a9549e16f733dcb6a0a0762e811f (patch)
tree803b0d2233a969230761e528030234d3c21335ff /src/panfrost/bifrost
parent1520131d82812c815a08e322d182f7f2dc84f627 (diff)
pan/bi: Pack FMA 32 FCMP
Signed-off-by: Alyssa Rosenzweig <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4789>
Diffstat (limited to 'src/panfrost/bifrost')
-rw-r--r--src/panfrost/bifrost/bi_pack.c82
-rw-r--r--src/panfrost/bifrost/bifrost.h3
2 files changed, 85 insertions, 0 deletions
diff --git a/src/panfrost/bifrost/bi_pack.c b/src/panfrost/bifrost/bi_pack.c
index af5193949f8..ea0319a0cd7 100644
--- a/src/panfrost/bifrost/bi_pack.c
+++ b/src/panfrost/bifrost/bi_pack.c
@@ -956,6 +956,87 @@ bi_pack_fma_select(bi_instruction *ins, struct bi_registers *regs)
}
}
+static enum bifrost_fcmp_cond
+bi_fcmp_cond(enum bi_cond cond)
+{
+ switch (cond) {
+ case BI_COND_LT: return BIFROST_OLT;
+ case BI_COND_LE: return BIFROST_OLE;
+ case BI_COND_GE: return BIFROST_OGE;
+ case BI_COND_GT: return BIFROST_OGT;
+ case BI_COND_EQ: return BIFROST_OEQ;
+ case BI_COND_NE: return BIFROST_UNE;
+ default: unreachable("Unknown bi_cond");
+ }
+}
+
+/* a <?> b <==> b <flip(?)> a (TODO: NaN behaviour?) */
+
+static enum bifrost_fcmp_cond
+bi_flip_fcmp(enum bifrost_fcmp_cond cond)
+{
+ switch (cond) {
+ case BIFROST_OGT:
+ return BIFROST_OLT;
+ case BIFROST_OGE:
+ return BIFROST_OLE;
+ case BIFROST_OLT:
+ return BIFROST_OGT;
+ case BIFROST_OLE:
+ return BIFROST_OGE;
+ case BIFROST_OEQ:
+ case BIFROST_UNE:
+ return cond;
+ default:
+ unreachable("Unknown fcmp cond");
+ }
+}
+
+static unsigned
+bi_pack_fma_cmp(bi_instruction *ins, struct bi_registers *regs)
+{
+ nir_alu_type Tl = ins->src_types[0];
+ nir_alu_type Tr = ins->src_types[1];
+
+ if (Tl == nir_type_float32 || Tr == nir_type_float32) {
+ /* TODO: Mixed 32/16 cmp */
+ assert(Tl == Tr);
+
+ enum bifrost_fcmp_cond cond = bi_fcmp_cond(ins->cond);
+
+ /* Only src1 has neg, so we arrange:
+ * a < b --- native
+ * a < -b --- native
+ * -a < -b <===> a > b
+ * -a < b <===> a > -b
+ * TODO: Is this NaN-precise?
+ */
+
+ bool flip = ins->src_neg[0];
+ bool neg = ins->src_neg[0] ^ ins->src_neg[1];
+
+ if (flip)
+ cond = bi_flip_fcmp(cond);
+
+ struct bifrost_fma_fcmp pack = {
+ .src0 = bi_get_src(ins, regs, 0, true),
+ .src1 = bi_get_src(ins, regs, 1, true),
+ .src0_abs = ins->src_abs[0],
+ .src1_abs = ins->src_abs[1],
+ .src1_neg = neg,
+ .src_expand = 0,
+ .unk1 = 0,
+ .cond = cond,
+ .op = BIFROST_FMA_OP_FCMP_GL
+ };
+
+ RETURN_PACKED(pack);
+ } else {
+ unreachable("Unknown cmp type");
+ }
+}
+
+
static unsigned
bi_pack_fma(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs)
{
@@ -966,6 +1047,7 @@ bi_pack_fma(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs)
case BI_ADD:
return bi_pack_fma_addmin(bundle.fma, regs);
case BI_CMP:
+ return bi_pack_fma_cmp(bundle.fma, regs);
case BI_BITWISE:
return BIFROST_FMA_NOP;
case BI_CONVERT:
diff --git a/src/panfrost/bifrost/bifrost.h b/src/panfrost/bifrost/bifrost.h
index e6fac6cae8b..66e337ca996 100644
--- a/src/panfrost/bifrost/bifrost.h
+++ b/src/panfrost/bifrost/bifrost.h
@@ -396,6 +396,9 @@ enum bifrost_fcmp_cond {
BIFROST_OLE = 5,
};
+#define BIFROST_FMA_OP_FCMP_GL (0x48000 >> 13)
+#define BIFROST_FMA_OP_FCMP_D3D (0x4c000 >> 13)
+
struct bifrost_fma_fcmp {
unsigned src0 : 3;
unsigned src1 : 3;