1 /* Test fscale instruction. */
7 struct { uint64_t sig
; uint16_t sign_exp
; } s
;
11 volatile long double ld_third
= 1.0L / 3.0L;
12 volatile long double ld_four_thirds
= 4.0L / 3.0L;
13 volatile union u ld_invalid_1
= { .s
= { 1, 1234 } };
14 volatile union u ld_invalid_2
= { .s
= { 0, 1234 } };
15 volatile union u ld_invalid_3
= { .s
= { 0, 0x7fff } };
16 volatile union u ld_invalid_4
= { .s
= { (UINT64_C(1) << 63) - 1, 0x7fff } };
18 volatile long double ld_res
;
20 int isnan_ld(long double x
)
22 union u tmp
= { .ld
= x
};
23 return ((tmp
.s
.sign_exp
& 0x7fff) == 0x7fff &&
24 (tmp
.s
.sig
>> 63) != 0 &&
25 (tmp
.s
.sig
<< 1) != 0);
28 int issignaling_ld(long double x
)
30 union u tmp
= { .ld
= x
};
31 return isnan_ld(x
) && (tmp
.s
.sig
& UINT64_C(0x4000000000000000)) == 0;
38 __asm__
volatile ("fscale" : "=t" (ld_res
) :
39 "0" (2.5L), "u" (__builtin_nansl("")));
40 if (!isnan_ld(ld_res
) || issignaling_ld(ld_res
)) {
41 printf("FAIL: fscale snan\n");
44 __asm__
volatile ("fscale" : "=t" (ld_res
) :
45 "0" (2.5L), "u" (ld_invalid_1
.ld
));
46 if (!isnan_ld(ld_res
) || issignaling_ld(ld_res
)) {
47 printf("FAIL: fscale invalid 1\n");
50 __asm__
volatile ("fscale" : "=t" (ld_res
) :
51 "0" (2.5L), "u" (ld_invalid_2
.ld
));
52 if (!isnan_ld(ld_res
) || issignaling_ld(ld_res
)) {
53 printf("FAIL: fscale invalid 2\n");
56 __asm__
volatile ("fscale" : "=t" (ld_res
) :
57 "0" (2.5L), "u" (ld_invalid_3
.ld
));
58 if (!isnan_ld(ld_res
) || issignaling_ld(ld_res
)) {
59 printf("FAIL: fscale invalid 3\n");
62 __asm__
volatile ("fscale" : "=t" (ld_res
) :
63 "0" (2.5L), "u" (ld_invalid_4
.ld
));
64 if (!isnan_ld(ld_res
) || issignaling_ld(ld_res
)) {
65 printf("FAIL: fscale invalid 4\n");
68 __asm__
volatile ("fscale" : "=t" (ld_res
) :
69 "0" (0.0L), "u" (__builtin_infl()));
70 if (!isnan_ld(ld_res
) || issignaling_ld(ld_res
)) {
71 printf("FAIL: fscale 0 up inf\n");
74 __asm__
volatile ("fscale" : "=t" (ld_res
) :
75 "0" (__builtin_infl()), "u" (-__builtin_infl()));
76 if (!isnan_ld(ld_res
) || issignaling_ld(ld_res
)) {
77 printf("FAIL: fscale inf down inf\n");
80 /* Set round-downward. */
81 __asm__
volatile ("fnstcw %0" : "=m" (cw
));
82 cw
= (cw
& ~0xc00) | 0x400;
83 __asm__
volatile ("fldcw %0" : : "m" (cw
));
84 __asm__
volatile ("fscale" : "=t" (ld_res
) :
85 "0" (1.0L), "u" (__builtin_infl()));
86 if (ld_res
!= __builtin_infl()) {
87 printf("FAIL: fscale finite up inf\n");
90 __asm__
volatile ("fscale" : "=t" (ld_res
) :
91 "0" (-1.0L), "u" (-__builtin_infl()));
92 if (ld_res
!= -0.0L || __builtin_copysignl(1.0L, ld_res
) != -1.0L) {
93 printf("FAIL: fscale finite down inf\n");
96 /* Set round-to-nearest with single-precision rounding. */
98 __asm__
volatile ("fldcw %0" : : "m" (cw
));
99 __asm__
volatile ("fscale" : "=t" (ld_res
) :
100 "0" (ld_third
), "u" (2.0L));
102 __asm__
volatile ("fldcw %0" : : "m" (cw
));
103 if (ld_res
!= ld_four_thirds
) {
104 printf("FAIL: fscale single-precision\n");