50 lines · cpp
1#include <cstdint>2 3struct alignas(16) float80_raw {4 uint64_t mantissa;5 uint16_t sign_exp;6};7 8int main() {9 float80_raw st[] = {10 {0x8000000000000000, 0x4000}, // +2.011 {0x3f00000000000000, 0x0000}, // 1.654785e-4932 (denormal)12 {0x0000000000000000, 0x0000}, // +013 {0x0000000000000000, 0x8000}, // -014 {0x8000000000000000, 0x7fff}, // +inf15 {0x8000000000000000, 0xffff}, // -inf16 {0xc000000000000000, 0xffff}, // nan17 // st7 will be freed to test tag word better18 {0x0000000000000000, 0x0000}, // +019 };20 21 // unmask divide-by-zero exception22 uint16_t cw = 0x037b;23 // used as single-precision float24 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 read30 "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 st739 "ffree %%st(7)\n\t"40 // this should trigger a divide-by-zero41 "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