| 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 | |