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 Myersint 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