1 /* Test floating-point exceptions.  */
2 
3 #include <float.h>
4 #include <stdint.h>
5 #include <stdio.h>
6 
7 union u {
8     struct { uint64_t sig; uint16_t sign_exp; } s;
9     long double ld;
10 };
11 
12 volatile float f_res;
13 volatile double d_res;
14 volatile long double ld_res;
15 volatile long double ld_res2;
16 
17 volatile union u ld_invalid_1 = { .s = { 1, 1234 } };
18 volatile float f_snan = __builtin_nansf("");
19 volatile double d_snan = __builtin_nans("");
20 volatile long double ld_third = 1.0L / 3.0L;
21 volatile long double ld_snan = __builtin_nansl("");
22 volatile long double ld_nan = __builtin_nanl("");
23 volatile long double ld_inf = __builtin_infl();
24 volatile long double ld_ninf = -__builtin_infl();
25 volatile long double ld_one = 1.0L;
26 volatile long double ld_zero = 0.0L;
27 volatile long double ld_nzero = -0.0L;
28 volatile long double ld_min = LDBL_MIN;
29 volatile long double ld_max = LDBL_MAX;
30 volatile long double ld_nmax = -LDBL_MAX;
31 
32 #define IE (1 << 0)
33 #define ZE (1 << 2)
34 #define OE (1 << 3)
35 #define UE (1 << 4)
36 #define PE (1 << 5)
37 #define EXC (IE | ZE | OE | UE | PE)
38 
39 int main(void)
40 {
41     short sw;
42     unsigned char out[10];
43     int ret = 0;
44     int16_t res_16;
45     int32_t res_32;
46     int64_t res_64;
47 
48     __asm__ volatile ("fnclex");
49     ld_res = f_snan;
50     __asm__ volatile ("fnstsw" : "=a" (sw));
51     if ((sw & EXC) != IE) {
52         printf("FAIL: widen float snan\n");
53         ret = 1;
54     }
55     __asm__ volatile ("fnclex");
56     ld_res = d_snan;
57     __asm__ volatile ("fnstsw" : "=a" (sw));
58     if ((sw & EXC) != IE) {
59         printf("FAIL: widen double snan\n");
60         ret = 1;
61     }
62 
63     __asm__ volatile ("fnclex");
64     f_res = ld_min;
65     __asm__ volatile ("fnstsw" : "=a" (sw));
66     if ((sw & EXC) != (UE | PE)) {
67         printf("FAIL: narrow float underflow\n");
68         ret = 1;
69     }
70     __asm__ volatile ("fnclex");
71     d_res = ld_min;
72     __asm__ volatile ("fnstsw" : "=a" (sw));
73     if ((sw & EXC) != (UE | PE)) {
74         printf("FAIL: narrow double underflow\n");
75         ret = 1;
76     }
77 
78     __asm__ volatile ("fnclex");
79     f_res = ld_max;
80     __asm__ volatile ("fnstsw" : "=a" (sw));
81     if ((sw & EXC) != (OE | PE)) {
82         printf("FAIL: narrow float overflow\n");
83         ret = 1;
84     }
85     __asm__ volatile ("fnclex");
86     d_res = ld_max;
87     __asm__ volatile ("fnstsw" : "=a" (sw));
88     if ((sw & EXC) != (OE | PE)) {
89         printf("FAIL: narrow double overflow\n");
90         ret = 1;
91     }
92 
93     __asm__ volatile ("fnclex");
94     f_res = ld_third;
95     __asm__ volatile ("fnstsw" : "=a" (sw));
96     if ((sw & EXC) != PE) {
97         printf("FAIL: narrow float inexact\n");
98         ret = 1;
99     }
100     __asm__ volatile ("fnclex");
101     d_res = ld_third;
102     __asm__ volatile ("fnstsw" : "=a" (sw));
103     if ((sw & EXC) != PE) {
104         printf("FAIL: narrow double inexact\n");
105         ret = 1;
106     }
107 
108     __asm__ volatile ("fnclex");
109     f_res = ld_snan;
110     __asm__ volatile ("fnstsw" : "=a" (sw));
111     if ((sw & EXC) != IE) {
112         printf("FAIL: narrow float snan\n");
113         ret = 1;
114     }
115     __asm__ volatile ("fnclex");
116     d_res = ld_snan;
117     __asm__ volatile ("fnstsw" : "=a" (sw));
118     if ((sw & EXC) != IE) {
119         printf("FAIL: narrow double snan\n");
120         ret = 1;
121     }
122 
123     __asm__ volatile ("fnclex");
124     f_res = ld_invalid_1.ld;
125     __asm__ volatile ("fnstsw" : "=a" (sw));
126     if ((sw & EXC) != IE) {
127         printf("FAIL: narrow float invalid\n");
128         ret = 1;
129     }
130     __asm__ volatile ("fnclex");
131     d_res = ld_invalid_1.ld;
132     __asm__ volatile ("fnstsw" : "=a" (sw));
133     if ((sw & EXC) != IE) {
134         printf("FAIL: narrow double invalid\n");
135         ret = 1;
136     }
137 
138     __asm__ volatile ("fnclex");
139     __asm__ volatile ("frndint" : "=t" (ld_res) : "0" (ld_min));
140     __asm__ volatile ("fnstsw" : "=a" (sw));
141     if ((sw & EXC) != PE) {
142         printf("FAIL: frndint min\n");
143         ret = 1;
144     }
145     __asm__ volatile ("fnclex");
146     __asm__ volatile ("frndint" : "=t" (ld_res) : "0" (ld_snan));
147     __asm__ volatile ("fnstsw" : "=a" (sw));
148     if ((sw & EXC) != IE) {
149         printf("FAIL: frndint snan\n");
150         ret = 1;
151     }
152     __asm__ volatile ("fnclex");
153     __asm__ volatile ("frndint" : "=t" (ld_res) : "0" (ld_invalid_1.ld));
154     __asm__ volatile ("fnstsw" : "=a" (sw));
155     if ((sw & EXC) != IE) {
156         printf("FAIL: frndint invalid\n");
157         ret = 1;
158     }
159 
160     __asm__ volatile ("fnclex");
161     __asm__ volatile ("fcom" : : "t" (ld_nan), "u" (ld_zero));
162     __asm__ volatile ("fnstsw" : "=a" (sw));
163     if ((sw & EXC) != IE) {
164         printf("FAIL: fcom nan\n");
165         ret = 1;
166     }
167     __asm__ volatile ("fnclex");
168     __asm__ volatile ("fucom" : : "t" (ld_nan), "u" (ld_zero));
169     __asm__ volatile ("fnstsw" : "=a" (sw));
170     if ((sw & EXC) != 0) {
171         printf("FAIL: fucom nan\n");
172         ret = 1;
173     }
174     __asm__ volatile ("fnclex");
175     __asm__ volatile ("fucom" : : "t" (ld_snan), "u" (ld_zero));
176     __asm__ volatile ("fnstsw" : "=a" (sw));
177     if ((sw & EXC) != IE) {
178         printf("FAIL: fucom snan\n");
179         ret = 1;
180     }
181     __asm__ volatile ("fnclex");
182     __asm__ volatile ("fucom" : : "t" (1.0L), "u" (ld_invalid_1.ld));
183     __asm__ volatile ("fnstsw" : "=a" (sw));
184     if ((sw & EXC) != IE) {
185         printf("FAIL: fucom invalid\n");
186         ret = 1;
187     }
188 
189     __asm__ volatile ("fnclex");
190     ld_res = ld_max + ld_max;
191     __asm__ volatile ("fnstsw" : "=a" (sw));
192     if ((sw & EXC) != (OE | PE)) {
193         printf("FAIL: add overflow\n");
194         ret = 1;
195     }
196     __asm__ volatile ("fnclex");
197     ld_res = ld_max + ld_min;
198     __asm__ volatile ("fnstsw" : "=a" (sw));
199     if ((sw & EXC) != PE) {
200         printf("FAIL: add inexact\n");
201         ret = 1;
202     }
203     __asm__ volatile ("fnclex");
204     ld_res = ld_inf + ld_ninf;
205     __asm__ volatile ("fnstsw" : "=a" (sw));
206     if ((sw & EXC) != IE) {
207         printf("FAIL: add inf -inf\n");
208         ret = 1;
209     }
210     __asm__ volatile ("fnclex");
211     ld_res = ld_snan + ld_third;
212     __asm__ volatile ("fnstsw" : "=a" (sw));
213     if ((sw & EXC) != IE) {
214         printf("FAIL: add snan\n");
215         ret = 1;
216     }
217     __asm__ volatile ("fnclex");
218     ld_res = ld_third + ld_invalid_1.ld;
219     __asm__ volatile ("fnstsw" : "=a" (sw));
220     if ((sw & EXC) != IE) {
221         printf("FAIL: add invalid\n");
222         ret = 1;
223     }
224 
225     __asm__ volatile ("fnclex");
226     ld_res = ld_max - ld_nmax;
227     __asm__ volatile ("fnstsw" : "=a" (sw));
228     if ((sw & EXC) != (OE | PE)) {
229         printf("FAIL: sub overflow\n");
230         ret = 1;
231     }
232     __asm__ volatile ("fnclex");
233     ld_res = ld_max - ld_min;
234     __asm__ volatile ("fnstsw" : "=a" (sw));
235     if ((sw & EXC) != PE) {
236         printf("FAIL: sub inexact\n");
237         ret = 1;
238     }
239     __asm__ volatile ("fnclex");
240     ld_res = ld_inf - ld_inf;
241     __asm__ volatile ("fnstsw" : "=a" (sw));
242     if ((sw & EXC) != IE) {
243         printf("FAIL: sub inf inf\n");
244         ret = 1;
245     }
246     __asm__ volatile ("fnclex");
247     ld_res = ld_snan - ld_third;
248     __asm__ volatile ("fnstsw" : "=a" (sw));
249     if ((sw & EXC) != IE) {
250         printf("FAIL: sub snan\n");
251         ret = 1;
252     }
253     __asm__ volatile ("fnclex");
254     ld_res = ld_third - ld_invalid_1.ld;
255     __asm__ volatile ("fnstsw" : "=a" (sw));
256     if ((sw & EXC) != IE) {
257         printf("FAIL: sub invalid\n");
258         ret = 1;
259     }
260 
261     __asm__ volatile ("fnclex");
262     ld_res = ld_max * ld_max;
263     __asm__ volatile ("fnstsw" : "=a" (sw));
264     if ((sw & EXC) != (OE | PE)) {
265         printf("FAIL: mul overflow\n");
266         ret = 1;
267     }
268     __asm__ volatile ("fnclex");
269     ld_res = ld_third * ld_third;
270     __asm__ volatile ("fnstsw" : "=a" (sw));
271     if ((sw & EXC) != PE) {
272         printf("FAIL: mul inexact\n");
273         ret = 1;
274     }
275     __asm__ volatile ("fnclex");
276     ld_res = ld_min * ld_min;
277     __asm__ volatile ("fnstsw" : "=a" (sw));
278     if ((sw & EXC) != (UE | PE)) {
279         printf("FAIL: mul underflow\n");
280         ret = 1;
281     }
282     __asm__ volatile ("fnclex");
283     ld_res = ld_inf * ld_zero;
284     __asm__ volatile ("fnstsw" : "=a" (sw));
285     if ((sw & EXC) != IE) {
286         printf("FAIL: mul inf 0\n");
287         ret = 1;
288     }
289     __asm__ volatile ("fnclex");
290     ld_res = ld_snan * ld_third;
291     __asm__ volatile ("fnstsw" : "=a" (sw));
292     if ((sw & EXC) != IE) {
293         printf("FAIL: mul snan\n");
294         ret = 1;
295     }
296     __asm__ volatile ("fnclex");
297     ld_res = ld_third * ld_invalid_1.ld;
298     __asm__ volatile ("fnstsw" : "=a" (sw));
299     if ((sw & EXC) != IE) {
300         printf("FAIL: mul invalid\n");
301         ret = 1;
302     }
303 
304     __asm__ volatile ("fnclex");
305     ld_res = ld_max / ld_min;
306     __asm__ volatile ("fnstsw" : "=a" (sw));
307     if ((sw & EXC) != (OE | PE)) {
308         printf("FAIL: div overflow\n");
309         ret = 1;
310     }
311     __asm__ volatile ("fnclex");
312     ld_res = ld_one / ld_third;
313     __asm__ volatile ("fnstsw" : "=a" (sw));
314     if ((sw & EXC) != PE) {
315         printf("FAIL: div inexact\n");
316         ret = 1;
317     }
318     __asm__ volatile ("fnclex");
319     ld_res = ld_min / ld_max;
320     __asm__ volatile ("fnstsw" : "=a" (sw));
321     if ((sw & EXC) != (UE | PE)) {
322         printf("FAIL: div underflow\n");
323         ret = 1;
324     }
325     __asm__ volatile ("fnclex");
326     ld_res = ld_one / ld_zero;
327     __asm__ volatile ("fnstsw" : "=a" (sw));
328     if ((sw & EXC) != ZE) {
329         printf("FAIL: div 1 0\n");
330         ret = 1;
331     }
332     __asm__ volatile ("fnclex");
333     ld_res = ld_inf / ld_zero;
334     __asm__ volatile ("fnstsw" : "=a" (sw));
335     if ((sw & EXC) != 0) {
336         printf("FAIL: div inf 0\n");
337         ret = 1;
338     }
339     __asm__ volatile ("fnclex");
340     ld_res = ld_nan / ld_zero;
341     __asm__ volatile ("fnstsw" : "=a" (sw));
342     if ((sw & EXC) != 0) {
343         printf("FAIL: div nan 0\n");
344         ret = 1;
345     }
346     __asm__ volatile ("fnclex");
347     ld_res = ld_zero / ld_zero;
348     __asm__ volatile ("fnstsw" : "=a" (sw));
349     if ((sw & EXC) != IE) {
350         printf("FAIL: div 0 0\n");
351         ret = 1;
352     }
353     __asm__ volatile ("fnclex");
354     ld_res = ld_inf / ld_inf;
355     __asm__ volatile ("fnstsw" : "=a" (sw));
356     if ((sw & EXC) != IE) {
357         printf("FAIL: div inf inf\n");
358         ret = 1;
359     }
360     __asm__ volatile ("fnclex");
361     ld_res = ld_snan / ld_third;
362     __asm__ volatile ("fnstsw" : "=a" (sw));
363     if ((sw & EXC) != IE) {
364         printf("FAIL: div snan\n");
365         ret = 1;
366     }
367     __asm__ volatile ("fnclex");
368     ld_res = ld_third / ld_invalid_1.ld;
369     __asm__ volatile ("fnstsw" : "=a" (sw));
370     if ((sw & EXC) != IE) {
371         printf("FAIL: div invalid\n");
372         ret = 1;
373     }
374 
375     __asm__ volatile ("fnclex");
376     __asm__ volatile ("fsqrt" : "=t" (ld_res) : "0" (ld_max));
377     __asm__ volatile ("fnstsw" : "=a" (sw));
378     if ((sw & EXC) != PE) {
379         printf("FAIL: fsqrt inexact\n");
380         ret = 1;
381     }
382     __asm__ volatile ("fnclex");
383     __asm__ volatile ("fsqrt" : "=t" (ld_res) : "0" (ld_nmax));
384     __asm__ volatile ("fnstsw" : "=a" (sw));
385     if ((sw & EXC) != IE) {
386         printf("FAIL: fsqrt -max\n");
387         ret = 1;
388     }
389     __asm__ volatile ("fnclex");
390     __asm__ volatile ("fsqrt" : "=t" (ld_res) : "0" (ld_ninf));
391     __asm__ volatile ("fnstsw" : "=a" (sw));
392     if ((sw & EXC) != IE) {
393         printf("FAIL: fsqrt -inf\n");
394         ret = 1;
395     }
396     __asm__ volatile ("fnclex");
397     __asm__ volatile ("fsqrt" : "=t" (ld_res) : "0" (ld_snan));
398     __asm__ volatile ("fnstsw" : "=a" (sw));
399     if ((sw & EXC) != IE) {
400         printf("FAIL: fsqrt snan\n");
401         ret = 1;
402     }
403     __asm__ volatile ("fnclex");
404     __asm__ volatile ("fsqrt" : "=t" (ld_res) : "0" (ld_invalid_1.ld));
405     __asm__ volatile ("fnstsw" : "=a" (sw));
406     if ((sw & EXC) != IE) {
407         printf("FAIL: fsqrt invalid\n");
408         ret = 1;
409     }
410     __asm__ volatile ("fnclex");
411     __asm__ volatile ("fsqrt" : "=t" (ld_res) : "0" (ld_nzero));
412     __asm__ volatile ("fnstsw" : "=a" (sw));
413     if ((sw & EXC) != 0) {
414         printf("FAIL: fsqrt -0\n");
415         ret = 1;
416     }
417     __asm__ volatile ("fnclex");
418     __asm__ volatile ("fsqrt" : "=t" (ld_res) : "0" (-__builtin_nanl("")));
419     __asm__ volatile ("fnstsw" : "=a" (sw));
420     if ((sw & EXC) != 0) {
421         printf("FAIL: fsqrt -nan\n");
422         ret = 1;
423     }
424 
425     __asm__ volatile ("fnclex");
426     __asm__ volatile ("fistp %0" : "=m" (res_16) : "t" (1.5L) : "st");
427     __asm__ volatile ("fnstsw" : "=a" (sw));
428     if ((sw & EXC) != PE) {
429         printf("FAIL: fistp inexact\n");
430         ret = 1;
431     }
432     __asm__ volatile ("fnclex");
433     __asm__ volatile ("fistp %0" : "=m" (res_16) : "t" (32767.5L) : "st");
434     __asm__ volatile ("fnstsw" : "=a" (sw));
435     if ((sw & EXC) != IE) {
436         printf("FAIL: fistp 32767.5\n");
437         ret = 1;
438     }
439     __asm__ volatile ("fnclex");
440     __asm__ volatile ("fistp %0" : "=m" (res_16) : "t" (-32768.51L) : "st");
441     __asm__ volatile ("fnstsw" : "=a" (sw));
442     if ((sw & EXC) != IE) {
443         printf("FAIL: fistp -32768.51\n");
444         ret = 1;
445     }
446     __asm__ volatile ("fnclex");
447     __asm__ volatile ("fistp %0" : "=m" (res_16) : "t" (ld_nan) : "st");
448     __asm__ volatile ("fnstsw" : "=a" (sw));
449     if ((sw & EXC) != IE) {
450         printf("FAIL: fistp nan\n");
451         ret = 1;
452     }
453     __asm__ volatile ("fnclex");
454     __asm__ volatile ("fistp %0" : "=m" (res_16) : "t" (ld_invalid_1.ld) :
455                       "st");
456     __asm__ volatile ("fnstsw" : "=a" (sw));
457     if ((sw & EXC) != IE) {
458         printf("FAIL: fistp invalid\n");
459         ret = 1;
460     }
461 
462     __asm__ volatile ("fnclex");
463     __asm__ volatile ("fistpl %0" : "=m" (res_32) : "t" (1.5L) : "st");
464     __asm__ volatile ("fnstsw" : "=a" (sw));
465     if ((sw & EXC) != PE) {
466         printf("FAIL: fistpl inexact\n");
467         ret = 1;
468     }
469     __asm__ volatile ("fnclex");
470     __asm__ volatile ("fistpl %0" : "=m" (res_32) : "t" (2147483647.5L) :
471                       "st");
472     __asm__ volatile ("fnstsw" : "=a" (sw));
473     if ((sw & EXC) != IE) {
474         printf("FAIL: fistpl 2147483647.5\n");
475         ret = 1;
476     }
477     __asm__ volatile ("fnclex");
478     __asm__ volatile ("fistpl %0" : "=m" (res_32) : "t" (-2147483648.51L) :
479                       "st");
480     __asm__ volatile ("fnstsw" : "=a" (sw));
481     if ((sw & EXC) != IE) {
482         printf("FAIL: fistpl -2147483648.51\n");
483         ret = 1;
484     }
485     __asm__ volatile ("fnclex");
486     __asm__ volatile ("fistpl %0" : "=m" (res_32) : "t" (ld_nan) : "st");
487     __asm__ volatile ("fnstsw" : "=a" (sw));
488     if ((sw & EXC) != IE) {
489         printf("FAIL: fistpl nan\n");
490         ret = 1;
491     }
492     __asm__ volatile ("fnclex");
493     __asm__ volatile ("fistpl %0" : "=m" (res_32) : "t" (ld_invalid_1.ld) :
494                       "st");
495     __asm__ volatile ("fnstsw" : "=a" (sw));
496     if ((sw & EXC) != IE) {
497         printf("FAIL: fistpl invalid\n");
498         ret = 1;
499     }
500 
501     __asm__ volatile ("fnclex");
502     __asm__ volatile ("fistpll %0" : "=m" (res_64) : "t" (1.5L) : "st");
503     __asm__ volatile ("fnstsw" : "=a" (sw));
504     if ((sw & EXC) != PE) {
505         printf("FAIL: fistpll inexact\n");
506         ret = 1;
507     }
508     __asm__ volatile ("fnclex");
509     __asm__ volatile ("fistpll %0" : "=m" (res_64) : "t" (0x1p63) :
510                       "st");
511     __asm__ volatile ("fnstsw" : "=a" (sw));
512     if ((sw & EXC) != IE) {
513         printf("FAIL: fistpll 0x1p63\n");
514         ret = 1;
515     }
516     __asm__ volatile ("fnclex");
517     __asm__ volatile ("fistpll %0" : "=m" (res_64) : "t" (-0x1.1p63L) :
518                       "st");
519     __asm__ volatile ("fnstsw" : "=a" (sw));
520     if ((sw & EXC) != IE) {
521         printf("FAIL: fistpll -0x1.1p63\n");
522         ret = 1;
523     }
524     __asm__ volatile ("fnclex");
525     __asm__ volatile ("fistpll %0" : "=m" (res_64) : "t" (ld_nan) : "st");
526     __asm__ volatile ("fnstsw" : "=a" (sw));
527     if ((sw & EXC) != IE) {
528         printf("FAIL: fistpll nan\n");
529         ret = 1;
530     }
531     __asm__ volatile ("fnclex");
532     __asm__ volatile ("fistpll %0" : "=m" (res_64) : "t" (ld_invalid_1.ld) :
533                       "st");
534     __asm__ volatile ("fnstsw" : "=a" (sw));
535     if ((sw & EXC) != IE) {
536         printf("FAIL: fistpll invalid\n");
537         ret = 1;
538     }
539 
540     __asm__ volatile ("fnclex");
541     __asm__ volatile ("fisttp %0" : "=m" (res_16) : "t" (1.5L) : "st");
542     __asm__ volatile ("fnstsw" : "=a" (sw));
543     if ((sw & EXC) != PE) {
544         printf("FAIL: fisttp inexact\n");
545         ret = 1;
546     }
547     __asm__ volatile ("fnclex");
548     __asm__ volatile ("fisttp %0" : "=m" (res_16) : "t" (32768.0L) : "st");
549     __asm__ volatile ("fnstsw" : "=a" (sw));
550     if ((sw & EXC) != IE) {
551         printf("FAIL: fisttp 32768\n");
552         ret = 1;
553     }
554     __asm__ volatile ("fnclex");
555     __asm__ volatile ("fisttp %0" : "=m" (res_16) : "t" (32768.5L) : "st");
556     __asm__ volatile ("fnstsw" : "=a" (sw));
557     if ((sw & EXC) != IE) {
558         printf("FAIL: fisttp 32768.5\n");
559         ret = 1;
560     }
561     __asm__ volatile ("fnclex");
562     __asm__ volatile ("fisttp %0" : "=m" (res_16) : "t" (-32769.0L) : "st");
563     __asm__ volatile ("fnstsw" : "=a" (sw));
564     if ((sw & EXC) != IE) {
565         printf("FAIL: fisttp -32769\n");
566         ret = 1;
567     }
568     __asm__ volatile ("fnclex");
569     __asm__ volatile ("fisttp %0" : "=m" (res_16) : "t" (-32769.5L) : "st");
570     __asm__ volatile ("fnstsw" : "=a" (sw));
571     if ((sw & EXC) != IE) {
572         printf("FAIL: fisttp -32769.5\n");
573         ret = 1;
574     }
575     __asm__ volatile ("fnclex");
576     __asm__ volatile ("fisttp %0" : "=m" (res_16) : "t" (ld_nan) : "st");
577     __asm__ volatile ("fnstsw" : "=a" (sw));
578     if ((sw & EXC) != IE) {
579         printf("FAIL: fisttp nan\n");
580         ret = 1;
581     }
582     __asm__ volatile ("fnclex");
583     __asm__ volatile ("fisttp %0" : "=m" (res_16) : "t" (ld_invalid_1.ld) :
584                       "st");
585     __asm__ volatile ("fnstsw" : "=a" (sw));
586     if ((sw & EXC) != IE) {
587         printf("FAIL: fisttp invalid\n");
588         ret = 1;
589     }
590 
591     __asm__ volatile ("fnclex");
592     __asm__ volatile ("fisttpl %0" : "=m" (res_32) : "t" (1.5L) : "st");
593     __asm__ volatile ("fnstsw" : "=a" (sw));
594     if ((sw & EXC) != PE) {
595         printf("FAIL: fisttpl inexact\n");
596         ret = 1;
597     }
598     __asm__ volatile ("fnclex");
599     __asm__ volatile ("fisttpl %0" : "=m" (res_32) : "t" (2147483648.0L) :
600                       "st");
601     __asm__ volatile ("fnstsw" : "=a" (sw));
602     if ((sw & EXC) != IE) {
603         printf("FAIL: fisttpl 2147483648\n");
604         ret = 1;
605     }
606     __asm__ volatile ("fnclex");
607     __asm__ volatile ("fisttpl %0" : "=m" (res_32) : "t" (-2147483649.0L) :
608                       "st");
609     __asm__ volatile ("fnstsw" : "=a" (sw));
610     if ((sw & EXC) != IE) {
611         printf("FAIL: fisttpl -2147483649\n");
612         ret = 1;
613     }
614     __asm__ volatile ("fnclex");
615     __asm__ volatile ("fisttpl %0" : "=m" (res_32) : "t" (ld_nan) : "st");
616     __asm__ volatile ("fnstsw" : "=a" (sw));
617     if ((sw & EXC) != IE) {
618         printf("FAIL: fisttpl nan\n");
619         ret = 1;
620     }
621     __asm__ volatile ("fnclex");
622     __asm__ volatile ("fisttpl %0" : "=m" (res_32) : "t" (ld_invalid_1.ld) :
623                       "st");
624     __asm__ volatile ("fnstsw" : "=a" (sw));
625     if ((sw & EXC) != IE) {
626         printf("FAIL: fisttpl invalid\n");
627         ret = 1;
628     }
629 
630     __asm__ volatile ("fnclex");
631     __asm__ volatile ("fisttpll %0" : "=m" (res_64) : "t" (1.5L) : "st");
632     __asm__ volatile ("fnstsw" : "=a" (sw));
633     if ((sw & EXC) != PE) {
634         printf("FAIL: fisttpll inexact\n");
635         ret = 1;
636     }
637     __asm__ volatile ("fnclex");
638     __asm__ volatile ("fisttpll %0" : "=m" (res_64) : "t" (0x1p63) :
639                       "st");
640     __asm__ volatile ("fnstsw" : "=a" (sw));
641     if ((sw & EXC) != IE) {
642         printf("FAIL: fisttpll 0x1p63\n");
643         ret = 1;
644     }
645     __asm__ volatile ("fnclex");
646     __asm__ volatile ("fisttpll %0" : "=m" (res_64) : "t" (-0x1.1p63L) :
647                       "st");
648     __asm__ volatile ("fnstsw" : "=a" (sw));
649     if ((sw & EXC) != IE) {
650         printf("FAIL: fisttpll -0x1.1p63\n");
651         ret = 1;
652     }
653     __asm__ volatile ("fnclex");
654     __asm__ volatile ("fisttpll %0" : "=m" (res_64) : "t" (ld_nan) : "st");
655     __asm__ volatile ("fnstsw" : "=a" (sw));
656     if ((sw & EXC) != IE) {
657         printf("FAIL: fisttpll nan\n");
658         ret = 1;
659     }
660     __asm__ volatile ("fnclex");
661     __asm__ volatile ("fisttpll %0" : "=m" (res_64) : "t" (ld_invalid_1.ld) :
662                       "st");
663     __asm__ volatile ("fnstsw" : "=a" (sw));
664     if ((sw & EXC) != IE) {
665         printf("FAIL: fisttpll invalid\n");
666         ret = 1;
667     }
668 
669     __asm__ volatile ("fnclex");
670     __asm__ volatile ("fxtract" : "=t" (ld_res), "=u" (ld_res2) :
671                       "0" (ld_zero));
672     __asm__ volatile ("fnstsw" : "=a" (sw));
673     if ((sw & EXC) != ZE) {
674         printf("FAIL: fxtract 0\n");
675         ret = 1;
676     }
677     __asm__ volatile ("fnclex");
678     __asm__ volatile ("fxtract" : "=t" (ld_res), "=u" (ld_res2) :
679                       "0" (ld_nzero));
680     __asm__ volatile ("fnstsw" : "=a" (sw));
681     if ((sw & EXC) != ZE) {
682         printf("FAIL: fxtract -0\n");
683         ret = 1;
684     }
685     __asm__ volatile ("fnclex");
686     __asm__ volatile ("fxtract" : "=t" (ld_res), "=u" (ld_res2) :
687                       "0" (ld_inf));
688     __asm__ volatile ("fnstsw" : "=a" (sw));
689     if ((sw & EXC) != 0) {
690         printf("FAIL: fxtract inf\n");
691         ret = 1;
692     }
693     __asm__ volatile ("fnclex");
694     __asm__ volatile ("fxtract" : "=t" (ld_res), "=u" (ld_res2) :
695                       "0" (ld_nan));
696     __asm__ volatile ("fnstsw" : "=a" (sw));
697     if ((sw & EXC) != 0) {
698         printf("FAIL: fxtract nan\n");
699         ret = 1;
700     }
701     __asm__ volatile ("fnclex");
702     __asm__ volatile ("fxtract" : "=t" (ld_res), "=u" (ld_res2) :
703                       "0" (ld_snan));
704     __asm__ volatile ("fnstsw" : "=a" (sw));
705     if ((sw & EXC) != IE) {
706         printf("FAIL: fxtract snan\n");
707         ret = 1;
708     }
709     __asm__ volatile ("fnclex");
710     __asm__ volatile ("fxtract" : "=t" (ld_res), "=u" (ld_res2) :
711                       "0" (ld_invalid_1.ld));
712     __asm__ volatile ("fnstsw" : "=a" (sw));
713     if ((sw & EXC) != IE) {
714         printf("FAIL: fxtract invalid\n");
715         ret = 1;
716     }
717 
718     __asm__ volatile ("fnclex");
719     __asm__ volatile ("fscale" : "=t" (ld_res) : "0" (ld_min), "u" (ld_max));
720     __asm__ volatile ("fnstsw" : "=a" (sw));
721     if ((sw & EXC) != (OE | PE)) {
722         printf("FAIL: fscale overflow\n");
723         ret = 1;
724     }
725     __asm__ volatile ("fnclex");
726     __asm__ volatile ("fscale" : "=t" (ld_res) : "0" (ld_max), "u" (ld_nmax));
727     __asm__ volatile ("fnstsw" : "=a" (sw));
728     if ((sw & EXC) != (UE | PE)) {
729         printf("FAIL: fscale underflow\n");
730         ret = 1;
731     }
732     __asm__ volatile ("fnclex");
733     __asm__ volatile ("fscale" : "=t" (ld_res) : "0" (ld_zero), "u" (ld_inf));
734     __asm__ volatile ("fnstsw" : "=a" (sw));
735     if ((sw & EXC) != IE) {
736         printf("FAIL: fscale 0 inf\n");
737         ret = 1;
738     }
739     __asm__ volatile ("fnclex");
740     __asm__ volatile ("fscale" : "=t" (ld_res) : "0" (ld_inf), "u" (ld_ninf));
741     __asm__ volatile ("fnstsw" : "=a" (sw));
742     if ((sw & EXC) != IE) {
743         printf("FAIL: fscale inf -inf\n");
744         ret = 1;
745     }
746     __asm__ volatile ("fnclex");
747     __asm__ volatile ("fscale" : "=t" (ld_res) : "0" (ld_one), "u" (ld_snan));
748     __asm__ volatile ("fnstsw" : "=a" (sw));
749     if ((sw & EXC) != IE) {
750         printf("FAIL: fscale 1 snan\n");
751         ret = 1;
752     }
753     __asm__ volatile ("fnclex");
754     __asm__ volatile ("fscale" : "=t" (ld_res) : "0" (ld_snan), "u" (ld_nan));
755     __asm__ volatile ("fnstsw" : "=a" (sw));
756     if ((sw & EXC) != IE) {
757         printf("FAIL: fscale snan nan\n");
758         ret = 1;
759     }
760     __asm__ volatile ("fnclex");
761     __asm__ volatile ("fscale" : "=t" (ld_res) :
762                       "0" (ld_invalid_1.ld), "u" (ld_one));
763     __asm__ volatile ("fnstsw" : "=a" (sw));
764     if ((sw & EXC) != IE) {
765         printf("FAIL: fscale invalid 1\n");
766         ret = 1;
767     }
768     __asm__ volatile ("fnclex");
769     __asm__ volatile ("fscale" : "=t" (ld_res) :
770                       "0" (ld_invalid_1.ld), "u" (ld_nan));
771     __asm__ volatile ("fnstsw" : "=a" (sw));
772     if ((sw & EXC) != IE) {
773         printf("FAIL: fscale invalid nan\n");
774         ret = 1;
775     }
776 
777     __asm__ volatile ("fnclex");
778     __asm__ volatile ("fbstp %0" : "=m" (out) : "t" (1.5L) :
779                       "st");
780     __asm__ volatile ("fnstsw" : "=a" (sw));
781     if ((sw & EXC) != PE) {
782         printf("FAIL: fbstp 1.5\n");
783         ret = 1;
784     }
785     __asm__ volatile ("fnclex");
786     __asm__ volatile ("fbstp %0" : "=m" (out) : "t" (999999999999999999.5L) :
787                       "st");
788     __asm__ volatile ("fnstsw" : "=a" (sw));
789     if ((sw & EXC) != IE) {
790         printf("FAIL: fbstp 999999999999999999.5\n");
791         ret = 1;
792     }
793     __asm__ volatile ("fnclex");
794     __asm__ volatile ("fbstp %0" : "=m" (out) : "t" (-1000000000000000000.0L) :
795                       "st");
796     __asm__ volatile ("fnstsw" : "=a" (sw));
797     if ((sw & EXC) != IE) {
798         printf("FAIL: fbstp -1000000000000000000\n");
799         ret = 1;
800     }
801     __asm__ volatile ("fnclex");
802     __asm__ volatile ("fbstp %0" : "=m" (out) : "t" (ld_inf) : "st");
803     __asm__ volatile ("fnstsw" : "=a" (sw));
804     if ((sw & EXC) != IE) {
805         printf("FAIL: fbstp inf\n");
806         ret = 1;
807     }
808     __asm__ volatile ("fnclex");
809     __asm__ volatile ("fbstp %0" : "=m" (out) : "t" (ld_nan) : "st");
810     __asm__ volatile ("fnstsw" : "=a" (sw));
811     if ((sw & EXC) != IE) {
812         printf("FAIL: fbstp nan\n");
813         ret = 1;
814     }
815     __asm__ volatile ("fnclex");
816     __asm__ volatile ("fbstp %0" : "=m" (out) : "t" (ld_snan) : "st");
817     __asm__ volatile ("fnstsw" : "=a" (sw));
818     if ((sw & EXC) != IE) {
819         printf("FAIL: fbstp snan\n");
820         ret = 1;
821     }
822     __asm__ volatile ("fnclex");
823     __asm__ volatile ("fbstp %0" : "=m" (out) : "t" (ld_invalid_1.ld) : "st");
824     __asm__ volatile ("fnstsw" : "=a" (sw));
825     if ((sw & EXC) != IE) {
826         printf("FAIL: fbstp invalid\n");
827         ret = 1;
828     }
829 
830     return ret;
831 }
832