pan/bi: Use src1/dest_invert instead of src_invert[]

This maps more closely to the hardware, which makes for easier packing.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6749>
diff --git a/src/panfrost/bifrost/bi_pack.c b/src/panfrost/bifrost/bi_pack.c
index 2c30017..b16a670 100644
--- a/src/panfrost/bifrost/bi_pack.c
+++ b/src/panfrost/bifrost/bi_pack.c
@@ -1078,8 +1078,22 @@
         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];
+        bool invert_1 = ins->bitwise.src1_invert;
+        bool invert_0 = false;
+
+        if (ins->bitwise.dest_invert) {
+                if (ins->op.bitwise == BI_BITWISE_OR) {
+                        ins->op.bitwise = BI_BITWISE_AND;
+                        invert_0 = true;
+                        invert_1 = !invert_1;
+                } else if (ins->op.bitwise == BI_BITWISE_AND) {
+                        ins->op.bitwise = BI_BITWISE_OR;
+                        invert_0 = true;
+                        invert_1 = !invert_1;
+                } else {
+                        invert_1 = !invert_1;
+                }
+        }
 
         if (ins->op.bitwise == BI_BITWISE_OR) {
                 /* Becomes NAND, so via De Morgan's:
diff --git a/src/panfrost/bifrost/bi_print.c b/src/panfrost/bifrost/bi_print.c
index 56e83be..2b5dd8c 100644
--- a/src/panfrost/bifrost/bi_print.c
+++ b/src/panfrost/bifrost/bi_print.c
@@ -123,11 +123,14 @@
         if (abs)
                 fprintf(fp, "abs(");
 
-        if (ins->type == BI_BITWISE && ins->bitwise.src_invert[s])
-                fprintf(fp, "~");
-
         bi_print_index(fp, ins, src, s);
 
+        if (ins->type == BI_BITWISE && s == 1 && ins->bitwise.src1_invert) {
+                /* For XOR, just use the destination invert */
+                assert(ins->op.bitwise != BI_BITWISE_XOR);
+                fprintf(fp, ".not");
+        }
+
         if (abs)
                 fprintf(fp, ")");
 }
@@ -303,6 +306,9 @@
         if (bi_class_props[ins->type] & BI_ROUNDMODE)
                 fprintf(fp, "%s", bi_round_mode_name(ins->roundmode));
 
+        if (ins->type == BI_BITWISE && ins->bitwise.dest_invert)
+                fprintf(fp, ".not");
+
         fprintf(fp, " ");
         ASSERTED bool succ = bi_print_dest_index(fp, ins, ins->dest);
         assert(succ);
diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c
index afe2c00..0ae2176 100644
--- a/src/panfrost/bifrost/bifrost_compile.c
+++ b/src/panfrost/bifrost/bifrost_compile.c
@@ -825,9 +825,9 @@
                 alu.op.special = BI_SPECIAL_IABS;
                 break;
         case nir_op_inot:
-                /* no dedicated bitwise not, but we can invert sources. convert to ~a | 0 */
+                /* no dedicated bitwise not, but we can invert sources. convert to ~(a | 0) */
                 alu.op.bitwise = BI_BITWISE_OR;
-                alu.bitwise.src_invert[0] = true;
+                alu.bitwise.dest_invert = true;
                 alu.src[1] = BIR_INDEX_ZERO;
                 /* zero shift */
                 alu.src[2] = BIR_INDEX_ZERO;
diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h
index b986a12..6f0578a 100644
--- a/src/panfrost/bifrost/compiler.h
+++ b/src/panfrost/bifrost/compiler.h
@@ -237,7 +237,8 @@
 };
 
 struct bi_bitwise {
-        bool src_invert[2];
+        bool dest_invert;
+        bool src1_invert;
         bool rshift; /* false for lshift */
 };
 
diff --git a/src/panfrost/bifrost/test/bi_interpret.c b/src/panfrost/bifrost/test/bi_interpret.c
index 2a84487..90d779d 100644
--- a/src/panfrost/bifrost/test/bi_interpret.c
+++ b/src/panfrost/bifrost/test/bi_interpret.c
@@ -456,10 +456,7 @@
 
         case BI_BITWISE: {
                 /* Apply inverts first */
-                if (ins->bitwise.src_invert[0])
-                        srcs[0].u64 = ~srcs[0].u64;
-
-                if (ins->bitwise.src_invert[1])
+                if (ins->bitwise.src1_invert)
                         srcs[1].u64 = ~srcs[1].u64;
 
                 /* TODO: Shifting */
@@ -474,6 +471,9 @@
                 else
                         unreachable("Unsupported op");
 
+                if (ins->bitwise.dest_invert)
+                        dest.u64 = ~dest.u64;
+
                 break;
          }
 
diff --git a/src/panfrost/bifrost/test/bi_test_pack.c b/src/panfrost/bifrost/test/bi_test_pack.c
index 865f71f..d30c585 100644
--- a/src/panfrost/bifrost/test/bi_test_pack.c
+++ b/src/panfrost/bifrost/test/bi_test_pack.c
@@ -548,8 +548,13 @@
                 ins.op.bitwise = op;
 
                 for (unsigned mods = 0; mods < 4; ++mods) {
-                        ins.bitwise.src_invert[0] = mods & 1;
-                        ins.bitwise.src_invert[1] = mods & 2;
+                        ins.bitwise.dest_invert = mods & 1;
+                        ins.bitwise.src1_invert = mods & 2;
+
+                        /* Skip out-of-spec combinations */
+                        if (ins.bitwise.src1_invert && op == BI_BITWISE_XOR)
+                                continue;
+
                         bit_test_single(dev, &ins, input, true, debug);
                 }
         }