1/* Excess precision tests.  Test excess precision is removed when
2   necessary.  */
3/* { dg-do run } */
4/* { dg-options "-O2 -mfpmath=387 -fexcess-precision=standard" } */
5
6#include <float.h>
7#include <stdarg.h>
8
9extern void abort (void);
10extern void exit (int);
11
12volatile float f1 = 1.0f;
13volatile float f2 = 0x1.0p-30f;
14volatile float f3 = 0x1.0p-60f;
15volatile double d1 = 1.0;
16volatile double d2 = 0x1.0p-30;
17volatile double d3 = 0x1.0p-60;
18volatile float fadd1 = 1.0f + 0x1.0p-30f;
19volatile double dadd2 = 1.0 + 0x1.0p-30 + 0x1.0p-60;
20volatile double dh = 0x1.0p-24;
21volatile float fha = 1.0f + 0x1.0p-23f;
22
23void
24test_assign (void)
25{
26  float f;
27  double d;
28  f = f1 + f2;
29  if (f != fadd1)
30    abort ();
31  d = f1 + f2;
32  if (d != dadd2)
33    abort ();
34  d = d1 + d2 + d3;
35  if (d != dadd2)
36    abort ();
37  /* Verify rounding direct to float without double rounding.  */
38  f = d1 + dh + d3;
39  if (f != fha)
40    abort ();
41}
42
43void
44test_init (void)
45{
46  float f = f1 + f2;
47  double d = d1 + d2 + d3;
48  if (f != fadd1)
49    abort ();
50  if (d != dadd2)
51    abort ();
52}
53
54volatile int i1 = 0x40000001;
55volatile unsigned int u1 = 0x80000001u;
56volatile long long ll1 = 0x4000000000000001ll;
57volatile unsigned long long ull1 = 0x8000000000000001ull;
58
59void
60test_cast (void)
61{
62  if ((float)(f1 + f2) != fadd1)
63    abort ();
64  if ((double)(d1 + d2 + d3) != dadd2)
65    abort ();
66  if ((double)(f1 + f2 + f3) != dadd2)
67    abort ();
68  if ((float)i1 != 0x1.0p30f)
69    abort ();
70  if ((float)u1 != 0x1.0p31f)
71    abort ();
72  if ((float)ll1 != 0x1.0p62f)
73    abort ();
74  if ((float)ull1 != 0x1.0p63f)
75    abort ();
76  if ((double)ll1 != 0x1.0p62)
77    abort ();
78  if ((double)ull1 != 0x1.0p63)
79    abort ();
80}
81
82static inline void
83check_float (float f)
84{
85  if (f != fadd1)
86    abort ();
87}
88
89static inline void
90check_double (double d)
91{
92  if (d != dadd2)
93    abort ();
94}
95
96static inline void
97check_float_nonproto (f)
98     float f;
99{
100  if (f != fadd1)
101    abort ();
102}
103
104static inline void
105check_double_nonproto (d)
106     double d;
107{
108  if (d != dadd2)
109    abort ();
110}
111
112static void
113check_double_va (int i, ...)
114{
115  va_list ap;
116  va_start (ap, i);
117  if (va_arg (ap, double) != dadd2)
118    abort ();
119  va_end (ap);
120}
121
122void
123test_call (void)
124{
125  check_float (f1 + f2);
126  check_double (d1 + d2 + d3);
127  check_double (f1 + f2 + f3);
128  check_float_nonproto (f1 + f2);
129  check_double_nonproto (d1 + d2 + d3);
130  check_double_nonproto (f1 + f2 + f3);
131  check_double_va (0, d1 + d2 + d3);
132  check_double_va (0, f1 + f2 + f3);
133}
134
135static inline float
136return_float (void)
137{
138  return f1 + f2;
139}
140
141static inline double
142return_double1 (void)
143{
144  return d1 + d2 + d3;
145}
146
147static inline double
148return_double2 (void)
149{
150  return f1 + f2 + f3;
151}
152
153void
154test_return (void)
155{
156  if (return_float () != fadd1)
157    abort ();
158  if (return_double1 () != dadd2)
159    abort ();
160  if (return_double2 () != dadd2)
161    abort ();
162}
163
164volatile float flt_min = FLT_MIN;
165volatile double dbl_min = DBL_MIN;
166volatile float flt_max = FLT_MAX;
167volatile double dbl_max = DBL_MAX;
168
169void
170test_builtin (void)
171{
172  /* Classification macros convert to the semantic type.  signbit and
173     comparison macros do not.  */
174  if (!__builtin_isinf (flt_max * flt_max))
175    abort ();
176  if (!__builtin_isinf (dbl_max * dbl_max))
177    abort ();
178  if (__builtin_isnormal (flt_max * flt_max))
179    abort ();
180  if (__builtin_isnormal (dbl_max * dbl_max))
181    abort ();
182  if (__builtin_isfinite (flt_max * flt_max))
183    abort ();
184  if (__builtin_isfinite (dbl_max * dbl_max))
185    abort ();
186  if (!__builtin_isgreater (flt_min * flt_min, 0.0f))
187    abort ();
188  if (!__builtin_isgreaterequal (flt_min * flt_min, 0.0f))
189    abort ();
190  if (!__builtin_isless (0.0f, flt_min * flt_min))
191    abort ();
192  if (__builtin_islessequal (flt_min * flt_min, 0.0f))
193    abort ();
194  if (!__builtin_islessgreater (flt_min * flt_min, 0.0f))
195    abort ();
196  if (!__builtin_isgreater (dbl_min * dbl_min, 0.0))
197    abort ();
198  if (!__builtin_isgreaterequal (dbl_min * dbl_min, 0.0))
199    abort ();
200  if (!__builtin_isless (0.0, dbl_min * dbl_min))
201    abort ();
202  if (__builtin_islessequal (dbl_min * dbl_min, 0.0))
203    abort ();
204  if (!__builtin_islessgreater (dbl_min * dbl_min, 0.0))
205    abort ();
206}
207
208int
209main (void)
210{
211  test_assign ();
212  test_init ();
213  test_cast ();
214  test_call ();
215  test_return ();
216  test_builtin ();
217  exit (0);
218}
219