<mod name="abs1" start="15" size="1" opt="abs"/>
</ins>
+ <ins name="*FABSNEG.f32" pseudo="true">
+ <src start="0" mask="0xfb"/>
+ <mod name="neg0" start="7" size="1" opt="neg"/>
+ <mod name="abs0" start="12" size="1" opt="abs"/>
+ <mod name="widen0" size="2">
+ <opt>none</opt>
+ <opt>h0</opt>
+ <opt>h1</opt>
+ </mod>
+ </ins>
+
+ <ins name="*FABSNEG.v2f16" pseudo="true">
+ <src start="0" mask="0xfb"/>
+ <mod name="abs0" size="1" opt="abs"/>
+ <mod name="neg0" start="7" size="1" opt="neg"/>
+ <mod name="swz0" start="9" size="2" default="h01">
+ <opt>h00</opt>
+ <opt>h10</opt>
+ <opt>h01</opt>
+ <opt>h11</opt>
+ </mod>
+ </ins>
+
</bifrost>
}
static bool
-bi_is_fabsneg(bi_instr *I)
+bi_is_fabsneg(enum bi_opcode op, enum bi_size size)
{
- return (I->op == BI_OPCODE_FADD_F32 || I->op == BI_OPCODE_FADD_V2F16) &&
- (I->src[1].type == BI_INDEX_CONSTANT && I->src[1].value == 0) &&
- (I->clamp == BI_CLAMP_NONE);
+ return (size == BI_SIZE_32 && op == BI_OPCODE_FABSNEG_F32) ||
+ (size == BI_SIZE_16 && op == BI_OPCODE_FABSNEG_V2F16);
}
static enum bi_swizzle
if (!mod)
continue;
- if (bi_opcode_props[mod->op].size != bi_opcode_props[I->op].size)
- continue;
+ unsigned size = bi_opcode_props[I->op].size;
- if (bi_is_fabsneg(mod)) {
+ if (bi_is_fabsneg(mod->op, size)) {
if (mod->src[0].abs && !bi_takes_fabs(ctx->arch, I, mod->src[0], s))
continue;
free(uses);
free(multiple);
}
+
+/** Lower pseudo instructions that exist to simplify the optimizer */
+
+void
+bi_lower_opt_instruction(bi_instr *I)
+{
+ switch (I->op) {
+ case BI_OPCODE_FABSNEG_F32:
+ case BI_OPCODE_FABSNEG_V2F16:
+ I->op = (bi_opcode_props[I->op].size == BI_SIZE_32) ?
+ BI_OPCODE_FADD_F32 : BI_OPCODE_FADD_V2F16;
+
+ I->round = BI_ROUND_NONE;
+ I->src[1] = bi_negzero();
+ break;
+
+ default:
+ break;
+ }
+}
}
case nir_op_fneg:
- bi_fadd_to(b, sz, dst, bi_neg(s0), bi_negzero(), BI_ROUND_NONE);
+ bi_fabsneg_to(b, sz, dst, bi_neg(s0));
break;
case nir_op_fabs:
- bi_fadd_to(b, sz, dst, bi_abs(s0), bi_negzero(), BI_ROUND_NONE);
+ bi_fabsneg_to(b, sz, dst, bi_abs(s0));
break;
case nir_op_fsin:
bi_validate(ctx, "Optimization passes");
}
+ bi_foreach_instr_global(ctx, I) {
+ bi_lower_opt_instruction(I);
+ }
+
bi_foreach_block(ctx, block) {
bi_lower_branch(block);
}
void bi_assign_scoreboard(bi_context *ctx);
void bi_register_allocate(bi_context *ctx);
+void bi_lower_opt_instruction(bi_instr *I);
+
void bi_schedule(bi_context *ctx);
bool bi_can_fma(bi_instr *ins);
bool bi_can_add(bi_instr *ins);