1  /* Test for the 32 bit fp to 64 bit int conversion routines.
       2     
       3     On S/390 32 bit we use our own implementations in order to be IEEE
       4     complaint as we are with our machine instructions.  These missed to
       5     throw FE_INVALID exceptions in a bunch of cases.  */
       6  
       7  /* { dg-do run { target s390-*-* } } */
       8  /* { dg-options "-O3 -mesa" } */
       9  /* { dg-require-effective-target fenv_exceptions } */
      10  
      11  #define _GNU_SOURCE
      12  #include <stdlib.h>
      13  #include <stdio.h>
      14  #include <fenv.h>
      15  
      16  #define INFINITYf       (__builtin_inff())
      17  #define INFINITY        (__builtin_inf())
      18  #define INFINITYl       (__builtin_infl())
      19  #define NANf            (__builtin_nanf (""))
      20  #define NAN             (__builtin_nan (""))
      21  #define NANl            (__builtin_nanl (""))
      22  
      23  #define TESTEXCEPT_FUNC(FUNC, TYPE_FROM, TYPE_TO)			\
      24    TYPE_TO								\
      25    __attribute__((noinline)) FUNC (TYPE_FROM a)				\
      26    {									\
      27      asm volatile ("" : : "f" (a));					\
      28      return (TYPE_TO)a;							\
      29    }
      30  
      31  #define TESTEXCEPT(FUNC, EXCEPT, EXPECT, VALUE, TYPE_TO)		\
      32    {									\
      33      TYPE_TO b;								\
      34      feclearexcept (FE_ALL_EXCEPT);					\
      35      b = FUNC (VALUE);							\
      36      if ((fetestexcept (EXCEPT) & (EXCEPT)) != EXPECT)			\
      37        {									\
      38  	printf ("FAIL in line: %d\n", __LINE__);			\
      39  	abort ();							\
      40        }									\
      41    }
      42  
      43  #define TESTEXCEPT_FUNC_ALLFLOATS(FUNC, TYPE_TO)		\
      44    TESTEXCEPT_FUNC (FUNC##_f, float, TYPE_TO);			\
      45    TESTEXCEPT_FUNC (FUNC##_d, double, TYPE_TO);			\
      46    TESTEXCEPT_FUNC (FUNC##_l, long double, TYPE_TO);		\
      47  
      48  #define TESTEXCEPT_ALLFLOATS(FUNC, EXCEPT, EXPECT, VALUE, TYPE_TO)	\
      49    TESTEXCEPT (FUNC##_f, EXCEPT, EXPECT, VALUE##f, TYPE_TO);		\
      50    TESTEXCEPT (FUNC##_d, EXCEPT, EXPECT, VALUE, TYPE_TO);		\
      51    TESTEXCEPT (FUNC##_l, EXCEPT, EXPECT, VALUE##l, TYPE_TO);		\
      52  
      53  TESTEXCEPT_FUNC_ALLFLOATS (a, unsigned long long);
      54  TESTEXCEPT_FUNC_ALLFLOATS (u, long long);
      55  
      56  
      57  int
      58  main ()
      59  {
      60    /* Prevent getting signals.  */
      61    fedisableexcept (FE_INVALID);
      62  
      63    /* To unsigned long long */
      64  
      65    TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, INFINITY, unsigned long long);
      66    TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, -INFINITY, unsigned long long);
      67    TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, NAN, unsigned long long);
      68    TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, -NAN, unsigned long long);
      69  
      70    /* Negative values >-1.0 must not cause FE_INVALID.  */
      71    TESTEXCEPT_ALLFLOATS (a, FE_INVALID, 0, -0x0.ffffffp0, unsigned long long);
      72    /* -1.0 instead must.  */
      73    TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, -0x1.0p+0, unsigned long long);
      74    TESTEXCEPT_ALLFLOATS (a, FE_INVALID, 0, 0x1.0p+63, unsigned long long);
      75    TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, 0x1.0p+64, unsigned long long);
      76  
      77    /* To signed long long */
      78  
      79    TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, INFINITY, long long);
      80    TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, -INFINITY, long long);
      81    TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, NAN, long long);
      82    TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, -NAN, long long);
      83  
      84    TESTEXCEPT_ALLFLOATS (u, FE_INVALID, 0, -0x1.0p+63, long long);
      85    TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, -0x1.1p+63, long long);
      86    TESTEXCEPT_ALLFLOATS (u, FE_INVALID, 0, 0x0.fffffp+63, long long);
      87    TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, 0x1.0p+63, long long);
      88  
      89    /* If there are additional bits which would not make it into the
      90       integer value no exception is supposed to occur.  */
      91    TESTEXCEPT (u_l, FE_INVALID,          0, -0x1.000000000000000123p+63l, long long);
      92    TESTEXCEPT (u_l, FE_INVALID, FE_INVALID, -0x1.000000000000000223p+63l, long long);
      93  
      94    return 0;
      95  }