#include "nir_search_helpers.h"
#include "sfn/sfn_nir.h"

#include "nir.h"
#include "nir_builder.h"
#include "nir_search.h"
#include "nir_search_helpers.h"

/* What follows is NIR algebraic transform code for the following 22
 * transforms:
 *    ('inot', ('flt', 'a(is_a_number)', 'b(is_a_number)')) => ('fge', 'a', 'b')
 *    ('inot', ('fge', 'a(is_a_number)', 'b(is_a_number)')) => ('flt', 'a', 'b')
 *    ('inot', ('fneu', 'a', 'b')) => ('feq', 'a', 'b')
 *    ('inot', ('feq', 'a', 'b')) => ('fneu', 'a', 'b')
 *    ('inot', ('ilt', 'a', 'b')) => ('ige', 'a', 'b')
 *    ('inot', ('ige', 'a', 'b')) => ('ilt', 'a', 'b')
 *    ('inot', ('ult', 'a', 'b')) => ('uge', 'a', 'b')
 *    ('inot', ('uge', 'a', 'b')) => ('ult', 'a', 'b')
 *    ('inot', ('ieq', 'a', 'b')) => ('ine', 'a', 'b')
 *    ('inot', ('ine', 'a', 'b')) => ('ieq', 'a', 'b')
 *    ('b2f32', ('fge', 'a@32', 'b@32')) => ('sge', 'a', 'b')
 *    ('b2f32', ('flt', 'a@32', 'b@32')) => ('slt', 'a', 'b')
 *    ('b2f32', ('feq', 'a@32', 'b@32')) => ('seq', 'a', 'b')
 *    ('b2f32', ('fneu', 'a@32', 'b@32')) => ('sne', 'a', 'b')
 *    ('flt', ('fadd', 'a', 'b'), 0.0) => ('flt', 'a', ('fneg', 'b'))
 *    ('flt', 0.0, ('fadd', 'a', 'b')) => ('flt', ('fneg', 'b'), 'a')
 *    ('slt', ('fadd', 'a', 'b'), 0.0) => ('slt', 'a', ('fneg', 'b'))
 *    ('slt', 0.0, ('fadd', 'a', 'b')) => ('slt', ('fneg', 'b'), 'a')
 *    ('sge', ('fadd', 'a', 'b'), 0.0) => ('sge', 'a', ('fneg', 'b'))
 *    ('sge', 0.0, ('fadd', 'a', 'b')) => ('sge', ('fneg', 'b'), 'a')
 *    ('seq', ('fadd', 'a', 'b'), 0.0) => ('seq', 'a', ('fneg', 'b'))
 *    ('sne', ('fadd', 'a', 'b'), 0.0) => ('sne', 'a', ('fneg', 'b'))
 */


