return bi_pack_fma_2src(ins, regs, op);
}
+static unsigned
+bi_pack_fma_imul(bi_instruction *ins, bi_registers *regs)
+{
+ assert(ins->op.imul == BI_IMUL_IMUL);
+ unsigned op = BIFROST_FMA_IMUL_32;
+ return bi_pack_fma_2src(ins, regs, op);
+}
+
static unsigned
bi_pack_fma(bi_clause *clause, bi_bundle bundle, bi_registers *regs)
{
return bi_pack_fma_round(bundle.fma, regs);
case BI_REDUCE_FMA:
return bi_pack_fma_reduce(bundle.fma, regs);
+ case BI_IMUL:
+ return bi_pack_fma_imul(bundle.fma, regs);
default:
unreachable("Cannot encode class as FMA");
}
case BI_TABLE: return "table";
case BI_TEX: return "tex";
case BI_ROUND: return "round";
+ case BI_IMUL: return "imul";
default: return "unknown_class";
}
}
[BI_SELECT] = BI_SCHED_ALL | BI_SWIZZLABLE,
[BI_TEX] = BI_SCHED_HI_LATENCY | BI_SCHED_ADD | BI_VECTOR | BI_DATA_REG_DEST,
[BI_ROUND] = BI_ROUNDMODE | BI_SCHED_ALL,
+ [BI_IMUL] = BI_SCHED_FMA,
};
#define BIFROST_FMA_IADD_32 (0x4ff98 >> 3)
#define BIFROST_FMA_ISUB_32 (0x4ffd8 >> 3)
+#define BIFROST_FMA_IMUL_32 ((BIFROST_FMA_EXT | 0x7818) >> 3)
struct bifrost_fma_2src {
unsigned src0 : 3;
case nir_op_isub:
return BI_IMATH;
+ case nir_op_imul:
+ return BI_IMUL;
+
case nir_op_iand:
case nir_op_ior:
case nir_op_ixor:
alu.src_types[2] = alu.src_types[1];
alu.src[1] = BIR_INDEX_ZERO;
break;
+ case nir_op_imul:
+ alu.op.imul = BI_IMUL_IMUL;
+ break;
case nir_op_fmax:
case nir_op_imax:
case nir_op_umax:
BI_TABLE,
BI_TEX,
BI_ROUND,
+ BI_IMUL,
BI_NUM_CLASSES
};
BI_IMATH_SUB,
};
+enum bi_imul_op {
+ BI_IMUL_IMUL,
+};
+
enum bi_table_op {
/* fp32 log2() with low precision, suitable for GL or half_log2() in
* CL. In the first argument, takes x. Letting u be such that x =
enum bi_frexp_op frexp;
enum bi_tex_op texture;
enum bi_imath_op imath;
+ enum bi_imul_op imul;
/* For FMA/ADD, should we add a biased exponent? */
bool mscale;