pan/bi: Pack csel4 opcodes
These are pretty straightforward but there's a lot of details to keep straight. In the IR, we keep a general logical comparator and types separately; in the hardware, the type gets fused with a (much more) limited number of comparators. So there's a fair bit of code here to account for these differences, fusing in the type information, and changing up argument order as necessary to make it actually correct. Anything to save a bit! Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4276> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4276>
This commit is contained in:
committed by
Marge Bot
parent
5cdc31abd6
commit
d9d549ff88
@@ -475,6 +475,81 @@ bi_pack_fma_1src(bi_instruction *ins, struct bi_registers *regs, unsigned op)
|
||||
RETURN_PACKED(pack);
|
||||
}
|
||||
|
||||
static enum bifrost_csel_cond
|
||||
bi_cond_to_csel(enum bi_cond cond, bool *flip, bool *invert, nir_alu_type T)
|
||||
{
|
||||
nir_alu_type B = nir_alu_type_get_base_type(T);
|
||||
unsigned idx = (B == nir_type_float) ? 0 :
|
||||
((B == nir_type_int) ? 1 : 2);
|
||||
|
||||
switch (cond){
|
||||
case BI_COND_LT:
|
||||
*flip = true;
|
||||
case BI_COND_GT: {
|
||||
const enum bifrost_csel_cond ops[] = {
|
||||
BIFROST_FGT_F,
|
||||
BIFROST_IGT_I,
|
||||
BIFROST_UGT_I
|
||||
};
|
||||
|
||||
return ops[idx];
|
||||
}
|
||||
case BI_COND_LE:
|
||||
*flip = true;
|
||||
case BI_COND_GE: {
|
||||
const enum bifrost_csel_cond ops[] = {
|
||||
BIFROST_FGE_F,
|
||||
BIFROST_IGE_I,
|
||||
BIFROST_UGE_I
|
||||
};
|
||||
|
||||
return ops[idx];
|
||||
}
|
||||
case BI_COND_NE:
|
||||
*invert = true;
|
||||
case BI_COND_EQ: {
|
||||
const enum bifrost_csel_cond ops[] = {
|
||||
BIFROST_FEQ_F,
|
||||
BIFROST_IEQ_F,
|
||||
BIFROST_IEQ_F /* sign is irrelevant */
|
||||
};
|
||||
|
||||
return ops[idx];
|
||||
}
|
||||
default:
|
||||
unreachable("Invalid op for csel");
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
bi_pack_fma_csel(bi_instruction *ins, struct bi_registers *regs)
|
||||
{
|
||||
/* TODO: Use csel3 as well */
|
||||
bool flip = false, invert = false;
|
||||
|
||||
enum bifrost_csel_cond cond =
|
||||
bi_cond_to_csel(ins->csel_cond, &flip, &invert, ins->src_types[0]);
|
||||
|
||||
unsigned size = nir_alu_type_get_type_size(ins->dest_type);
|
||||
|
||||
unsigned cmp_0 = (flip ? 3 : 0);
|
||||
unsigned cmp_1 = (flip ? 0 : 3);
|
||||
unsigned res_0 = (invert ? 2 : 1);
|
||||
unsigned res_1 = (invert ? 1 : 2);
|
||||
|
||||
struct bifrost_csel4 pack = {
|
||||
.src0 = bi_get_src(ins, regs, cmp_0, true),
|
||||
.src1 = bi_get_src(ins, regs, cmp_1, true),
|
||||
.src2 = bi_get_src(ins, regs, res_0, true),
|
||||
.src3 = bi_get_src(ins, regs, res_1, true),
|
||||
.cond = cond,
|
||||
.op = (size == 16) ? BIFROST_FMA_OP_CSEL4_V16 :
|
||||
BIFROST_FMA_OP_CSEL4
|
||||
};
|
||||
|
||||
RETURN_PACKED(pack);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
bi_pack_fma(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs)
|
||||
{
|
||||
@@ -487,8 +562,9 @@ bi_pack_fma(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs)
|
||||
case BI_CMP:
|
||||
case BI_BITWISE:
|
||||
case BI_CONVERT:
|
||||
case BI_CSEL:
|
||||
return BIFROST_FMA_NOP;
|
||||
case BI_CSEL:
|
||||
return bi_pack_fma_csel(bundle.fma, regs);
|
||||
case BI_FMA:
|
||||
return bi_pack_fma_fma(bundle.fma, regs);
|
||||
case BI_FREXP:
|
||||
|
||||
@@ -230,6 +230,9 @@ enum bifrost_csel_cond {
|
||||
BIFROST_UGE_I = 0x7
|
||||
};
|
||||
|
||||
#define BIFROST_FMA_OP_CSEL4 (0x5c)
|
||||
#define BIFROST_FMA_OP_CSEL4_V16 (0xdc)
|
||||
|
||||
struct bifrost_csel4 {
|
||||
unsigned src0 : 3;
|
||||
unsigned src1 : 3;
|
||||
|
||||
Reference in New Issue
Block a user