xref: /openbmc/qemu/tests/tcg/i386/test-i386-fscale.c (revision 0d48b436)
1*0d48b436SJoseph Myers /* Test fscale instruction.  */
2*0d48b436SJoseph Myers 
3*0d48b436SJoseph Myers #include <stdint.h>
4*0d48b436SJoseph Myers #include <stdio.h>
5*0d48b436SJoseph Myers 
6*0d48b436SJoseph Myers union u {
7*0d48b436SJoseph Myers     struct { uint64_t sig; uint16_t sign_exp; } s;
8*0d48b436SJoseph Myers     long double ld;
9*0d48b436SJoseph Myers };
10*0d48b436SJoseph Myers 
11*0d48b436SJoseph Myers volatile long double ld_res;
12*0d48b436SJoseph Myers 
13*0d48b436SJoseph Myers int isnan_ld(long double x)
14*0d48b436SJoseph Myers {
15*0d48b436SJoseph Myers   union u tmp = { .ld = x };
16*0d48b436SJoseph Myers   return ((tmp.s.sign_exp & 0x7fff) == 0x7fff &&
17*0d48b436SJoseph Myers           (tmp.s.sig >> 63) != 0 &&
18*0d48b436SJoseph Myers           (tmp.s.sig << 1) != 0);
19*0d48b436SJoseph Myers }
20*0d48b436SJoseph Myers 
21*0d48b436SJoseph Myers int issignaling_ld(long double x)
22*0d48b436SJoseph Myers {
23*0d48b436SJoseph Myers     union u tmp = { .ld = x };
24*0d48b436SJoseph Myers     return isnan_ld(x) && (tmp.s.sig & UINT64_C(0x4000000000000000)) == 0;
25*0d48b436SJoseph Myers }
26*0d48b436SJoseph Myers 
27*0d48b436SJoseph Myers int main(void)
28*0d48b436SJoseph Myers {
29*0d48b436SJoseph Myers     int ret = 0;
30*0d48b436SJoseph Myers     __asm__ volatile ("fscale" : "=t" (ld_res) :
31*0d48b436SJoseph Myers                       "0" (2.5L), "u" (__builtin_nansl("")));
32*0d48b436SJoseph Myers     if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) {
33*0d48b436SJoseph Myers         printf("FAIL: fscale snan\n");
34*0d48b436SJoseph Myers         ret = 1;
35*0d48b436SJoseph Myers     }
36*0d48b436SJoseph Myers     return ret;
37*0d48b436SJoseph Myers }
38