141602807SJoseph Myers /* Test pseudo-denormal operations.  */
241602807SJoseph Myers 
341602807SJoseph Myers #include <stdint.h>
441602807SJoseph Myers #include <stdio.h>
541602807SJoseph Myers 
641602807SJoseph Myers union u {
741602807SJoseph Myers     struct { uint64_t sig; uint16_t sign_exp; } s;
841602807SJoseph Myers     long double ld;
941602807SJoseph Myers };
1041602807SJoseph Myers 
1141602807SJoseph Myers volatile union u ld_pseudo_m16382 = { .s = { UINT64_C(1) << 63, 0 } };
1241602807SJoseph Myers 
1341602807SJoseph Myers volatile long double ld_res;
1441602807SJoseph Myers 
main(void)1541602807SJoseph Myers int main(void)
1641602807SJoseph Myers {
17*9ecaf5ccSJoseph Myers     short cw;
1841602807SJoseph Myers     int ret = 0;
1941602807SJoseph Myers     ld_res = ld_pseudo_m16382.ld + ld_pseudo_m16382.ld;
2041602807SJoseph Myers     if (ld_res != 0x1p-16381L) {
2141602807SJoseph Myers         printf("FAIL: pseudo-denormal add\n");
2241602807SJoseph Myers         ret = 1;
2341602807SJoseph Myers     }
24be53fa78SJoseph Myers     if (ld_pseudo_m16382.ld != 0x1p-16382L) {
25be53fa78SJoseph Myers         printf("FAIL: pseudo-denormal compare\n");
26be53fa78SJoseph Myers         ret = 1;
27be53fa78SJoseph Myers     }
28*9ecaf5ccSJoseph Myers     /* Set round-upward.  */
29*9ecaf5ccSJoseph Myers     __asm__ volatile ("fnstcw %0" : "=m" (cw));
30*9ecaf5ccSJoseph Myers     cw = (cw & ~0xc00) | 0x800;
31*9ecaf5ccSJoseph Myers     __asm__ volatile ("fldcw %0" : : "m" (cw));
32*9ecaf5ccSJoseph Myers     __asm__ ("frndint" : "=t" (ld_res) : "0" (ld_pseudo_m16382.ld));
33*9ecaf5ccSJoseph Myers     if (ld_res != 1.0L) {
34*9ecaf5ccSJoseph Myers         printf("FAIL: pseudo-denormal round-to-integer\n");
35*9ecaf5ccSJoseph Myers         ret = 1;
36*9ecaf5ccSJoseph Myers     }
3741602807SJoseph Myers     return ret;
3841602807SJoseph Myers }
39