1 #include <cstdint>
2
3 struct alignas(16) float80_raw {
4 uint64_t mantissa;
5 uint16_t sign_exp;
6 };
7
main()8 int main() {
9 float80_raw st[] = {
10 {0x8000000000000000, 0x4000}, // +2.0
11 {0x3f00000000000000, 0x0000}, // 1.654785e-4932 (denormal)
12 {0x0000000000000000, 0x0000}, // +0
13 {0x0000000000000000, 0x8000}, // -0
14 {0x8000000000000000, 0x7fff}, // +inf
15 {0x8000000000000000, 0xffff}, // -inf
16 {0xc000000000000000, 0xffff}, // nan
17 // st7 will be freed to test tag word better
18 {0x0000000000000000, 0x0000}, // +0
19 };
20
21 // unmask divide-by-zero exception
22 uint16_t cw = 0x037b;
23 // used as single-precision float
24 uint32_t zero = 0;
25
26 asm volatile(
27 "finit\n\t"
28 "fldcw %1\n\t"
29 // load on stack in reverse order to make the result easier to read
30 "fldt 0x70(%0)\n\t"
31 "fldt 0x60(%0)\n\t"
32 "fldt 0x50(%0)\n\t"
33 "fldt 0x40(%0)\n\t"
34 "fldt 0x30(%0)\n\t"
35 "fldt 0x20(%0)\n\t"
36 "fldt 0x10(%0)\n\t"
37 "fldt 0x00(%0)\n\t"
38 // free st7
39 "ffree %%st(7)\n\t"
40 // this should trigger a divide-by-zero
41 "fdivs (%2)\n\t"
42 "int3\n\t"
43 :
44 : "a"(st), "m"(cw), "b"(&zero)
45 : "st"
46 );
47
48 return 0;
49 }
50