| 2364 | #define FPU_GET_TOP(sw) ((sw & 0x3800) >> 11) |
| 2365 | |
| 2366 | void testFSAVE() { |
| 2367 | float f1 = 1; |
| 2368 | float f2 = 0; |
| 2369 | float f3 = -1; |
| 2370 | float f4 = .001f; |
| 2371 | struct FSaveState state; |
| 2372 | struct FSaveState16 state16; |
| 2373 | |
| 2374 | #if defined (BOXEDWINE_MSVC) && !defined (BOXEDWINE_64) |
| 2375 | { |
| 2376 | __asm { |
| 2377 | finit; |
| 2378 | fld f1; |
| 2379 | fld f2; |
| 2380 | fld f3; |
| 2381 | fld f4; |
| 2382 | fsave[state]; |
| 2383 | } |
| 2384 | U32 top = FPU_GET_TOP(state.fsw); |
| 2385 | assertTrue(top == 4); |
| 2386 | assertTrue(state.ftw == 0x10ff); // TAG_Valid << 14 | TAG_Zero << 12 || TAG_Valid << 10 | || TAG_Valid << 8 (0xff for 4 TAG_Empty) |
| 2387 | } |
| 2388 | #endif |
| 2389 | newInstruction(0); |
| 2390 | fpu_init(); |
| 2391 | fldf32(f1, 1); |
| 2392 | fldf32(f2, 2); |
| 2393 | fldf32(f3, 3); |
| 2394 | fldf32(f4, 4); |
| 2395 | pushCode8(0xdd); |
| 2396 | pushCode8(rm(true, 6, cpu->big ? 5 : 6)); |
| 2397 | if (cpu->big) { |
| 2398 | pushCode32(0); |
| 2399 | } else { |
| 2400 | pushCode16(0); |
| 2401 | } |
| 2402 | runTestCPU(); |
| 2403 | if (cpu->isBig()) { |
| 2404 | cpu->memory->memcpy(&state, HEAP_ADDRESS, sizeof(state)); |
| 2405 | U32 top = FPU_GET_TOP(state.fsw); |
| 2406 | assertTrue(top == 4); |
| 2407 | assertTrue(state.ftw == 0x10ff); |
| 2408 | } else { |
| 2409 | cpu->memory->memcpy(&state16, HEAP_ADDRESS, sizeof(state16)); |
| 2410 | U32 top = FPU_GET_TOP(state16.fsw); |
| 2411 | assertTrue(top == 4); |
| 2412 | assertTrue(state16.ftw == 0x10ff); |
| 2413 | } |
| 2414 | } |
| 2415 | |
| 2416 | void testFSAVEMmx() { |
| 2417 | float f1 = 1; |
no test coverage detected