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
53TESTEXCEPT_FUNC_ALLFLOATS (a, unsigned long long);
54TESTEXCEPT_FUNC_ALLFLOATS (u, long long);
55
56
57int
58main ()
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