static const nir_search_value_union r600_sfn_lower_alu_values[] = {
   /* ('inot', ('flt', 'a(is_a_number)', 'b(is_a_number)')) => ('fge', 'a', 'b') */
   { .variable = {
      { nir_search_value_variable, -2 },
      0, /* a */
      false,
      nir_type_invalid,
      0,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, -2 },
      1, /* b */
      false,
      nir_type_invalid,
      0,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_flt,
      -1, 0,
      { 0, 1 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 0,
      { 2 },
      -1,
   } },

   { .variable = {
      { nir_search_value_variable, -2 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, -2 },
      1, /* b */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_fge,
      -1, 0,
      { 4, 5 },
      -1,
   } },

   /* ('inot', ('fge', 'a(is_a_number)', 'b(is_a_number)')) => ('flt', 'a', 'b') */
   /* search1_0_0 -> 0 in the cache */
   /* search1_0_1 -> 1 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_fge,
      -1, 0,
      { 0, 1 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 0,
      { 7 },
      -1,
   } },

   /* replace1_0 -> 4 in the cache */
   /* replace1_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_flt,
      -1, 0,
      { 4, 5 },
      -1,
   } },

   /* ('inot', ('fneu', 'a', 'b')) => ('feq', 'a', 'b') */
   /* search2_0_0 -> 4 in the cache */
   /* search2_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_fneu,
      0, 1,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 1,
      { 10 },
      -1,
   } },

   /* replace2_0 -> 4 in the cache */
   /* replace2_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_feq,
      0, 1,
      { 4, 5 },
      -1,
   } },

   /* ('inot', ('feq', 'a', 'b')) => ('fneu', 'a', 'b') */
   /* search3_0_0 -> 4 in the cache */
   /* search3_0_1 -> 5 in the cache */
   /* search3_0 -> 12 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 1,
      { 12 },
      -1,
   } },

   /* replace3_0 -> 4 in the cache */
   /* replace3_1 -> 5 in the cache */
   /* replace3 -> 10 in the cache */

   /* ('inot', ('ilt', 'a', 'b')) => ('ige', 'a', 'b') */
   /* search4_0_0 -> 4 in the cache */
   /* search4_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_ilt,
      -1, 0,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 0,
      { 14 },
      -1,
   } },

   /* replace4_0 -> 4 in the cache */
   /* replace4_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_ige,
      -1, 0,
      { 4, 5 },
      -1,
   } },

   /* ('inot', ('ige', 'a', 'b')) => ('ilt', 'a', 'b') */
   /* search5_0_0 -> 4 in the cache */
   /* search5_0_1 -> 5 in the cache */
   /* search5_0 -> 16 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 0,
      { 16 },
      -1,
   } },

   /* replace5_0 -> 4 in the cache */
   /* replace5_1 -> 5 in the cache */
   /* replace5 -> 14 in the cache */

   /* ('inot', ('ult', 'a', 'b')) => ('uge', 'a', 'b') */
   /* search6_0_0 -> 4 in the cache */
   /* search6_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_ult,
      -1, 0,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 0,
      { 18 },
      -1,
   } },

   /* replace6_0 -> 4 in the cache */
   /* replace6_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_uge,
      -1, 0,
      { 4, 5 },
      -1,
   } },

   /* ('inot', ('uge', 'a', 'b')) => ('ult', 'a', 'b') */
   /* search7_0_0 -> 4 in the cache */
   /* search7_0_1 -> 5 in the cache */
   /* search7_0 -> 20 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 0,
      { 20 },
      -1,
   } },

   /* replace7_0 -> 4 in the cache */
   /* replace7_1 -> 5 in the cache */
   /* replace7 -> 18 in the cache */

   /* ('inot', ('ieq', 'a', 'b')) => ('ine', 'a', 'b') */
   /* search8_0_0 -> 4 in the cache */
   /* search8_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_ieq,
      0, 1,
      { 4, 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 1,
      { 22 },
      -1,
   } },

   /* replace8_0 -> 4 in the cache */
   /* replace8_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_ine,
      0, 1,
      { 4, 5 },
      -1,
   } },

   /* ('inot', ('ine', 'a', 'b')) => ('ieq', 'a', 'b') */
   /* search9_0_0 -> 4 in the cache */
   /* search9_0_1 -> 5 in the cache */
   /* search9_0 -> 24 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_inot,
      -1, 1,
      { 24 },
      -1,
   } },

   /* replace9_0 -> 4 in the cache */
   /* replace9_1 -> 5 in the cache */
   /* replace9 -> 22 in the cache */

   /* ('b2f32', ('fge', 'a@32', 'b@32')) => ('sge', 'a', 'b') */
   { .variable = {
      { nir_search_value_variable, 32 },
      0, /* a */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .variable = {
      { nir_search_value_variable, 32 },
      1, /* b */
      false,
      nir_type_invalid,
      -1,
      {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_fge,
      -1, 0,
      { 26, 27 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_b2f32,
      -1, 0,
      { 28 },
      -1,
   } },

   /* replace10_0 -> 26 in the cache */
   /* replace10_1 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_sge,
      -1, 0,
      { 26, 27 },
      -1,
   } },

   /* ('b2f32', ('flt', 'a@32', 'b@32')) => ('slt', 'a', 'b') */
   /* search11_0_0 -> 26 in the cache */
   /* search11_0_1 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_flt,
      -1, 0,
      { 26, 27 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_b2f32,
      -1, 0,
      { 31 },
      -1,
   } },

   /* replace11_0 -> 26 in the cache */
   /* replace11_1 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_slt,
      -1, 0,
      { 26, 27 },
      -1,
   } },

   /* ('b2f32', ('feq', 'a@32', 'b@32')) => ('seq', 'a', 'b') */
   /* search12_0_0 -> 26 in the cache */
   /* search12_0_1 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_feq,
      0, 1,
      { 26, 27 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_b2f32,
      -1, 1,
      { 34 },
      -1,
   } },

   /* replace12_0 -> 26 in the cache */
   /* replace12_1 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_seq,
      0, 1,
      { 26, 27 },
      -1,
   } },

   /* ('b2f32', ('fneu', 'a@32', 'b@32')) => ('sne', 'a', 'b') */
   /* search13_0_0 -> 26 in the cache */
   /* search13_0_1 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_fneu,
      0, 1,
      { 26, 27 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_b2f32,
      -1, 1,
      { 37 },
      -1,
   } },

   /* replace13_0 -> 26 in the cache */
   /* replace13_1 -> 27 in the cache */
   { .expression = {
      { nir_search_value_expression, 32 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_sne,
      0, 1,
      { 26, 27 },
      -1,
   } },

   /* ('flt', ('fadd', 'a', 'b'), 0.0) => ('flt', 'a', ('fneg', 'b')) */
   /* search14_0_0 -> 4 in the cache */
   /* search14_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_fadd,
      0, 1,
      { 4, 5 },
      -1,
   } },
   { .constant = {
      { nir_search_value_constant, -2 },
      nir_type_float, { 0x0ull /* 0.0 */ },
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      true,
      -1,
      nir_op_flt,
      -1, 1,
      { 40, 41 },
      -1,
   } },

   /* replace14_0 -> 4 in the cache */
   /* replace14_1_0 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_fneg,
      -1, 0,
      { 5 },
      -1,
   } },
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_flt,
      -1, 0,
      { 4, 43 },
      -1,
   } },

   /* ('flt', 0.0, ('fadd', 'a', 'b')) => ('flt', ('fneg', 'b'), 'a') */
   /* search15_0 -> 41 in the cache */
   /* search15_1_0 -> 4 in the cache */
   /* search15_1_1 -> 5 in the cache */
   /* search15_1 -> 40 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_flt,
      -1, 1,
      { 41, 40 },
      -1,
   } },

   /* replace15_0_0 -> 5 in the cache */
   /* replace15_0 -> 43 in the cache */
   /* replace15_1 -> 4 in the cache */
   { .expression = {
      { nir_search_value_expression, 1 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_flt,
      -1, 0,
      { 43, 4 },
      -1,
   } },

   /* ('slt', ('fadd', 'a', 'b'), 0.0) => ('slt', 'a', ('fneg', 'b')) */
   /* search16_0_0 -> 4 in the cache */
   /* search16_0_1 -> 5 in the cache */
   /* search16_0 -> 40 in the cache */
   /* search16_1 -> 41 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      true,
      -1,
      nir_op_slt,
      -1, 1,
      { 40, 41 },
      -1,
   } },

   /* replace16_0 -> 4 in the cache */
   /* replace16_1_0 -> 5 in the cache */
   /* replace16_1 -> 43 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_slt,
      -1, 0,
      { 4, 43 },
      -1,
   } },

   /* ('slt', 0.0, ('fadd', 'a', 'b')) => ('slt', ('fneg', 'b'), 'a') */
   /* search17_0 -> 41 in the cache */
   /* search17_1_0 -> 4 in the cache */
   /* search17_1_1 -> 5 in the cache */
   /* search17_1 -> 40 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_slt,
      -1, 1,
      { 41, 40 },
      -1,
   } },

   /* replace17_0_0 -> 5 in the cache */
   /* replace17_0 -> 43 in the cache */
   /* replace17_1 -> 4 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_slt,
      -1, 0,
      { 43, 4 },
      -1,
   } },

   /* ('sge', ('fadd', 'a', 'b'), 0.0) => ('sge', 'a', ('fneg', 'b')) */
   /* search18_0_0 -> 4 in the cache */
   /* search18_0_1 -> 5 in the cache */
   /* search18_0 -> 40 in the cache */
   /* search18_1 -> 41 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      true,
      -1,
      nir_op_sge,
      -1, 1,
      { 40, 41 },
      -1,
   } },

   /* replace18_0 -> 4 in the cache */
   /* replace18_1_0 -> 5 in the cache */
   /* replace18_1 -> 43 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_sge,
      -1, 0,
      { 4, 43 },
      -1,
   } },

   /* ('sge', 0.0, ('fadd', 'a', 'b')) => ('sge', ('fneg', 'b'), 'a') */
   /* search19_0 -> 41 in the cache */
   /* search19_1_0 -> 4 in the cache */
   /* search19_1_1 -> 5 in the cache */
   /* search19_1 -> 40 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_sge,
      -1, 1,
      { 41, 40 },
      -1,
   } },

   /* replace19_0_0 -> 5 in the cache */
   /* replace19_0 -> 43 in the cache */
   /* replace19_1 -> 4 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_sge,
      -1, 0,
      { 43, 4 },
      -1,
   } },

   /* ('seq', ('fadd', 'a', 'b'), 0.0) => ('seq', 'a', ('fneg', 'b')) */
   /* search20_0_0 -> 4 in the cache */
   /* search20_0_1 -> 5 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_fadd,
      1, 1,
      { 4, 5 },
      -1,
   } },
   /* search20_1 -> 41 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      true,
      -1,
      nir_op_seq,
      0, 2,
      { 55, 41 },
      -1,
   } },

   /* replace20_0 -> 4 in the cache */
   /* replace20_1_0 -> 5 in the cache */
   /* replace20_1 -> 43 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_seq,
      0, 1,
      { 4, 43 },
      -1,
   } },

   /* ('sne', ('fadd', 'a', 'b'), 0.0) => ('sne', 'a', ('fneg', 'b')) */
   /* search21_0_0 -> 4 in the cache */
   /* search21_0_1 -> 5 in the cache */
   /* search21_0 -> 55 in the cache */
   /* search21_1 -> 41 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      true,
      -1,
      nir_op_sne,
      0, 2,
      { 55, 41 },
      -1,
   } },

   /* replace21_0 -> 4 in the cache */
   /* replace21_1_0 -> 5 in the cache */
   /* replace21_1 -> 43 in the cache */
   { .expression = {
      { nir_search_value_expression, -2 },
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      false,
      -1,
      nir_op_sne,
      0, 1,
      { 4, 43 },
      -1,
   } },

};


static const nir_search_variable_cond r600_sfn_lower_alu_variable_cond[] = {
   (is_a_number),
};

static const struct transform r600_sfn_lower_alu_transforms[] = {
   { ~0, ~0, ~0 }, /* Sentinel */

   { 3, 6, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 8, 9, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 11, 12, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 13, 10, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 15, 16, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 17, 14, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 19, 20, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 21, 18, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 23, 24, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 25, 22, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 32, 33, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 29, 30, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 38, 39, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 35, 36, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 45, 46, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 42, 44, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 49, 50, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 47, 48, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 53, 54, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 51, 52, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 56, 57, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

   { 58, 59, 0 },
   { ~0, ~0, ~0 }, /* Sentinel */

};

static const struct per_op_table r600_sfn_lower_alu_pass_op_table[nir_num_search_ops] = {
   [nir_op_inot] = {
      .filter = (const uint16_t []) {
         0,
         0,
         1,
         2,
         3,
         4,
         5,
         6,
         7,
         8,
         9,
         10,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 11,
      .table = (const uint16_t []) {
      
         0,
         13,
         14,
         15,
         16,
         17,
         18,
         19,
         20,
         21,
         22,
      },
   },
   [nir_op_flt] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 3,
      .table = (const uint16_t []) {
      
         2,
         2,
         2,
         2,
         2,
         27,
         2,
         28,
         2,
      },
   },
   [nir_op_fge] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         3,
      },
   },
   [nir_op_fneu] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         4,
      },
   },
   [nir_op_feq] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         5,
      },
   },
   [nir_op_ilt] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         6,
      },
   },
   [nir_op_ige] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         7,
      },
   },
   [nir_op_ult] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         8,
      },
   },
   [nir_op_uge] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         9,
      },
   },
   [nir_op_ieq] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         10,
      },
   },
   [nir_op_ine] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         11,
      },
   },
   [nir_search_op_b2f] = {
      .filter = (const uint16_t []) {
         0,
         0,
         1,
         2,
         3,
         4,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 5,
      .table = (const uint16_t []) {
      
         0,
         23,
         24,
         25,
         26,
      },
   },
   [nir_op_fadd] = {
      .filter = NULL,
      
      .num_filtered_states = 1,
      .table = (const uint16_t []) {
      
         12,
      },
   },
   [nir_op_slt] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 3,
      .table = (const uint16_t []) {
      
         0,
         0,
         0,
         0,
         0,
         29,
         0,
         30,
         0,
      },
   },
   [nir_op_sge] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 3,
      .table = (const uint16_t []) {
      
         0,
         0,
         0,
         0,
         0,
         31,
         0,
         32,
         0,
      },
   },
   [nir_op_seq] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 3,
      .table = (const uint16_t []) {
      
         0,
         0,
         0,
         0,
         0,
         33,
         0,
         33,
         0,
      },
   },
   [nir_op_sne] = {
      .filter = (const uint16_t []) {
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
      },
      
      .num_filtered_states = 3,
      .table = (const uint16_t []) {
      
         0,
         0,
         0,
         0,
         0,
         34,
         0,
         34,
         0,
      },
   },
};

