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
main()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 }
96