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