1 #include <cstdint> 2 3 struct alignas(16) float80_raw { 4 uint64_t mantissa; 5 uint16_t sign_exp; 6 }; 7 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