1 /* Test pseudo-denormal operations.  */
2 
3 #include <stdint.h>
4 #include <stdio.h>
5 
6 union u {
7     struct { uint64_t sig; uint16_t sign_exp; } s;
8     long double ld;
9 };
10 
11 volatile union u ld_pseudo_m16382 = { .s = { UINT64_C(1) << 63, 0 } };
12 
13 volatile long double ld_res;
14 
15 int main(void)
16 {
17     short cw;
18     int ret = 0;
19     ld_res = ld_pseudo_m16382.ld + ld_pseudo_m16382.ld;
20     if (ld_res != 0x1p-16381L) {
21         printf("FAIL: pseudo-denormal add\n");
22         ret = 1;
23     }
24     if (ld_pseudo_m16382.ld != 0x1p-16382L) {
25         printf("FAIL: pseudo-denormal compare\n");
26         ret = 1;
27     }
28     /* Set round-upward.  */
29     __asm__ volatile ("fnstcw %0" : "=m" (cw));
30     cw = (cw & ~0xc00) | 0x800;
31     __asm__ volatile ("fldcw %0" : : "m" (cw));
32     __asm__ ("frndint" : "=t" (ld_res) : "0" (ld_pseudo_m16382.ld));
33     if (ld_res != 1.0L) {
34         printf("FAIL: pseudo-denormal round-to-integer\n");
35         ret = 1;
36     }
37     return ret;
38 }
39