From d2158a5b3016bf4e6593ba4f0fc4de653323bf87 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 9 Sep 2020 17:46:58 -0400 Subject: [PATCH] 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 Reviewed-by: Daniel Stone Part-of: --- src/panfrost/bifrost/bi_pack.c | 18 ++++++++++++++++-- src/panfrost/bifrost/bi_print.c | 12 +++++++++--- src/panfrost/bifrost/bifrost_compile.c | 4 ++-- src/panfrost/bifrost/compiler.h | 3 ++- src/panfrost/bifrost/test/bi_interpret.c | 8 ++++---- src/panfrost/bifrost/test/bi_test_pack.c | 9 +++++++-- 6 files changed, 40 insertions(+), 14 deletions(-) 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 @@ bi_pack_fma_bitwise(bi_instruction *ins, 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]; + 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 @@ bi_print_src(FILE *fp, bi_instruction *ins, unsigned s) 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 @@ bi_print_instruction(bi_instruction *ins, FILE *fp) 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 @@ emit_alu(bi_context *ctx, nir_alu_instr *instr) 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 @@ enum bi_tex_op { }; 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 @@ bit_step(struct bit_state *s, bi_instruction *ins, bool FMA) 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 @@ bit_step(struct bit_state *s, bi_instruction *ins, bool FMA) 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 @@ bit_bitwise_helper(struct panfrost_device *dev, uint32_t *input, unsigned size, 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); } } -- 2.7.4