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 short _Fract fx_t;
      10  typedef short _Sat _Fract satfx_t;
      11  typedef char intfx_t;
      12  
      13  SS_FUN (ss_add, +, fx_t, hr)
      14  SS_FUN (ss_sub, -, fx_t, hr)
      15  
      16  #define VAL(N, X)                               \
      17      __attribute__((noinline,noclone))           \
      18      satfx_t ss_add2_##N (satfx_t a)             \
      19      {                                           \
      20          return ss_add_hr (a, X##P##-##7hr);     \
      21      }                                           \
      22      __attribute__((noinline,noclone))           \
      23      satfx_t ss_add_##N (satfx_t a)              \
      24      {                                           \
      25          return a + X##P##-##7hr;                \
      26      }                                           \
      27      __attribute__((noinline,noclone))           \
      28      satfx_t ss_sub2_##N (satfx_t a)             \
      29      {                                           \
      30          return ss_sub_hr (a, X##P##-##7hr);     \
      31      }                                           \
      32      __attribute__((noinline,noclone))           \
      33      satfx_t ss_sub_##N (satfx_t a)              \
      34      {                                           \
      35          return a - X##P##-##7hr;                \
      36      }
      37  #include "vals-hr.def"
      38  #undef VAL
      39  
      40  __attribute__((noinline,noclone))
      41  satfx_t ss_add2_99 (satfx_t a)
      42  {
      43    return ss_add_hr (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_hr (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-hr.def"
      71    VAL (99,)
      72  #undef VAL
      73  };
      74  
      75  
      76  const volatile __flash intfx_t vals[] =
      77    {
      78      0, 1, 2, 0x7f, 0x80, 0x81, 0xff,
      79      0x40, 0x3e, 0x3f, 0xbf, 0xc0, 0xc1
      80    };
      81  
      82  int main (void)
      83  {
      84    for (unsigned int i = 0; i < sizeof (vals) / sizeof (*vals); i++)
      85      {
      86        satfx_t a, f1, f2;
      87        intfx_t val = vals[i];
      88        __builtin_memcpy (&a, &val, sizeof (satfx_t));
      89        for (unsigned int f = 0; f < sizeof (fun) / sizeof (*fun); f += 2)
      90          {
      91            if (fun[f](a) != fun[f+1](a))
      92              abort();
      93          }
      94      }
      95  
      96    exit (0);
      97    return 0;
      98  }