/* Mapping from state index to offset in transforms (0 being no transforms) */
static const uint16_t r600_sfn_lower_alu_transform_offsets[] = {
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   0,
   1,
   3,
   5,
   7,
   9,
   11,
   13,
   15,
   17,
   19,
   21,
   23,
   25,
   27,
   29,
   31,
   33,
   35,
   37,
   39,
   41,
   43,
};

static const nir_algebraic_table r600_sfn_lower_alu_table = {
   .transforms = r600_sfn_lower_alu_transforms,
   .transform_offsets = r600_sfn_lower_alu_transform_offsets,
   .pass_op_table = r600_sfn_lower_alu_pass_op_table,
   .values = r600_sfn_lower_alu_values,
   .expression_cond = NULL,
   .variable_cond = r600_sfn_lower_alu_variable_cond,
};

bool
r600_sfn_lower_alu(
   nir_shader *shader
) {
   bool progress = false;
   bool condition_flags[1];
   const nir_shader_compiler_options *options = shader->options;
   const shader_info *info = &shader->info;
   (void) options;
   (void) info;

   STATIC_ASSERT(60 == ARRAY_SIZE(r600_sfn_lower_alu_values));
   condition_flags[0] = true;

   nir_foreach_function_impl(impl, shader) {
     progress |= nir_algebraic_impl(impl, condition_flags, &r600_sfn_lower_alu_table);
   }

   return progress;
}

