| #include <cassert> | |
| #include <cinttypes> | |
| #include <cstdint> | |
| #include <cstdio> | |
| struct alignas(16) float80_raw { | |
| uint8_t data[10]; | |
| }; | |
| int main() { | |
| float80_raw st[8]; | |
| uint16_t env[14]; | |
| union alignas(16) { | |
| uint16_t i16[256]; | |
| uint32_t i32[128]; | |
| uint64_t i64[64]; | |
| } fxsave; | |
| asm volatile( | |
| "finit\n\t" | |
| "int3\n\t" | |
| #if defined(__x86_64__) | |
| "fxsave64 %2\n\t" | |
| #else | |
| "fxsave %2\n\t" | |
| #endif | |
| "fnstenv %1\n\t" | |
| "fnclex\n\t" | |
| "fstpt 0x00(%0)\n\t" | |
| "fstpt 0x10(%0)\n\t" | |
| "fstpt 0x20(%0)\n\t" | |
| "fstpt 0x30(%0)\n\t" | |
| "fstpt 0x40(%0)\n\t" | |
| "fstpt 0x50(%0)\n\t" | |
| "fstpt 0x60(%0)\n\t" | |
| "fstpt 0x70(%0)\n\t" | |
| : | |
| : "a"(st), "m"(env), "m"(fxsave) | |
| : "st" | |
| ); | |
| assert(env[0] == fxsave.i16[0]); | |
| assert(env[2] == fxsave.i16[1]); | |
| printf("fctrl = 0x%04" PRIx16 "\n", env[0]); | |
| printf("fstat = 0x%04" PRIx16 "\n", env[2]); | |
| printf("ftag = 0x%04" PRIx16 "\n", env[4]); | |
| printf("fop = 0x%04" PRIx16 "\n", fxsave.i16[3]); | |
| #if defined(__x86_64__) | |
| printf("fip = 0x%016" PRIx64 "\n", fxsave.i64[1]); | |
| printf("fdp = 0x%016" PRIx64 "\n", fxsave.i64[2]); | |
| #else | |
| printf("fip = 0x%08" PRIx32 "\n", fxsave.i32[2]); | |
| printf("fcs = 0x%04" PRIx16 "\n", fxsave.i16[6]); | |
| printf("fdp = 0x%08" PRIx32 "\n", fxsave.i32[4]); | |
| printf("fds = 0x%04" PRIx16 "\n", fxsave.i16[10]); | |
| #endif | |
| printf("mxcsr = 0x%08" PRIx32 "\n", fxsave.i32[6]); | |
| printf("mxcsr_mask = 0x%08" PRIx32 "\n", fxsave.i32[7]); | |
| for (int i = 0; i < 8; ++i) { | |
| printf("st%d = { ", i); | |
| for (int j = 0; j < sizeof(st->data); ++j) | |
| printf("0x%02" PRIx8 " ", st[i].data[j]); | |
| printf("}\n"); | |
| } | |
| return 0; | |
| } |