summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>2020-04-28 14:19:34 -0400
committerMarge Bot <eric+marge@anholt.net>2020-04-29 00:30:05 +0000
commitef9582738e5950764dcd33eddef7183e5529e5ff (patch)
tree2dfd27bd32e66c653e6f8c65457c93a8470f4d8d
parent9b415bf6a037867432c72294f0f03917f3b06ae8 (diff)
pan/bi: Pack BI_BITWISE
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4790>
-rw-r--r--src/panfrost/bifrost/bi_pack.c65
-rw-r--r--src/panfrost/bifrost/bifrost.h14
2 files changed, 77 insertions, 2 deletions
diff --git a/src/panfrost/bifrost/bi_pack.c b/src/panfrost/bifrost/bi_pack.c
index aa8d590c733..e884417476f 100644
--- a/src/panfrost/bifrost/bi_pack.c
+++ b/src/panfrost/bifrost/bi_pack.c
@@ -1063,8 +1063,71 @@ bi_pack_fma_cmp(bi_instruction *ins, struct bi_registers *regs)
unreachable("Unknown cmp type");
}
}
+
+static unsigned
+bi_fma_bitwise_op(enum bi_bitwise_op op, bool rshift)
+{
+ switch (op) {
+ case BI_BITWISE_OR:
+ /* Via De Morgan's */
+ return rshift ?
+ BIFROST_FMA_OP_RSHIFT_NAND :
+ BIFROST_FMA_OP_LSHIFT_NAND;
+ case BI_BITWISE_AND:
+ return rshift ?
+ BIFROST_FMA_OP_RSHIFT_AND :
+ BIFROST_FMA_OP_LSHIFT_AND;
+ case BI_BITWISE_XOR:
+ /* Shift direction handled out of band */
+ return BIFROST_FMA_OP_RSHIFT_XOR;
+ default:
+ unreachable("Unknown op");
+ }
+}
+static unsigned
+bi_pack_fma_bitwise(bi_instruction *ins, struct bi_registers *regs)
+{
+ unsigned size = nir_alu_type_get_type_size(ins->dest_type);
+ assert(size <= 32);
+
+ bool invert_0 = ins->bitwise.src_invert[0];
+ bool invert_1 = ins->bitwise.src_invert[1];
+ if (ins->op.bitwise == BI_BITWISE_OR) {
+ /* Becomes NAND, so via De Morgan's:
+ * f(A) | f(B) = ~(~f(A) & ~f(B))
+ * = NAND(~f(A), ~f(B))
+ */
+
+ invert_0 = !invert_0;
+ invert_1 = !invert_1;
+ } else if (ins->op.bitwise == BI_BITWISE_XOR) {
+ /* ~A ^ ~B = ~(A ^ ~B) = ~(~(A ^ B)) = A ^ B
+ * ~A ^ B = ~(A ^ B) = A ^ ~B
+ */
+
+ invert_0 ^= invert_1;
+ invert_1 = false;
+
+ /* invert_1 ends up specifying shift direction */
+ invert_1 = !ins->bitwise.rshift;
+ }
+
+ struct bifrost_shift_fma pack = {
+ .src0 = bi_get_src(ins, regs, 0, true),
+ .src1 = bi_get_src(ins, regs, 1, true),
+ .src2 = bi_get_src(ins, regs, 2, true),
+ .half = (size == 32) ? 0 : (size == 16) ? 0x7 : (size == 8) ? 0x4 : 0,
+ .unk = 1, /* XXX */
+ .invert_1 = invert_0,
+ .invert_2 = invert_1,
+ .op = bi_fma_bitwise_op(ins->op.bitwise, ins->bitwise.rshift)
+ };
+
+ RETURN_PACKED(pack);
+}
+
static unsigned
bi_pack_fma(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs)
{
@@ -1077,7 +1140,7 @@ bi_pack_fma(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs)
case BI_CMP:
return bi_pack_fma_cmp(bundle.fma, regs);
case BI_BITWISE:
- return BIFROST_FMA_NOP;
+ return bi_pack_fma_bitwise(bundle.fma, regs);
case BI_CONVERT:
return bi_pack_convert(bundle.fma, regs, true);
case BI_CSEL:
diff --git a/src/panfrost/bifrost/bifrost.h b/src/panfrost/bifrost/bifrost.h
index bef8cd84f00..bfbaa2c2e56 100644
--- a/src/panfrost/bifrost/bifrost.h
+++ b/src/panfrost/bifrost/bifrost.h
@@ -363,11 +363,23 @@ struct bifrost_csel4 {
unsigned op : 8;
} __attribute__((packed));
+#define BIFROST_FMA_OP_RSHIFT_NAND (0x60000 >> 12)
+#define BIFROST_FMA_OP_RSHIFT_AND (0x61000 >> 12)
+#define BIFROST_FMA_OP_LSHIFT_NAND (0x62000 >> 12)
+#define BIFROST_FMA_OP_LSHIFT_AND (0x63000 >> 12)
+#define BIFROST_FMA_OP_RSHIFT_XOR (0x64000 >> 12)
+#define BIFROST_FMA_OP_LSHIFT_ADD_32 (0x65200 >> 6)
+#define BIFROST_FMA_OP_LSHIFT_SUB_32 (0x65600 >> 6)
+#define BIFROST_FMA_OP_LSHIFT_RSUB_32 (0x65a00 >> 6)
+#define BIFROST_FMA_OP_RSHIFT_ADD_32 (0x65e00 >> 6)
+#define BIFROST_FMA_OP_RSHIFT_SUB_32 (0x66200 >> 6)
+#define BIFROST_FMA_OP_RSHIFT_RSUB_32 (0x66600 >> 6)
+
struct bifrost_shift_fma {
unsigned src0 : 3;
unsigned src1 : 3;
unsigned src2 : 3;
- unsigned half : 3; /* 000 for i32, 100 for i8, 111 for v2i16 */
+ unsigned half : 3;
unsigned unk : 1; /* always set? */
unsigned invert_1 : 1; /* Inverts sources to combining op */
/* For XOR, switches RSHIFT to LSHIFT since only one invert needed */