diff options
author | Alyssa Rosenzweig <[email protected]> | 2020-04-28 12:27:34 -0400 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-04-28 17:17:48 +0000 |
commit | c94d41ad7c92a9549e16f733dcb6a0a0762e811f (patch) | |
tree | 803b0d2233a969230761e528030234d3c21335ff /src/panfrost/bifrost | |
parent | 1520131d82812c815a08e322d182f7f2dc84f627 (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.c | 82 | ||||
-rw-r--r-- | src/panfrost/bifrost/bifrost.h | 3 |
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; |