1  /* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */
       2  
       3  typedef unsigned long int unsigned_word;
       4  typedef signed long int signed_word;
       5  typedef unsigned_word word;
       6  
       7  typedef enum { ADD, ADD_CI, ADD_CO, ADD_CIO, SUB, SUB_CI, SUB_CO,
       8  SUB_CIO, ADC_CI, ADC_CO, ADC_CIO, AND, IOR, XOR, ANDC, IORC, EQV,
       9  NAND, NOR, AND_RC, IOR_RC, XOR_RC, ANDC_RC, IORC_RC, EQV_RC, NAND_RC,
      10  NOR_RC, AND_CC, IOR_CC, XOR_CC, ANDC_CC, IORC_CC, EQV_CC, NAND_CC,
      11  NOR_CC, LSHIFTR, ASHIFTR, SHIFTL, LSHIFTR_CO, ASHIFTR_CO, SHIFTL_CO,
      12  ROTATEL, ROTATEL_CO, ROTATEXL_CIO, ASHIFTR_CON, EXTS1, EXTS2, EXTU1,
      13  EXTU2, CLZ, CTZ, FF1, FF0, ABSVAL, NABSVAL, CMP, CPEQ, CPGE, CPGEU,
      14  CPGT, CPGTU, CPLE, CPLEU, CPLT, CPLTU, CPNEQ, CMPPAR, DOZ, COPY,
      15  EXCHANGE, COMCY, } opcode_t;
      16  
      17  typedef struct
      18  {
      19    opcode_t opcode:8;
      20    unsigned int s1:8;
      21    unsigned int s2:8;
      22    unsigned int d:8;
      23  } insn_t;
      24  
      25  enum prune_flags
      26  {
      27    NO_PRUNE = 0,
      28    CY_0 = 1,
      29    CY_1 = 2,
      30    CY_JUST_SET = 4,
      31  };
      32  
      33  int flag_use_carry = 1;
      34  
      35  inline
      36  recurse(opcode_t opcode,
      37   int d,
      38   int s1,
      39   int s2,
      40   word v,
      41   int cost,
      42   insn_t *sequence,
      43   int n_insns,
      44   word *values,
      45   int n_values,
      46   const word goal_value,
      47   int allowed_cost,
      48   int cy,
      49   int prune_flags)
      50  {
      51    insn_t insn;
      52  
      53    allowed_cost -= cost;
      54  
      55    if (allowed_cost > 0)
      56      {
      57        word old_d;
      58  
      59        old_d = values[d];
      60        values[d] = v;
      61  
      62        insn.opcode = opcode;
      63        insn.s1 = s1;
      64        insn.s2 = s2;
      65        insn.d = d;
      66        sequence[n_insns] = insn;
      67  
      68        synth(sequence, n_insns + 1, values, n_values,
      69       goal_value, allowed_cost, cy, prune_flags);
      70  
      71        values[d] = old_d;
      72      }
      73    else if (goal_value == v)
      74      {
      75        insn.opcode = opcode;
      76        insn.s1 = s1;
      77        insn.s2 = s2;
      78        insn.d = d;
      79        sequence[n_insns] = insn;
      80        test_sequence(sequence, n_insns + 1);
      81      }
      82  }
      83  
      84  synth(insn_t *sequence,
      85        int n_insns,
      86        word *values,
      87        int n_values,
      88        word goal_value,
      89        int allowed_cost,
      90        int ci,
      91        int prune_hint)
      92  {
      93    int s1, s2;
      94    word v, r1, r2;
      95    int co;
      96    int last_dest;
      97  
      98    if (n_insns > 0)
      99      last_dest = sequence[n_insns - 1].d;
     100    else
     101      last_dest = -1;
     102    if (ci >= 0 && flag_use_carry)
     103      {
     104        for (s1 = n_values - 1; s1 >= 0; s1--)
     105   {
     106     r1 = values[s1];
     107     for (s2 = s1 - 1; s2 >= 0; s2--)
     108       {
     109         r2 = values[s2];
     110  
     111         if (allowed_cost <= 1 && (prune_hint & CY_JUST_SET) == 0)
     112    {
     113      if (last_dest >= 0 && s1 != last_dest && s2 != last_dest)
     114        continue;
     115    }
     116         do { word __d = ( r1) + ( r2) + (( ci)); ( co) = ( ci) ? __d <= ( r1) : __d < ( r1); (v) = __d; } while (0);
     117         recurse(ADD_CIO, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     118         do { word __d = ( r1) + ( r2) + (( ci)); ( co) = ( ci); (v) = __d; } while (0);
     119         recurse(ADD_CI, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     120  
     121         do { word __d = ( r1) - ( r2) - (( ci)); ( co) = ( ci) ? __d >= ( r1) : __d > ( r1); (v) = __d; } while (0);
     122         recurse(SUB_CIO, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     123         do { word __d = ( r2) - ( r1) - (( ci)); ( co) = ( ci) ? __d >= ( r2) : __d > ( r2); (v) = __d; } while (0);
     124         recurse(SUB_CIO, n_values,  s2,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     125  
     126         do { word __d = ( r1) - ( r2) - (( ci)); ( co) = ( ci); (v) = __d; } while (0);
     127         recurse(SUB_CI, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     128         do { word __d = ( r2) - ( r1) - (( ci)); ( co) = ( ci); (v) = __d; } while (0);
     129         recurse(SUB_CI, n_values,  s2,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     130  
     131       }
     132   }
     133      }
     134    for (s1 = n_values - 1; s1 >= 0; s1--)
     135      {
     136        r1 = values[s1];
     137        for (s2 = s1 - 1; s2 >= 0; s2--)
     138   {
     139     r2 = values[s2];
     140  
     141     if (allowed_cost <= 1)
     142       {
     143         if (last_dest >= 0 && s1 != last_dest && s2 != last_dest)
     144    continue;
     145       }
     146  
     147     do { word __d = ( r1) + ( r2); ( co) = __d < ( r1); (v) = __d; } while (0);
     148     recurse(ADD_CO, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     149  
     150     ((v) = ( r1) + ( r2), ( co) = ( ci));
     151     recurse(ADD, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     152  
     153     do { word __d = ( r1) - ( r2); ( co) = __d > ( r1); (v) = __d; } while (0);
     154     recurse(SUB_CO, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     155     do { word __d = ( r2) - ( r1); ( co) = __d > ( r2); (v) = __d; } while (0);
     156     recurse(SUB_CO, n_values,  s2,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     157     ((v) = ( r1) - ( r2), ( co) = ( ci));
     158     recurse(SUB, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     159     ((v) = ( r2) - ( r1), ( co) = ( ci));
     160     recurse(SUB, n_values,  s2,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     161  
     162     ((v) = ( r1) & ( r2), ( co) = ( ci));
     163     recurse(AND, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     164  
     165     ((v) = ( r1) | ( r2), ( co) = ( ci));
     166     recurse(IOR, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     167  
     168     ((v) = ( r1) ^ ( r2), ( co) = ( ci));
     169     recurse(XOR, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     170  
     171     ((v) = ( r1) & ~( r2), ( co) = ( ci));
     172     recurse(ANDC, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     173     ((v) = ( r2) & ~( r1), ( co) = ( ci));
     174     recurse(ANDC, n_values,  s2,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     175     ((v) = ( r1) | ~( r2), ( co) = ( ci));
     176     recurse(IORC, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     177     ((v) = ( r2) | ~( r1), ( co) = ( ci));
     178     recurse(IORC, n_values,  s2,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     179     ((v) = ( r1) ^ ~( r2), ( co) = ( ci));
     180     recurse(EQV, n_values,  s1,  s2, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     181  
     182   }
     183      }
     184    if (ci >= 0 && flag_use_carry)
     185      {
     186        for (s1 = n_values - 1; s1 >= 0; s1--)
     187   {
     188     r1 = values[s1];
     189  
     190     if (allowed_cost <= 1 && (prune_hint & CY_JUST_SET) == 0)
     191       {
     192  
     193         if (last_dest >= 0 && s1 != last_dest)
     194    continue;
     195       }
     196  
     197     do { word __d = ( r1) + ( r1) + (( ci)); ( co) = ( ci) ? __d <= ( r1) : __d < ( r1); (v) = __d; } while (0);
     198     recurse(ADD_CIO, n_values,  s1,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     199  
     200     do { word __d = ( r1) + ( r1) + (( ci)); ( co) = ( ci); (v) = __d; } while (0);
     201     recurse(ADD_CI, n_values,  s1,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     202  
     203     do { word __d = ( r1) + ( -1 ) + (( ci)); ( co) = ( ci) ? __d <= ( r1) : __d < ( r1); (v) = __d; } while (0);
     204     recurse(ADD_CIO, n_values,  s1,  (0x20 + -1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     205  
     206     do { word __d = ( r1) + ( 0 ) + (( ci)); ( co) = ( ci) ? __d <= ( r1) : __d < ( r1); (v) = __d; } while (0);
     207     recurse(ADD_CIO, n_values,  s1,  (0x20 + 0) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     208     do { word __d = ( 0 ) - ( r1) - (( ci)); ( co) = ( ci) ? __d >= ( 0 ) : __d > ( 0 ); (v) = __d; } while (0);
     209     recurse(SUB_CIO, n_values,  (0x20 + 0) ,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     210  
     211   }
     212      }
     213    for (s1 = n_values - 1; s1 >= 0; s1--)
     214      {
     215        r1 = values[s1];
     216  
     217        if (allowed_cost <= 1)
     218   {
     219     if (last_dest >= 0 && s1 != last_dest)
     220       continue;
     221   }
     222        do { word __d = ( r1) + ( r1); ( co) = __d < ( r1); (v) = __d; } while (0);
     223        recurse(ADD_CO, n_values,  s1,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     224  
     225        ((v) = ( r1) & ( 1 ), ( co) = ( ci));
     226        recurse(AND, n_values,  s1,  (0x20 + 1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     227  
     228        ((v) = ( r1) ^ ( 1 ), ( co) = ( ci));
     229        recurse(XOR, n_values,  s1,  (0x20 + 1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     230  
     231        ((v) = ( -1 ) - ( r1), ( co) = ( ci));
     232        recurse(SUB, n_values,  (0x20 + -1) ,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     233        do { word __d = ( r1) + ( 1 ); ( co) = __d < ( r1); (v) = __d; } while (0);
     234        recurse(ADD_CO, n_values,  s1,  (0x20 + 1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     235        ((v) = ( r1) + ( 1 ), ( co) = ( ci));
     236        recurse(ADD, n_values,  s1,  (0x20 + 1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     237        do { word __d = ( r1) + ( -1 ); ( co) = __d < ( r1); (v) = __d; } while (0);
     238        recurse(ADD_CO, n_values,  s1,  (0x20 + -1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     239        do { word __d = ( r1) - ( 1 ); ( co) = __d > ( r1); (v) = __d; } while (0);
     240        recurse(SUB_CO, n_values,  s1,  (0x20 + 1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     241        do { word __d = ( 0 ) - ( r1); ( co) = __d > ( 0 ); (v) = __d; } while (0);
     242        recurse(SUB_CO, n_values,  (0x20 + 0) ,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET);
     243        ((v) = ( 0 ) - ( r1), ( co) = ( ci));
     244        recurse(SUB, n_values,  (0x20 + 0) ,  s1, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     245        ((v) = ((unsigned_word) ( r1) >> (( 1 ) & (32  - 1)) ), ( co) = ( ci));
     246        recurse(LSHIFTR, n_values,  s1,  (0x20 + 1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     247        ((v) = ((signed_word) ( r1) >> (( 1 ) & (32  - 1)) ), ( co) = ( ci));
     248        recurse(ASHIFTR, n_values,  s1,  (0x20 + 1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     249        ((v) = ((signed_word) ( r1) << (( 1 ) & (32  - 1)) ), ( co) = ( ci));
     250        recurse(SHIFTL, n_values,  s1,  (0x20 + 1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     251        ((v) = ((unsigned_word) ( r1) >> (( 32 -1 ) & (32  - 1)) ), ( co) = ( ci));
     252        recurse(LSHIFTR, n_values,  s1,  (0x20 + 32 -1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     253        ((v) = ((signed_word) ( r1) >> (( 32 -1 ) & (32  - 1)) ), ( co) = ( ci));
     254        recurse(ASHIFTR, n_values,  s1,  (0x20 + 32 -1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     255      }
     256    if (ci >= 0 && flag_use_carry
     257        && (allowed_cost <= 1 ? ((prune_hint & CY_JUST_SET) != 0) : 1))
     258      {
     259        do { word __d = ( 0 ) + ( 0 ) + (( ci)); ( co) = ( ci) ? __d <= ( 0 ) : __d < ( 0 ); (v) = __d; } while (0);
     260        recurse(ADD_CIO, n_values,  (0x20 + 0) ,  (0x20 + 0) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET | CY_0);
     261        do { word __d = ( 0 ) - ( 0 ) - (( ci)); ( co) = ( ci) ? __d >= ( 0 ) : __d > ( 0 ); (v) = __d; } while (0);
     262        recurse(SUB_CIO, n_values,  (0x20 + 0) ,  (0x20 + 0) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     263        do { word __d = ( 0 ) - ( -1 ) - (( ci)); ( co) = ( ci) ? __d >= ( 0 ) : __d > ( 0 ); (v) = __d; } while (0);
     264        recurse(SUB_CIO, n_values,  (0x20 + 0) ,  (0x20 + -1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  CY_JUST_SET | CY_1);
     265        do { word __d = ( 0 ) + ( -1 ) + (( ci)); ( co) = ( ci) ? __d <= ( 0 ) : __d < ( 0 ); (v) = __d; } while (0);
     266        recurse(ADD_CIO, n_values,  (0x20 + 0) ,  (0x20 + -1) , v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     267  
     268      }
     269  
     270    if (allowed_cost > 1)
     271      {
     272        ((v) = ( 0x80000000 ), ( co) = ( ci));
     273        recurse(COPY, n_values,  (0x20 - 2) ,  0, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     274  
     275        ((v) = ( -1 ), ( co) = ( ci));
     276        recurse(COPY, n_values,  (0x20 + -1) ,  0, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     277  
     278        ((v) = ( 1 ), ( co) = ( ci));
     279        recurse(COPY, n_values,  (0x20 + 1) ,  0, v, 1, sequence, n_insns, values, n_values + 1, goal_value, allowed_cost, co,  prune_hint & ~CY_JUST_SET);
     280      }
     281  }