1  /* { dg-do run { target { ! avr_tiny } } } */
       2  /* { dg-options "-std=gnu99 -fwrapv" } */
       3  
       4  #include "fix-types.h"
       5  
       6  extern void abort (void);
       7  extern void exit (int);
       8  
       9  typedef _Fract fx_t;
      10  typedef _Sat _Fract satfx_t;
      11  typedef int intfx_t;
      12  
      13  SS_FUN (ss_add, +, fx_t, r)
      14  SS_FUN (ss_sub, -, fx_t, r)
      15  
      16  #define VAL(N, X)                               \
      17    __attribute__((noinline,noclone))             \
      18    satfx_t ss_add2_##N (satfx_t a)               \
      19    {                                             \
      20      return ss_add_r (a, X##P##-##15r);          \
      21    }                                             \
      22    __attribute__((noinline,noclone))             \
      23    satfx_t ss_add_##N (satfx_t a)                \
      24    {                                             \
      25      return a + X##P##-##15r;                    \
      26    }                                             \
      27    __attribute__((noinline,noclone))             \
      28    satfx_t ss_sub2_##N (satfx_t a)               \
      29    {                                             \
      30      return ss_sub_r (a, X##P##-##15r);          \
      31    }                                             \
      32    __attribute__((noinline,noclone))             \
      33    satfx_t ss_sub_##N (satfx_t a)                \
      34    {                                             \
      35      return a - X##P##-##15r;                    \
      36    }
      37  #include "vals-r.def"
      38  #undef VAL
      39  
      40  __attribute__((noinline,noclone))
      41  satfx_t ss_add2_99 (satfx_t a)
      42  {
      43    return ss_add_r (a, __FRACT_MIN__);
      44  }
      45  
      46  __attribute__((noinline,noclone))
      47  satfx_t ss_add_99 (satfx_t a)
      48  {
      49    return a + __FRACT_MIN__;
      50  }
      51  
      52  __attribute__((noinline,noclone))
      53  satfx_t ss_sub2_99 (satfx_t a)
      54  {
      55    return ss_sub_r (a, __FRACT_MIN__);
      56  }
      57  
      58  __attribute__((noinline,noclone))
      59  satfx_t ss_sub_99 (satfx_t a)
      60  {
      61    return a - __FRACT_MIN__;
      62  }
      63  
      64  
      65  satfx_t (* __flash const fun[])(satfx_t) =
      66  {
      67  #define VAL(N, X)                               \
      68    ss_add_##N, ss_add2_##N,                      \
      69    ss_sub_##N, ss_sub2_##N,
      70  #include "vals-r.def"
      71    VAL (99,)
      72  #undef VAL
      73  };
      74  
      75  
      76  const volatile __flash intfx_t vals[] =
      77    {
      78      0, -1, 1, -2, 2, -127, -128, -129,
      79      0x7f, 0x80, 0x81, 0x100,
      80      0x4000, 0x3e80, 0x3f80,
      81      0x7ffe, 0x7fff,
      82      0x7f7f, 0x7f81, 0x7f80,
      83      0x7f01,
      84      0x8000, 0x8001, 0x8080,
      85      0x8081, 0x80ff, 0x80fe,
      86      0x8100, 0x8180, 0x817f,
      87      0xff00, 0xff01, 0xff01,
      88      0xff7f, 0xff80
      89    };
      90  
      91  int main (void)
      92  {
      93    for (unsigned int i = 0; i < sizeof (vals) / sizeof (*vals); i++)
      94      {
      95        satfx_t a, f1, f2;
      96        intfx_t val = vals[i];
      97        __builtin_memcpy (&a, &val, sizeof (satfx_t));
      98        for (unsigned int f = 0; f < sizeof (fun) / sizeof (*fun); f += 2)
      99          {
     100            if (fun[f](a) != fun[f+1](a))
     101              abort();
     102          }
     103      }
     104  
     105    exit (0);
     106    return 0;
     107  }