}
}
-/* Being a little silly with the names, but returns the op that is the bitwise
- * inverse of the op with the argument switched. I.e. (f and g are
- * contrapositives):
- *
- * f(a, b) = ~g(b, a)
- *
- * Corollary: if g is the contrapositve of f, f is the contrapositive of g:
- *
- * f(a, b) = ~g(b, a)
- * ~f(a, b) = g(b, a)
- * ~f(a, b) = ~h(a, b) where h is the contrapositive of g
- * f(a, b) = h(a, b)
- *
- * Thus we define this function in pairs.
- */
-
-static inline midgard_alu_op
-mir_contrapositive(midgard_alu_op op)
-{
- switch (op) {
- case midgard_alu_op_flt:
- return midgard_alu_op_fle;
- case midgard_alu_op_fle:
- return midgard_alu_op_flt;
-
- case midgard_alu_op_ilt:
- return midgard_alu_op_ile;
- case midgard_alu_op_ile:
- return midgard_alu_op_ilt;
-
- default:
- unreachable("No known contrapositive");
- }
-}
-
/* Midgard supports two types of constants, embedded constants (128-bit) and
* inline constants (16-bit). Sometimes, especially with scalar ops, embedded
* constants can be demoted to inline constants, for space savings and
bool flip = alu_opcode_props[op].props & OP_COMMUTES;
switch (op) {
- /* Conditionals can be inverted */
- case midgard_alu_op_flt:
- case midgard_alu_op_ilt:
- case midgard_alu_op_fle:
- case midgard_alu_op_ile:
- ins->alu.op = mir_contrapositive(ins->alu.op);
- ins->invert = true;
- flip = true;
- break;
-
case midgard_alu_op_fcsel:
case midgard_alu_op_icsel:
DBG("Missed non-commutative flip (%s)\n", alu_opcode_props[op].name);
for op in SPECIAL:
converts += [((op + '@16', a), ('f2f16', (op, ('f2f32', a))))]
+# Try to force constants to the right
+constant_switch = [
+ # fge gets flipped to fle, so we invert to keep the order
+ (('fge', 'a', '#b'), (('inot', ('flt', a, b)))),
+ (('fge32', 'a', '#b'), (('inot', ('flt32', a, b)))),
+ (('ige32', 'a', '#b'), (('inot', ('ilt32', a, b)))),
+ (('uge32', 'a', '#b'), (('inot', ('ult32', a, b)))),
+
+ # fge gets mapped to fle with a flip
+ (('flt32', '#a', 'b'), ('inot', ('fge32', a, b))),
+ (('ilt32', '#a', 'b'), ('inot', ('ige32', a, b))),
+ (('ult32', '#a', 'b'), ('inot', ('uge32', a, b)))
+]
+
# Midgard scales fsin/fcos arguments by pi.
# Pass must be run only once, after the main loop
print('#include "midgard_nir.h"')
print(nir_algebraic.AlgebraicPass("midgard_nir_lower_algebraic_late",
- algebraic_late + converts).render())
+ algebraic_late + converts + constant_switch).render())
print(nir_algebraic.AlgebraicPass("midgard_nir_scale_trig",
scale_trig).render())