1 | #include <cassert> |
2 | #include <cinttypes> |
3 | #include <cstdint> |
4 | #include <cstdio> |
5 | |
6 | struct alignas(16) float80_raw { |
7 | uint8_t data[10]; |
8 | }; |
9 | |
10 | int main() { |
11 | float80_raw st[8]; |
12 | uint16_t env[14]; |
13 | union alignas(16) { |
14 | uint16_t i16[256]; |
15 | uint32_t i32[128]; |
16 | uint64_t i64[64]; |
17 | } fxsave; |
18 | |
19 | asm volatile( |
20 | "finit\n\t" |
21 | "int3\n\t" |
22 | #if defined(__x86_64__) |
23 | "fxsave64 %2\n\t" |
24 | #else |
25 | "fxsave %2\n\t" |
26 | #endif |
27 | "fnstenv %1\n\t" |
28 | "fnclex\n\t" |
29 | "fstpt 0x00(%0)\n\t" |
30 | "fstpt 0x10(%0)\n\t" |
31 | "fstpt 0x20(%0)\n\t" |
32 | "fstpt 0x30(%0)\n\t" |
33 | "fstpt 0x40(%0)\n\t" |
34 | "fstpt 0x50(%0)\n\t" |
35 | "fstpt 0x60(%0)\n\t" |
36 | "fstpt 0x70(%0)\n\t" |
37 | : |
38 | : "a" (st), "m" (env), "m" (fxsave) |
39 | : "st" |
40 | ); |
41 | |
42 | assert(env[0] == fxsave.i16[0]); |
43 | assert(env[2] == fxsave.i16[1]); |
44 | |
45 | printf(format: "fctrl = 0x%04" PRIx16 "\n" , env[0]); |
46 | printf(format: "fstat = 0x%04" PRIx16 "\n" , env[2]); |
47 | printf(format: "ftag = 0x%04" PRIx16 "\n" , env[4]); |
48 | printf(format: "fop = 0x%04" PRIx16 "\n" , fxsave.i16[3]); |
49 | #if defined(__x86_64__) |
50 | printf(format: "fip = 0x%016" PRIx64 "\n" , fxsave.i64[1]); |
51 | printf(format: "fdp = 0x%016" PRIx64 "\n" , fxsave.i64[2]); |
52 | #else |
53 | printf("fip = 0x%08" PRIx32 "\n" , fxsave.i32[2]); |
54 | printf("fcs = 0x%04" PRIx16 "\n" , fxsave.i16[6]); |
55 | printf("fdp = 0x%08" PRIx32 "\n" , fxsave.i32[4]); |
56 | printf("fds = 0x%04" PRIx16 "\n" , fxsave.i16[10]); |
57 | #endif |
58 | printf(format: "mxcsr = 0x%08" PRIx32 "\n" , fxsave.i32[6]); |
59 | printf(format: "mxcsr_mask = 0x%08" PRIx32 "\n" , fxsave.i32[7]); |
60 | |
61 | for (int i = 0; i < 8; ++i) { |
62 | printf(format: "st%d = { " , i); |
63 | for (int j = 0; j < sizeof(st->data); ++j) |
64 | printf(format: "0x%02" PRIx8 " " , st[i].data[j]); |
65 | printf(format: "}\n" ); |
66 | } |
67 | |
68 | return 0; |
69 | } |
70 | |