From: Alyssa Rosenzweig Date: Mon, 6 Apr 2020 17:27:12 +0000 (-0400) Subject: pan/bi: Implement min/max on FMA X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f6bd0ec907a6fe61638046bd1286c7b3548fecbd;p=mesa.git pan/bi: Implement min/max on FMA Unfortunately, while this looks fine to the disasm, it's raising INSTR_INVALID_ENC on my g31 board here. Looks like it might be ADD only on newer Bifrost. Signed-off-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/panfrost/bifrost/bi_pack.c b/src/panfrost/bifrost/bi_pack.c index 81f149cf562..648e6932915 100644 --- a/src/panfrost/bifrost/bi_pack.c +++ b/src/panfrost/bifrost/bi_pack.c @@ -525,8 +525,13 @@ bi_pack_fma_fma(bi_instruction *ins, struct bi_registers *regs) } static unsigned -bi_pack_fma_add_f32(bi_instruction *ins, struct bi_registers *regs) +bi_pack_fma_addmin_f32(bi_instruction *ins, struct bi_registers *regs) { + unsigned op = + (ins->type == BI_ADD) ? BIFROST_FMA_OP_FADD32 : + (ins->op.minmax == BI_MINMAX_MIN) ? BIFROST_FMA_OP_FMIN32 : + BIFROST_FMA_OP_FMAX32; + struct bifrost_fma_add pack = { .src0 = bi_get_src(ins, regs, 0, true), .src1 = bi_get_src(ins, regs, 1, true), @@ -536,8 +541,8 @@ bi_pack_fma_add_f32(bi_instruction *ins, struct bi_registers *regs) .src1_neg = ins->src_neg[1], .unk = 0x0, .outmod = ins->outmod, - .roundmode = ins->roundmode, - .op = BIFROST_FMA_OP_FADD32 + .roundmode = (ins->type == BI_ADD) ? ins->roundmode : ins->minmax, + .op = op }; RETURN_PACKED(pack); @@ -613,10 +618,10 @@ bi_pack_fma_addmin_f16(bi_instruction *ins, struct bi_registers *regs) } static unsigned -bi_pack_fma_add(bi_instruction *ins, struct bi_registers *regs) +bi_pack_fma_addmin(bi_instruction *ins, struct bi_registers *regs) { if (ins->dest_type == nir_type_float32) - return bi_pack_fma_add_f32(ins, regs); + return bi_pack_fma_addmin_f32(ins, regs); else if(ins->dest_type == nir_type_float16) return bi_pack_fma_addmin_f16(ins, regs); else @@ -794,7 +799,7 @@ bi_pack_fma(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs) switch (bundle.fma->type) { case BI_ADD: - return bi_pack_fma_add(bundle.fma, regs); + return bi_pack_fma_addmin(bundle.fma, regs); case BI_CMP: case BI_BITWISE: return BIFROST_FMA_NOP; @@ -806,8 +811,9 @@ bi_pack_fma(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs) return bi_pack_fma_fma(bundle.fma, regs); case BI_FREXP: case BI_ISUB: - case BI_MINMAX: return BIFROST_FMA_NOP; + case BI_MINMAX: + return bi_pack_fma_addmin(bundle.fma, regs); case BI_MOV: return bi_pack_fma_1src(bundle.fma, regs, BIFROST_FMA_OP_MOV); case BI_SHIFT: diff --git a/src/panfrost/bifrost/bifrost.h b/src/panfrost/bifrost/bifrost.h index 602788a7225..db173bb0645 100644 --- a/src/panfrost/bifrost/bifrost.h +++ b/src/panfrost/bifrost/bifrost.h @@ -201,6 +201,8 @@ enum bifrost_minmax_mode { }; #define BIFROST_FMA_OP_FADD32 (0x58 >> 2) +#define BIFROST_FMA_OP_FMAX32 (0x40 >> 2) +#define BIFROST_FMA_OP_FMIN32 (0x44 >> 2) struct bifrost_fma_add { unsigned src0 : 3;