Mesa (master): pan/bi: Pack BI_BITWISE

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Apr 29 00:40:40 UTC 2020


Module: Mesa
Branch: master
Commit: ef9582738e5950764dcd33eddef7183e5529e5ff
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ef9582738e5950764dcd33eddef7183e5529e5ff

Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date:   Tue Apr 28 14:19:34 2020 -0400

pan/bi: Pack BI_BITWISE

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4790>

---

 src/panfrost/bifrost/bi_pack.c | 65 +++++++++++++++++++++++++++++++++++++++++-
 src/panfrost/bifrost/bifrost.h | 14 ++++++++-
 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 */



More information about the mesa-commit mailing list