mirror of
https://github.com/ptitSeb/box86.git
synced 2024-11-27 08:50:28 +00:00
Added USE_FLOAT build option (hopefully a bit faster on the Pandora)
This commit is contained in:
parent
b98412de11
commit
fbd494d348
@ -9,7 +9,7 @@ option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACH
|
||||
option(LD80BITS "Set to ON if host device have 80bits long double (i.e. i386)" ${LD80BITS})
|
||||
option(NOALIGN "Set to ON if host device doesn't need re-align (i.e. i386)" ${NOALIGN})
|
||||
option(HAVE_TRACE "Set to ON to have Trace ability (needs ZydisInfo library)" ${HAVE_TRACE})
|
||||
|
||||
option(USE_FLOAT "Set to ON to use only float, no double, in all x87 Emulation" ${USE_FLOAT})
|
||||
|
||||
# Pandora
|
||||
if(PANDORA)
|
||||
@ -29,6 +29,10 @@ if(HAVE_TRACE)
|
||||
add_definitions(-DHAVE_TRACE)
|
||||
endif()
|
||||
|
||||
if(USE_FLOAT)
|
||||
add_definitions(-DUSE_FLOAT)
|
||||
endif()
|
||||
|
||||
add_definitions(-g -std=gnu99 -funwind-tables -O3 -fvisibility=hidden -no-pie -fjump-tables)
|
||||
|
||||
if(USE_CCACHE)
|
||||
@ -115,52 +119,58 @@ set(WRAPPER "${CMAKE_HOME_DIRECTORY}/src/wrapper.c" "${CMAKE_HOME_DIRECTORY}/src
|
||||
add_custom_command(OUTPUT ${WRAPPER} COMMAND "${CMAKE_HOME_DIRECTORY}/rebuild_wrappers.py" "${CMAKE_HOME_DIRECTORY}" MAIN_DEPENDENCY "${CMAKE_HOME_DIRECTORY}/rebuild_wrappers.py" DEPENDS ${WRAPPEDS})
|
||||
set_source_files_properties(${WRAPPER} PROPERTIES GENERATED TRUE)
|
||||
|
||||
add_executable(box86 ${ELFLOADER_SRC} ${WRAPPEDS})
|
||||
target_link_libraries(box86 m dl rt pthread)
|
||||
if(USE_FLOAT)
|
||||
set(BOX86 box86f)
|
||||
else()
|
||||
set(BOX86 box86)
|
||||
endif()
|
||||
|
||||
target_link_libraries(box86 -no-pie -Wl,-Ttext-segment,0xA8000000)
|
||||
add_executable(${BOX86} ${ELFLOADER_SRC} ${WRAPPEDS})
|
||||
target_link_libraries(${BOX86} m dl rt pthread)
|
||||
|
||||
add_test(test01 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
target_link_libraries(${BOX86} -no-pie -Wl,-Ttext-segment,0xA8000000)
|
||||
|
||||
add_test(test01 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test01 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref01.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test02 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
add_test(test02 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test02 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref02.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test03 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
add_test(test03 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test03 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref03.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test04 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
add_test(test04 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test04 -D TEST_ARGS2=yeah -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref04.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test05 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
add_test(test05 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test05 -D TEST_ARGS2=7 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref05.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test06 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
add_test(test06 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test06 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref06.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test07 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
add_test(test07 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test07 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref07.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test08 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
add_test(test08 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test08 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref08.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test09 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/box86
|
||||
add_test(test09 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test09 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref09.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
@ -88,6 +88,12 @@ typedef union ui64_s {
|
||||
uint32_t d[2];
|
||||
} ui64_t;
|
||||
|
||||
#ifdef USE_FLOAT
|
||||
#define ST0val ST0.f
|
||||
#else
|
||||
#define ST0val ST0.d
|
||||
#endif
|
||||
|
||||
""",
|
||||
"wrapper.h": """/*****************************************************************
|
||||
* File automatically generated by rebuild_wrappers.py (v1.0.0.02)
|
||||
@ -202,10 +208,10 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
||||
"R_EAX=(unsigned short)fn({0});", # W
|
||||
"R_EAX=(uint32_t)fn({0});", # u
|
||||
"ui64_t r; r.u=(uint64_t)fn({0}); R_EAX=r.d[0]; R_EDX=r.d[1];", # U
|
||||
"float fl=fn({0}); fpu_do_push(emu); ST0.d = fl;", # f
|
||||
"double db=fn({0}); fpu_do_push(emu); ST0.d = db;", # d
|
||||
"long double ld=fn({0}); fpu_do_push(emu); ST0.d = ld;", # D
|
||||
"double db=fn({0}); fpu_do_push(emu); ST0.d = db;", # L
|
||||
"float fl=fn({0}); fpu_do_push(emu); ST0val = fl;", # f
|
||||
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # d
|
||||
"long double ld=fn({0}); fpu_do_push(emu); ST0val = ld;", # D
|
||||
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # L
|
||||
"R_EAX=(uintptr_t)fn({0});", # p
|
||||
"\n#error Invalid return type: va_list\n", # V
|
||||
]
|
||||
|
@ -172,7 +172,13 @@ int main(int argc, const char **argv, const char **env) {
|
||||
|
||||
// trying to open and load 1st arg
|
||||
if(argc==1) {
|
||||
printf("Box86 v%d.%d.%d\n", BOX86_MAJOR, BOX86_MINOR, BOX86_REVISION);
|
||||
printf("Box86%s v%d.%d.%d\n",
|
||||
#ifdef USE_FLOAT
|
||||
" (float only)",
|
||||
#else
|
||||
"",
|
||||
#endif
|
||||
BOX86_MAJOR, BOX86_MINOR, BOX86_REVISION);
|
||||
PrintHelp();
|
||||
return 1;
|
||||
}
|
||||
|
@ -76,6 +76,10 @@ typedef enum {
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef union {
|
||||
#ifdef USE_FLOAT
|
||||
float f;
|
||||
uint32_t ll; // same, to avoid more #ifdef...
|
||||
#else
|
||||
double d;
|
||||
struct {
|
||||
uint32_t lower;
|
||||
@ -86,6 +90,7 @@ typedef union {
|
||||
float upper;
|
||||
} f;
|
||||
int64_t ll;
|
||||
#endif
|
||||
} fpu_reg_t;
|
||||
|
||||
typedef union {
|
||||
|
80
src/rund8.h
80
src/rund8.h
@ -8,7 +8,11 @@
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7: /* FADD */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f += ST(nextop&7).f;
|
||||
#else
|
||||
ST0.d += ST(nextop&7).d;
|
||||
#endif
|
||||
break;
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
@ -18,7 +22,11 @@
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF: /* FMUL */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f *= ST(nextop&7).f;
|
||||
#else
|
||||
ST0.d *= ST(nextop&7).d;
|
||||
#endif
|
||||
break;
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
@ -28,7 +36,11 @@
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7: /* FCOM */
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcom(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcom(emu, ST(nextop&7).d);
|
||||
#endif
|
||||
break;
|
||||
case 0xD8:
|
||||
case 0xD9:
|
||||
@ -38,7 +50,11 @@
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF: /* FCOMP */
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcom(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcom(emu, ST(nextop&7).d);
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 0xE0:
|
||||
@ -49,7 +65,11 @@
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7: /* FSUB */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f -= ST(nextop&7).f;
|
||||
#else
|
||||
ST0.d -= ST(nextop&7).d;
|
||||
#endif
|
||||
break;
|
||||
case 0xE8:
|
||||
case 0xE9:
|
||||
@ -59,7 +79,11 @@
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF: /* FSUBR */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = ST(nextop&7).f - ST0.f;
|
||||
#else
|
||||
ST0.d = ST(nextop&7).d - ST0.d;
|
||||
#endif
|
||||
break;
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
@ -69,7 +93,11 @@
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7: /* FDIV */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f /= ST(nextop&7).f;
|
||||
#else
|
||||
ST0.d /= ST(nextop&7).d;
|
||||
#endif
|
||||
break;
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
@ -79,26 +107,46 @@
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF: /* FDIVR */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = ST(nextop&7).f / ST0.f;
|
||||
#else
|
||||
ST0.d = ST(nextop&7).d / ST0.d;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: /* FADD ST0, float */
|
||||
GET_ED;
|
||||
if(!(((uintptr_t)ED)&3))
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f += *(float*)ED;
|
||||
#else
|
||||
ST0.d += *(float*)ED;
|
||||
#endif
|
||||
else {
|
||||
*(uint32_t*)&f = ED->dword[0];
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f += f;
|
||||
#else
|
||||
ST0.d += f;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 1: /* FMUL ST0, float */
|
||||
GET_ED;
|
||||
if(!(((uintptr_t)ED)&3))
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f *= *(float*)ED;
|
||||
#else
|
||||
ST0.d *= *(float*)ED;
|
||||
#endif
|
||||
else {
|
||||
*(uint32_t*)&f = ED->dword[0];
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f *= f;
|
||||
#else
|
||||
ST0.d *= f;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 2: /* FCOM ST0, float */
|
||||
@ -123,37 +171,69 @@
|
||||
case 4: /* FSUB ST0, float */
|
||||
GET_ED;
|
||||
if(!(((uintptr_t)ED)&3))
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f -= *(float*)ED;
|
||||
#else
|
||||
ST0.d -= *(float*)ED;
|
||||
#endif
|
||||
else {
|
||||
*(uint32_t*)&f = ED->dword[0];
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f -= f;
|
||||
#else
|
||||
ST0.d -= f;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 5: /* FSUBR ST0, float */
|
||||
GET_ED;
|
||||
if(!(((uintptr_t)ED)&3))
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = *(float*)ED - ST0.f;
|
||||
#else
|
||||
ST0.d = *(float*)ED - ST0.d;
|
||||
#endif
|
||||
else {
|
||||
*(uint32_t*)&f = ED->dword[0];
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = f - ST0.f;
|
||||
#else
|
||||
ST0.d = f - ST0.d;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 6: /* FDIV ST0, float */
|
||||
GET_ED;
|
||||
if(!(((uintptr_t)ED)&3))
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f /= *(float*)ED;
|
||||
#else
|
||||
ST0.d /= *(float*)ED;
|
||||
#endif
|
||||
else {
|
||||
*(uint32_t*)&f = ED->dword[0];
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f /= f;
|
||||
#else
|
||||
ST0.d /= f;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 7: /* FDIVR ST0, float */
|
||||
GET_ED;
|
||||
if(!(((uintptr_t)ED)&3))
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = *(float*)ED / ST0.f;
|
||||
#else
|
||||
ST0.d = *(float*)ED / ST0.d;
|
||||
#endif
|
||||
else {
|
||||
*(uint32_t*)&f = ED->dword[0];
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = f / ST0.f;
|
||||
#else
|
||||
ST0.d = f / ST0.d;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
83
src/rund9.h
83
src/rund9.h
@ -29,10 +29,18 @@
|
||||
break;
|
||||
|
||||
case 0xE0: /* FCHS */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = -ST0.f;
|
||||
#else
|
||||
ST0.d = -ST0.d;
|
||||
#endif
|
||||
break;
|
||||
case 0xE1: /* FABS */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = fabsf(ST0.f);
|
||||
#else
|
||||
ST0.d = fabs(ST0.d);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0xE5: /* FXAM */
|
||||
@ -41,46 +49,89 @@
|
||||
|
||||
case 0xE8: /* FLD1 */
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = 1.0f;
|
||||
#else
|
||||
ST0.d = 1.0;
|
||||
#endif
|
||||
break;
|
||||
case 0xE9: /* FLDL2T */
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = L2T;
|
||||
#else
|
||||
ST0.d = L2T;
|
||||
#endif
|
||||
break;
|
||||
case 0xEA: /* FLDL2E */
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = L2E;
|
||||
#else
|
||||
ST0.d = L2E;
|
||||
#endif
|
||||
break;
|
||||
case 0xEB: /* FLDPI */
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = PI;
|
||||
#else
|
||||
ST0.d = PI;
|
||||
#endif
|
||||
break;
|
||||
case 0xEC: /* FLDLG2 */
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = LG2;
|
||||
#else
|
||||
ST0.d = LG2;
|
||||
#endif
|
||||
break;
|
||||
case 0xED: /* FLDLN2 */
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = LN2;
|
||||
#else
|
||||
ST0.d = LN2;
|
||||
#endif
|
||||
break;
|
||||
case 0xEE: /* FLDZ */
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = 0.0f;
|
||||
#else
|
||||
ST0.d = 0.0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0xF2: /* FTAN */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = tanf(ST0.f);
|
||||
fpu_do_push(emu);
|
||||
ST0.f = 1.0f;
|
||||
#else
|
||||
ST0.d = tan(ST0.d);
|
||||
fpu_do_push(emu);
|
||||
ST0.d = 1.0;
|
||||
#endif
|
||||
break;
|
||||
case 0xF3: /* FPATAN */
|
||||
#ifdef USE_FLOAT
|
||||
ST1.f = atan2f(ST1.f, ST0.f);
|
||||
#else
|
||||
ST1.d = atan2(ST1.d, ST0.d);
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
|
||||
case 0xF8: /* FPREM */
|
||||
#ifdef USE_FLOAT
|
||||
tmp32s = ST0.f / ST1.f;
|
||||
ST0.f -= ST1.f * tmp32s;
|
||||
#else
|
||||
tmp32s = ST0.d / ST1.d;
|
||||
ST0.d -= ST1.d * tmp32s;
|
||||
#endif
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
emu->sw.f.F87_C0 = (tmp32s&1);
|
||||
emu->sw.f.F87_C3 = ((tmp32s>>1)&1);
|
||||
@ -88,21 +139,41 @@
|
||||
break;
|
||||
|
||||
case 0xFA: /* FSQRT */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = sqrtf(ST0.f);
|
||||
#else
|
||||
ST0.d = sqrt(ST0.d);
|
||||
#endif
|
||||
break;
|
||||
case 0xFB: /* FSINCOS */
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
sincosf(ST1.f, &ST1.f, &ST0.f);
|
||||
#else
|
||||
sincos(ST1.d, &ST1.d, &ST0.d);
|
||||
#endif
|
||||
break;
|
||||
case 0xFC: /* FRNDINT */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = fpu_round(emu, ST0.f);
|
||||
#else
|
||||
ST0.d = fpu_round(emu, ST0.d);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0xFE: /* FSIN */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = sinf(ST0.f);
|
||||
#else
|
||||
ST0.d = sin(ST0.d);
|
||||
#endif
|
||||
break;
|
||||
case 0xFF: /* FCOS */
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = cosf(ST0.f);
|
||||
#else
|
||||
ST0.d = cos(ST0.d);
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
||||
@ -139,15 +210,27 @@
|
||||
case 0: /* FLD ST0, Ed float */
|
||||
GET_ED;
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = *(float*)ED;
|
||||
#else
|
||||
ST0.d = *(float*)ED;
|
||||
#endif
|
||||
break;
|
||||
case 2: /* FST Ed, ST0 */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
*(float*)ED = ST0.f;
|
||||
#else
|
||||
*(float*)ED = ST0.d;
|
||||
#endif
|
||||
break;
|
||||
case 3: /* FSTP Ed, ST0 */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
*(float*)ED = ST0.f;
|
||||
#else
|
||||
*(float*)ED = ST0.d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 4: /* FLDENV m */
|
||||
|
28
src/runda.h
28
src/runda.h
@ -51,7 +51,11 @@
|
||||
break;
|
||||
|
||||
case 0xE9: /* FUCOMPP */
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcom(emu, ST1.f);
|
||||
#else
|
||||
fpu_fcom(emu, ST1.d); // bad, should handle QNaN and IA interrupt
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
@ -72,27 +76,51 @@
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: /* FIADD ST0, Ed int */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f += ED->sdword[0];
|
||||
#else
|
||||
ST0.d += ED->sdword[0];
|
||||
#endif
|
||||
break;
|
||||
case 1: /* FIMUL ST0, Ed int */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f *= ED->sdword[0];
|
||||
#else
|
||||
ST0.d *= ED->sdword[0];
|
||||
#endif
|
||||
break;
|
||||
case 4: /* FISUB ST0, Ed int */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f -= ED->sdword[0];
|
||||
#else
|
||||
ST0.d -= ED->sdword[0];
|
||||
#endif
|
||||
break;
|
||||
case 5: /* FISUBR ST0, Ed int */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = ED->sdword[0] - ST0.f;
|
||||
#else
|
||||
ST0.d = ED->sdword[0] - ST0.d;
|
||||
#endif
|
||||
break;
|
||||
case 6: /* FIDIV ST0, Ed int */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f /= ED->sdword[0];
|
||||
#else
|
||||
ST0.d /= ED->sdword[0];
|
||||
#endif
|
||||
break;
|
||||
case 7: /* FIDIVR ST0, Ed int */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = ED->sdword[0] / ST0.f;
|
||||
#else
|
||||
ST0.d = ED->sdword[0] / ST0.d;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
goto _default;
|
||||
|
69
src/rundb.h
69
src/rundb.h
@ -73,7 +73,11 @@
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcomi(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcomi(emu, ST(nextop&7).d); // bad, should handle QNaN and IA interrupt
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0xF0: /* FCOMI ST0, STx */
|
||||
@ -84,7 +88,11 @@
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcomi(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcomi(emu, ST(nextop&7).d);
|
||||
#endif
|
||||
break;
|
||||
case 0xE0:
|
||||
case 0xE1:
|
||||
@ -98,18 +106,48 @@
|
||||
case 0: /* FILD ST0, Gd */
|
||||
GET_ED;
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = ED->sdword[0];
|
||||
#else
|
||||
ST0.d = ED->sdword[0];
|
||||
#endif
|
||||
break;
|
||||
case 1: /* FISTTP Ed, ST0 */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
tmp32s = ST0.f; // TODO: Handling of FPU Exception
|
||||
if(tmp32s==0x7fffffff && isgreater(ST0.f, (float)(int32_t)0x7fffffff))
|
||||
tmp32s = 0x80000000;
|
||||
#else
|
||||
tmp32s = ST0.d; // TODO: Handling of FPU Exception
|
||||
if(tmp32s==0x7fffffff && isgreater(ST0.d, (double)(int32_t)0x7fffffff))
|
||||
tmp32s = 0x80000000;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
ED->sdword[0] = tmp32s;
|
||||
break;
|
||||
case 2: /* FIST Ed, ST0 */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
if(isgreater(ST0.f, (float)(int32_t)0x7fffffff) || isless(ST0.f, -(float)(int32_t)0x7fffffff))
|
||||
ED->sdword[0] = 0x80000000;
|
||||
else {
|
||||
switch(emu->round) {
|
||||
case ROUND_Nearest:
|
||||
ED->sdword[0] = floorf(ST0.f+0.5);
|
||||
break;
|
||||
case ROUND_Down:
|
||||
ED->sdword[0] = floorf(ST0.f);
|
||||
break;
|
||||
case ROUND_Up:
|
||||
ED->sdword[0] = ceilf(ST0.f);
|
||||
break;
|
||||
case ROUND_Chop:
|
||||
ED->sdword[0] = ST0.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(isgreater(ST0.d, (double)(int32_t)0x7fffffff) || isless(ST0.d, -(double)(int32_t)0x7fffffff))
|
||||
ED->sdword[0] = 0x80000000;
|
||||
else {
|
||||
@ -128,9 +166,30 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 3: /* FISTP Ed, ST0 */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
if(isgreater(ST0.f, (float)(int32_t)0x7fffffff) || isless(ST0.f, -(float)(int32_t)0x7fffffff))
|
||||
ED->sdword[0] = 0x80000000;
|
||||
else {
|
||||
switch(emu->round) {
|
||||
case ROUND_Nearest:
|
||||
ED->sdword[0] = floorf(ST0.f+0.5);
|
||||
break;
|
||||
case ROUND_Down:
|
||||
ED->sdword[0] = floorf(ST0.f);
|
||||
break;
|
||||
case ROUND_Up:
|
||||
ED->sdword[0] = ceilf(ST0.f);
|
||||
break;
|
||||
case ROUND_Chop:
|
||||
ED->sdword[0] = ST0.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(isgreater(ST0.d, (double)(int32_t)0x7fffffff) || isless(ST0.d, -(double)(int32_t)0x7fffffff))
|
||||
ED->sdword[0] = 0x80000000;
|
||||
else {
|
||||
@ -149,19 +208,29 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 5: /* FLD ST0, Gt */
|
||||
GET_ED;
|
||||
fpu_do_push(emu);
|
||||
memcpy(&STld(0).ld, ED, 10);
|
||||
#ifdef USE_FLOAT
|
||||
LD2D(&STld(0), &d);
|
||||
ST0.f = d;
|
||||
#else
|
||||
LD2D(&STld(0), &ST(0).d);
|
||||
#endif
|
||||
STld(0).ref = ST0.ll;
|
||||
break;
|
||||
case 7: /* FSTP tbyte */
|
||||
GET_ED;
|
||||
if(ST0.ll!=STld(0).ref)
|
||||
#ifdef USE_FLOAT
|
||||
{d = ST0.f; D2LD(&d, ED);}
|
||||
#else
|
||||
D2LD(&ST0.d, ED);
|
||||
#endif
|
||||
else
|
||||
memcpy(ED, &STld(0).ld, 10);
|
||||
fpu_do_pop(emu);
|
||||
|
88
src/rundc.h
88
src/rundc.h
@ -8,7 +8,11 @@
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7: /* FADD */
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f += ST0.f;
|
||||
#else
|
||||
ST(nextop&7).d += ST0.d;
|
||||
#endif
|
||||
break;
|
||||
case 0xC8:
|
||||
case 0xC9:
|
||||
@ -18,7 +22,11 @@
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF: /* FMUL */
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f *= ST0.f;
|
||||
#else
|
||||
ST(nextop&7).d *= ST0.d;
|
||||
#endif
|
||||
break;
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
@ -28,7 +36,11 @@
|
||||
case 0xD5:
|
||||
case 0xD6:
|
||||
case 0xD7: /* FCOM */
|
||||
fpu_fcom(emu, ST(nextop&7).d); // TODO: is this ok?
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcom(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcom(emu, ST(nextop&7).d);
|
||||
#endif
|
||||
break;
|
||||
case 0xD8:
|
||||
case 0xD9:
|
||||
@ -38,7 +50,11 @@
|
||||
case 0xDD:
|
||||
case 0xDE:
|
||||
case 0xDF: /* FCOMP */
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcom(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcom(emu, ST(nextop&7).d); // TODO: is this ok?
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 0xE0:
|
||||
@ -49,7 +65,11 @@
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7: /* FSUBR */
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f = ST0.f -ST(nextop&7).f;
|
||||
#else
|
||||
ST(nextop&7).d = ST0.d -ST(nextop&7).d;
|
||||
#endif
|
||||
break;
|
||||
case 0xE8:
|
||||
case 0xE9:
|
||||
@ -59,7 +79,11 @@
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF: /* FSUB */
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f -= ST0.f;
|
||||
#else
|
||||
ST(nextop&7).d -= ST0.d;
|
||||
#endif
|
||||
break;
|
||||
case 0xF0:
|
||||
case 0xF1:
|
||||
@ -69,7 +93,11 @@
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7: /* FDIVR */
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f = ST0.f / ST(nextop&7).f;
|
||||
#else
|
||||
ST(nextop&7).d = ST0.d / ST(nextop&7).d;
|
||||
#endif
|
||||
break;
|
||||
case 0xF8:
|
||||
case 0xF9:
|
||||
@ -79,26 +107,48 @@
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF: /* FDIV */
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f /= ST0.f;
|
||||
#else
|
||||
ST(nextop&7).d /= ST0.d;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
GET_ED;
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: /* FADD ST0, double */
|
||||
#ifdef USE_FLOAT
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.f += *(double*)ED;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.f += d;
|
||||
}
|
||||
#else
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.d += *(double*)ED;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.d += d;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 1: /* FMUL ST0, double */
|
||||
#ifdef USE_FLOAT
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.f *= *(double*)ED;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.f *= d;
|
||||
}
|
||||
#else
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.d *= *(double*)ED;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.d *= d;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 2: /* FCOM ST0, double */
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
@ -118,36 +168,72 @@
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 4: /* FSUB ST0, double */
|
||||
#ifdef USE_FLOAT
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.f -= *(double*)ED;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.f -= d;
|
||||
}
|
||||
#else
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.d -= *(double*)ED;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.d -= d;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 5: /* FSUBR ST0, double */
|
||||
#ifdef USE_FLOAT
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.f = *(double*)ED - ST0.f;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.f = d - ST0.f;
|
||||
}
|
||||
#else
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.d = *(double*)ED - ST0.d;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.d = d - ST0.d;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 6: /* FDIV ST0, double */
|
||||
#ifdef USE_FLOAT
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.f /= *(double*)ED;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.f /= d;
|
||||
}
|
||||
#else
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.d /= *(double*)ED;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.d /= d;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 7: /* FDIVR ST0, double */
|
||||
#ifdef USE_FLOAT
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.f = *(double*)ED / ST0.f;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.f = d / ST0.f;
|
||||
}
|
||||
#else
|
||||
if(!(((uintptr_t)ED)&7))
|
||||
ST0.d = *(double*)ED / ST0.d;
|
||||
else {
|
||||
*(uint64_t*)&d = *(uint64_t*)ED;
|
||||
ST0.d = d / ST0.d;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
goto _default;
|
||||
|
37
src/rundd.h
37
src/rundd.h
@ -40,7 +40,11 @@
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcom(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcom(emu, ST(nextop&7).d); // bad, should handle QNaN and IA interrupt
|
||||
#endif
|
||||
break;
|
||||
case 0xE8: /* FUCOMP ST0, STx */
|
||||
case 0xE9:
|
||||
@ -50,7 +54,11 @@
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcom(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcom(emu, ST(nextop&7).d); // bad, should handle QNaN and IA interrupt
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
|
||||
@ -85,20 +93,39 @@
|
||||
case 0: /* FLD double */
|
||||
GET_ED;
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
*(uint64_t*)&d = *(int64_t*)ED;
|
||||
ST0.f = d;
|
||||
#else
|
||||
ST0.ll = *(int64_t*)ED;
|
||||
#endif
|
||||
break;
|
||||
case 1: /* FISTTP ED qword */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
*(int64_t*)ED = ST0.f;
|
||||
#else
|
||||
*(int64_t*)ED = ST0.d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 2: /* FST double */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
d = ST0.f;
|
||||
*(int64_t*)ED = *(uint64_t*)&d;
|
||||
#else
|
||||
*(int64_t*)ED = ST0.ll;
|
||||
#endif
|
||||
break;
|
||||
case 3: /* FSTP double */
|
||||
GET_ED;
|
||||
#ifdef USE_FLOAT
|
||||
d = ST0.f;
|
||||
*(int64_t*)ED = *(uint64_t*)&d;
|
||||
#else
|
||||
*(int64_t*)ED = ST0.ll;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 4: /* FRSTOR m108byte */
|
||||
@ -109,7 +136,12 @@
|
||||
char* p =(char*)ED;
|
||||
p += 28;
|
||||
for (int i=0; i<8; ++i) {
|
||||
#ifdef USE_FLOAT
|
||||
d = ST(i).f;
|
||||
LD2D(p, &d);
|
||||
#else
|
||||
LD2D(p, &ST(i).d);
|
||||
#endif
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
@ -124,7 +156,12 @@
|
||||
char* p =(char*)ED;
|
||||
p += 28;
|
||||
for (int i=0; i<8; ++i) {
|
||||
#ifdef USE_FLOAT
|
||||
D2LD(&d, p);
|
||||
ST(i).f = d;
|
||||
#else
|
||||
D2LD(&ST(i).d, p);
|
||||
#endif
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
|
71
src/runde.h
71
src/runde.h
@ -1,7 +1,11 @@
|
||||
nextop = F8;
|
||||
switch (nextop) {
|
||||
case 0xC1: /* FADDP ST1, ST0 */
|
||||
#ifdef USE_FLOAT
|
||||
ST(1).f += ST0.f;
|
||||
#else
|
||||
ST(1).d += ST0.d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 0xC0: /* FADDP STx, ST0 */
|
||||
@ -11,11 +15,19 @@
|
||||
case 0xC5:
|
||||
case 0xC6:
|
||||
case 0xC7:
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f += ST0.f;
|
||||
#else
|
||||
ST(nextop&7).d += ST0.d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 0xC9: /* FMULP ST1, ST0 */
|
||||
#ifdef USE_FLOAT
|
||||
ST1.f *= ST0.f;
|
||||
#else
|
||||
ST1.d *= ST0.d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 0xC8: /* FMULP STx, ST0 */
|
||||
@ -25,11 +37,19 @@
|
||||
case 0xCD:
|
||||
case 0xCE:
|
||||
case 0xCF:
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f *= ST0.f;
|
||||
#else
|
||||
ST(nextop&7).d *= ST0.d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 0xD9: /* FCOMPP */
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcom(emu, ST1.f);
|
||||
#else
|
||||
fpu_fcom(emu, ST1.d);
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
@ -45,11 +65,19 @@
|
||||
case 0xE5:
|
||||
case 0xE6:
|
||||
case 0xE7:
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f = ST0.f - ST(nextop&7).f;
|
||||
#else
|
||||
ST(nextop&7).d = ST0.d - ST(nextop&7).d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 0xE9: /* FSUBP ST1, ST0 */
|
||||
#ifdef USE_FLOAT
|
||||
ST1.f -= ST0.f;
|
||||
#else
|
||||
ST1.d -= ST0.d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 0xE8: /* FSUBP STx, ST0 */
|
||||
@ -59,12 +87,13 @@
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f -= ST0.f;
|
||||
#else
|
||||
ST(nextop&7).d -= ST0.d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
/*ST(1).d = ST0.d / ST(1).d;
|
||||
fpu_do_pop(emu);
|
||||
break;*/
|
||||
case 0xF0: /* FDIVRP STx, ST0 */
|
||||
case 0xF1: /* FDIVRP ST1, ST0 */
|
||||
case 0xF2:
|
||||
@ -73,13 +102,13 @@
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f = ST0.f / ST(nextop&7).f;
|
||||
#else
|
||||
ST(nextop&7).d = ST0.d / ST(nextop&7).d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
/*d = ST0.d;
|
||||
fpu_do_pop(emu);
|
||||
ST0.d /= d;
|
||||
break;*/
|
||||
case 0xF8: /* FDIVP STx, ST0 */
|
||||
case 0xF9: /* FDIVP ST1, ST0 */
|
||||
case 0xFA:
|
||||
@ -88,7 +117,11 @@
|
||||
case 0xFD:
|
||||
case 0xFE:
|
||||
case 0xFF:
|
||||
#ifdef USE_FLOAT
|
||||
ST(nextop&7).f /= ST0.f;
|
||||
#else
|
||||
ST(nextop&7).d /= ST0.d;
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
|
||||
@ -113,27 +146,51 @@
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: /* FIADD ST0, Ew int */
|
||||
GET_EW;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f += EW->sword[0];
|
||||
#else
|
||||
ST0.d += EW->sword[0];
|
||||
#endif
|
||||
break;
|
||||
case 1: /* FIMUL ST0, Ew int */
|
||||
GET_EW;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f *= EW->sword[0];
|
||||
#else
|
||||
ST0.d *= EW->sword[0];
|
||||
#endif
|
||||
break;
|
||||
case 4: /* FISUB ST0, Ew int */
|
||||
GET_EW;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f -= EW->sword[0];
|
||||
#else
|
||||
ST0.d -= EW->sword[0];
|
||||
#endif
|
||||
break;
|
||||
case 5: /* FISUBR ST0, Ew int */
|
||||
GET_EW;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = EW->sword[0] - ST0.f;
|
||||
#else
|
||||
ST0.d = EW->sword[0] - ST0.d;
|
||||
#endif
|
||||
break;
|
||||
case 6: /* FIDIV ST0, Ew int */
|
||||
GET_EW;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f /= EW->sword[0];
|
||||
#else
|
||||
ST0.d /= EW->sword[0];
|
||||
#endif
|
||||
break;
|
||||
case 7: /* FIDIVR ST0, Ew int */
|
||||
GET_EW;
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = EW->sword[0] / ST0.f;
|
||||
#else
|
||||
ST0.d = EW->sword[0] / ST0.d;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
goto _default;
|
||||
|
69
src/rundf.h
69
src/rundf.h
@ -13,7 +13,11 @@
|
||||
case 0xED:
|
||||
case 0xEE:
|
||||
case 0xEF:
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcomi(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcomi(emu, ST(nextop&7).d); // bad, should handle QNaN and IA interrupt
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
|
||||
@ -25,7 +29,11 @@
|
||||
case 0xF5:
|
||||
case 0xF6:
|
||||
case 0xF7:
|
||||
#ifdef USE_FLOAT
|
||||
fpu_fcomi(emu, ST(nextop&7).f);
|
||||
#else
|
||||
fpu_fcomi(emu, ST(nextop&7).d);
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
|
||||
@ -84,16 +92,44 @@
|
||||
GET_EW;
|
||||
tmp16s = EW->sword[0];
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = tmp16s;
|
||||
#else
|
||||
ST0.d = tmp16s;
|
||||
#endif
|
||||
break;
|
||||
case 1: /* FISTTP Ew, ST0 */
|
||||
GET_EW;
|
||||
#ifdef USE_FLOAT
|
||||
tmp16s = ST0.f;
|
||||
#else
|
||||
tmp16s = ST0.d;
|
||||
#endif
|
||||
EW->sword[0] = tmp16s;
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 2: /* FIST Ew, ST0 */
|
||||
GET_EW;
|
||||
#ifdef USE_FLOAT
|
||||
if(isgreater(ST0.f, (float)(int32_t)0x7fff) || isless(ST0.f, -(float)(int32_t)0x7fff))
|
||||
EW->sword[0] = 0x8000;
|
||||
else {
|
||||
switch(emu->round) {
|
||||
case ROUND_Nearest:
|
||||
EW->sword[0] = floorf(ST0.f+0.5);
|
||||
break;
|
||||
case ROUND_Down:
|
||||
EW->sword[0] = floorf(ST0.f);
|
||||
break;
|
||||
case ROUND_Up:
|
||||
EW->sword[0] = ceilf(ST0.f);
|
||||
break;
|
||||
case ROUND_Chop:
|
||||
EW->sword[0] = ST0.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(isgreater(ST0.d, (double)(int32_t)0x7fff) || isless(ST0.d, -(double)(int32_t)0x7fff))
|
||||
EW->sword[0] = 0x8000;
|
||||
else {
|
||||
@ -112,9 +148,30 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 3: /* FISTP Ew, ST0 */
|
||||
GET_EW;
|
||||
#ifdef USE_FLOAT
|
||||
if(isgreater(ST0.f, (float)(int32_t)0x7fff) || isless(ST0.f, -(float)(int32_t)0x7fff))
|
||||
EW->sword[0] = 0x8000;
|
||||
else {
|
||||
switch(emu->round) {
|
||||
case ROUND_Nearest:
|
||||
EW->sword[0] = floorf(ST0.f+0.5);
|
||||
break;
|
||||
case ROUND_Down:
|
||||
EW->sword[0] = floorf(ST0.f);
|
||||
break;
|
||||
case ROUND_Up:
|
||||
EW->sword[0] = ceilf(ST0.f);
|
||||
break;
|
||||
case ROUND_Chop:
|
||||
EW->sword[0] = ST0.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(isgreater(ST0.d, (double)(int32_t)0x7fff) || isless(ST0.d, -(double)(int32_t)0x7fff))
|
||||
EW->sword[0] = 0x8000;
|
||||
else {
|
||||
@ -133,6 +190,7 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
case 4: /* FBLD ST0, tbytes */
|
||||
@ -144,7 +202,11 @@
|
||||
GET_ED;
|
||||
tmp64s = *(int64_t*)ED;
|
||||
fpu_do_push(emu);
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = tmp64s;
|
||||
#else
|
||||
ST0.d = tmp64s;
|
||||
#endif
|
||||
STll(0).ll = tmp64s;
|
||||
STll(0).ref = ST0.ll;
|
||||
break;
|
||||
@ -158,10 +220,17 @@
|
||||
if(STll(0).ref==ST(0).ll) {
|
||||
*(int64_t*)ED = STll(0).ll;
|
||||
} else {
|
||||
#ifdef USE_FLOAT
|
||||
if(isgreater(ST0.f, (float)(int64_t)0x7fffffffffffffffLL) || isless(ST0.f, (float)(int64_t)0x8000000000000000LL))
|
||||
*(int64_t*)ED = 0x8000000000000000LL;
|
||||
else
|
||||
*(int64_t*)ED = (int64_t)ST0.f;
|
||||
#else
|
||||
if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, (double)(int64_t)0x8000000000000000LL))
|
||||
*(int64_t*)ED = 0x8000000000000000LL;
|
||||
else
|
||||
*(int64_t*)ED = (int64_t)ST0.d;
|
||||
#endif
|
||||
}
|
||||
fpu_do_pop(emu);
|
||||
break;
|
||||
|
@ -17,6 +17,12 @@ typedef union ui64_s {
|
||||
uint32_t d[2];
|
||||
} ui64_t;
|
||||
|
||||
#ifdef USE_FLOAT
|
||||
#define ST0val ST0.f
|
||||
#else
|
||||
#define ST0val ST0.d
|
||||
#endif
|
||||
|
||||
typedef int32_t (*iF_t)();
|
||||
typedef void (*vFE_t)(x86emu_t*);
|
||||
typedef void (*vFv_t)(void);
|
||||
@ -818,11 +824,11 @@ void uFu(x86emu_t *emu, uintptr_t fcn) { uFu_t fn = (uFu_t)fcn; R_EAX=(uint32_t)
|
||||
void uFp(x86emu_t *emu, uintptr_t fcn) { uFp_t fn = (uFp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4)); }
|
||||
void UFv(x86emu_t *emu, uintptr_t fcn) { UFv_t fn = (UFv_t)fcn; ui64_t r; r.u=(uint64_t)fn(); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void UFp(x86emu_t *emu, uintptr_t fcn) { UFp_t fn = (UFp_t)fcn; ui64_t r; r.u=(uint64_t)fn(*(void**)(R_ESP + 4)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void fFi(x86emu_t *emu, uintptr_t fcn) { fFi_t fn = (fFi_t)fcn; float fl=fn(*(int32_t*)(R_ESP + 4)); fpu_do_push(emu); ST0.d = fl; }
|
||||
void fFf(x86emu_t *emu, uintptr_t fcn) { fFf_t fn = (fFf_t)fcn; float fl=fn(*(float*)(R_ESP + 4)); fpu_do_push(emu); ST0.d = fl; }
|
||||
void dFi(x86emu_t *emu, uintptr_t fcn) { dFi_t fn = (dFi_t)fcn; double db=fn(*(int32_t*)(R_ESP + 4)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFd(x86emu_t *emu, uintptr_t fcn) { dFd_t fn = (dFd_t)fcn; double db=fn(*(double*)(R_ESP + 4)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFp(x86emu_t *emu, uintptr_t fcn) { dFp_t fn = (dFp_t)fcn; double db=fn(*(void**)(R_ESP + 4)); fpu_do_push(emu); ST0.d = db; }
|
||||
void fFi(x86emu_t *emu, uintptr_t fcn) { fFi_t fn = (fFi_t)fcn; float fl=fn(*(int32_t*)(R_ESP + 4)); fpu_do_push(emu); ST0val = fl; }
|
||||
void fFf(x86emu_t *emu, uintptr_t fcn) { fFf_t fn = (fFf_t)fcn; float fl=fn(*(float*)(R_ESP + 4)); fpu_do_push(emu); ST0val = fl; }
|
||||
void dFi(x86emu_t *emu, uintptr_t fcn) { dFi_t fn = (dFi_t)fcn; double db=fn(*(int32_t*)(R_ESP + 4)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFd(x86emu_t *emu, uintptr_t fcn) { dFd_t fn = (dFd_t)fcn; double db=fn(*(double*)(R_ESP + 4)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFp(x86emu_t *emu, uintptr_t fcn) { dFp_t fn = (dFp_t)fcn; double db=fn(*(void**)(R_ESP + 4)); fpu_do_push(emu); ST0val = db; }
|
||||
void pFE(x86emu_t *emu, uintptr_t fcn) { pFE_t fn = (pFE_t)fcn; R_EAX=(uintptr_t)fn(emu); }
|
||||
void pFv(x86emu_t *emu, uintptr_t fcn) { pFv_t fn = (pFv_t)fcn; R_EAX=(uintptr_t)fn(); }
|
||||
void pFi(x86emu_t *emu, uintptr_t fcn) { pFi_t fn = (pFi_t)fcn; R_EAX=(uintptr_t)fn(*(int32_t*)(R_ESP + 4)); }
|
||||
@ -882,18 +888,18 @@ void uFpi(x86emu_t *emu, uintptr_t fcn) { uFpi_t fn = (uFpi_t)fcn; R_EAX=(uint32
|
||||
void uFpu(x86emu_t *emu, uintptr_t fcn) { uFpu_t fn = (uFpu_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8)); }
|
||||
void uFpp(x86emu_t *emu, uintptr_t fcn) { uFpp_t fn = (uFpp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8)); }
|
||||
void UFEp(x86emu_t *emu, uintptr_t fcn) { UFEp_t fn = (UFEp_t)fcn; ui64_t r; r.u=(uint64_t)fn(emu, *(void**)(R_ESP + 4)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void fFfi(x86emu_t *emu, uintptr_t fcn) { fFfi_t fn = (fFfi_t)fcn; float fl=fn(*(float*)(R_ESP + 4), *(int32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0.d = fl; }
|
||||
void fFff(x86emu_t *emu, uintptr_t fcn) { fFff_t fn = (fFff_t)fcn; float fl=fn(*(float*)(R_ESP + 4), *(float*)(R_ESP + 8)); fpu_do_push(emu); ST0.d = fl; }
|
||||
void fFfp(x86emu_t *emu, uintptr_t fcn) { fFfp_t fn = (fFfp_t)fcn; float fl=fn(*(float*)(R_ESP + 4), *(void**)(R_ESP + 8)); fpu_do_push(emu); ST0.d = fl; }
|
||||
void fFpp(x86emu_t *emu, uintptr_t fcn) { fFpp_t fn = (fFpp_t)fcn; float fl=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8)); fpu_do_push(emu); ST0.d = fl; }
|
||||
void dFEp(x86emu_t *emu, uintptr_t fcn) { dFEp_t fn = (dFEp_t)fcn; double db=fn(emu, *(void**)(R_ESP + 4)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFuu(x86emu_t *emu, uintptr_t fcn) { dFuu_t fn = (dFuu_t)fcn; double db=fn(*(uint32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFdi(x86emu_t *emu, uintptr_t fcn) { dFdi_t fn = (dFdi_t)fcn; double db=fn(*(double*)(R_ESP + 4), *(int32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFdd(x86emu_t *emu, uintptr_t fcn) { dFdd_t fn = (dFdd_t)fcn; double db=fn(*(double*)(R_ESP + 4), *(double*)(R_ESP + 12)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFdp(x86emu_t *emu, uintptr_t fcn) { dFdp_t fn = (dFdp_t)fcn; double db=fn(*(double*)(R_ESP + 4), *(void**)(R_ESP + 12)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFpi(x86emu_t *emu, uintptr_t fcn) { dFpi_t fn = (dFpi_t)fcn; double db=fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFpp(x86emu_t *emu, uintptr_t fcn) { dFpp_t fn = (dFpp_t)fcn; double db=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8)); fpu_do_push(emu); ST0.d = db; }
|
||||
void LFLp(x86emu_t *emu, uintptr_t fcn) { LFLp_t fn = (LFLp_t)fcn; double db=fn(FromLD((void*)(R_ESP + 4)), *(void**)(R_ESP + 16)); fpu_do_push(emu); ST0.d = db; }
|
||||
void fFfi(x86emu_t *emu, uintptr_t fcn) { fFfi_t fn = (fFfi_t)fcn; float fl=fn(*(float*)(R_ESP + 4), *(int32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0val = fl; }
|
||||
void fFff(x86emu_t *emu, uintptr_t fcn) { fFff_t fn = (fFff_t)fcn; float fl=fn(*(float*)(R_ESP + 4), *(float*)(R_ESP + 8)); fpu_do_push(emu); ST0val = fl; }
|
||||
void fFfp(x86emu_t *emu, uintptr_t fcn) { fFfp_t fn = (fFfp_t)fcn; float fl=fn(*(float*)(R_ESP + 4), *(void**)(R_ESP + 8)); fpu_do_push(emu); ST0val = fl; }
|
||||
void fFpp(x86emu_t *emu, uintptr_t fcn) { fFpp_t fn = (fFpp_t)fcn; float fl=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8)); fpu_do_push(emu); ST0val = fl; }
|
||||
void dFEp(x86emu_t *emu, uintptr_t fcn) { dFEp_t fn = (dFEp_t)fcn; double db=fn(emu, *(void**)(R_ESP + 4)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFuu(x86emu_t *emu, uintptr_t fcn) { dFuu_t fn = (dFuu_t)fcn; double db=fn(*(uint32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFdi(x86emu_t *emu, uintptr_t fcn) { dFdi_t fn = (dFdi_t)fcn; double db=fn(*(double*)(R_ESP + 4), *(int32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFdd(x86emu_t *emu, uintptr_t fcn) { dFdd_t fn = (dFdd_t)fcn; double db=fn(*(double*)(R_ESP + 4), *(double*)(R_ESP + 12)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFdp(x86emu_t *emu, uintptr_t fcn) { dFdp_t fn = (dFdp_t)fcn; double db=fn(*(double*)(R_ESP + 4), *(void**)(R_ESP + 12)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFpi(x86emu_t *emu, uintptr_t fcn) { dFpi_t fn = (dFpi_t)fcn; double db=fn(*(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFpp(x86emu_t *emu, uintptr_t fcn) { dFpp_t fn = (dFpp_t)fcn; double db=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8)); fpu_do_push(emu); ST0val = db; }
|
||||
void LFLp(x86emu_t *emu, uintptr_t fcn) { LFLp_t fn = (LFLp_t)fcn; double db=fn(FromLD((void*)(R_ESP + 4)), *(void**)(R_ESP + 16)); fpu_do_push(emu); ST0val = db; }
|
||||
void pFEp(x86emu_t *emu, uintptr_t fcn) { pFEp_t fn = (pFEp_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4)); }
|
||||
void pFii(x86emu_t *emu, uintptr_t fcn) { pFii_t fn = (pFii_t)fcn; R_EAX=(uintptr_t)fn(*(int32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8)); }
|
||||
void pFip(x86emu_t *emu, uintptr_t fcn) { pFip_t fn = (pFip_t)fcn; R_EAX=(uintptr_t)fn(*(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8)); }
|
||||
@ -1005,13 +1011,13 @@ void uFppi(x86emu_t *emu, uintptr_t fcn) { uFppi_t fn = (uFppi_t)fcn; R_EAX=(uin
|
||||
void uFppu(x86emu_t *emu, uintptr_t fcn) { uFppu_t fn = (uFppu_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); }
|
||||
void uFppp(x86emu_t *emu, uintptr_t fcn) { uFppp_t fn = (uFppp_t)fcn; R_EAX=(uint32_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12)); }
|
||||
void UFppi(x86emu_t *emu, uintptr_t fcn) { UFppi_t fn = (UFppi_t)fcn; ui64_t r; r.u=(uint64_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
|
||||
void fFuii(x86emu_t *emu, uintptr_t fcn) { fFuii_t fn = (fFuii_t)fcn; float fl=fn(*(uint32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0.d = fl; }
|
||||
void fFppu(x86emu_t *emu, uintptr_t fcn) { fFppu_t fn = (fFppu_t)fcn; float fl=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0.d = fl; }
|
||||
void fFppp(x86emu_t *emu, uintptr_t fcn) { fFppp_t fn = (fFppp_t)fcn; float fl=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12)); fpu_do_push(emu); ST0.d = fl; }
|
||||
void dFEpi(x86emu_t *emu, uintptr_t fcn) { dFEpi_t fn = (dFEpi_t)fcn; double db=fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFppu(x86emu_t *emu, uintptr_t fcn) { dFppu_t fn = (dFppu_t)fcn; double db=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0.d = db; }
|
||||
void dFppp(x86emu_t *emu, uintptr_t fcn) { dFppp_t fn = (dFppp_t)fcn; double db=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12)); fpu_do_push(emu); ST0.d = db; }
|
||||
void DFppu(x86emu_t *emu, uintptr_t fcn) { DFppu_t fn = (DFppu_t)fcn; long double ld=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0.d = ld; }
|
||||
void fFuii(x86emu_t *emu, uintptr_t fcn) { fFuii_t fn = (fFuii_t)fcn; float fl=fn(*(uint32_t*)(R_ESP + 4), *(int32_t*)(R_ESP + 8), *(int32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0val = fl; }
|
||||
void fFppu(x86emu_t *emu, uintptr_t fcn) { fFppu_t fn = (fFppu_t)fcn; float fl=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0val = fl; }
|
||||
void fFppp(x86emu_t *emu, uintptr_t fcn) { fFppp_t fn = (fFppp_t)fcn; float fl=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12)); fpu_do_push(emu); ST0val = fl; }
|
||||
void dFEpi(x86emu_t *emu, uintptr_t fcn) { dFEpi_t fn = (dFEpi_t)fcn; double db=fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFppu(x86emu_t *emu, uintptr_t fcn) { dFppu_t fn = (dFppu_t)fcn; double db=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0val = db; }
|
||||
void dFppp(x86emu_t *emu, uintptr_t fcn) { dFppp_t fn = (dFppp_t)fcn; double db=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(void**)(R_ESP + 12)); fpu_do_push(emu); ST0val = db; }
|
||||
void DFppu(x86emu_t *emu, uintptr_t fcn) { DFppu_t fn = (DFppu_t)fcn; long double ld=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(uint32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0val = ld; }
|
||||
void pFEip(x86emu_t *emu, uintptr_t fcn) { pFEip_t fn = (pFEip_t)fcn; R_EAX=(uintptr_t)fn(emu, *(int32_t*)(R_ESP + 4), *(void**)(R_ESP + 8)); }
|
||||
void pFEpi(x86emu_t *emu, uintptr_t fcn) { pFEpi_t fn = (pFEpi_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(int32_t*)(R_ESP + 8)); }
|
||||
void pFEpp(x86emu_t *emu, uintptr_t fcn) { pFEpp_t fn = (pFEpp_t)fcn; R_EAX=(uintptr_t)fn(emu, *(void**)(R_ESP + 4), *(void**)(R_ESP + 8)); }
|
||||
|
@ -275,7 +275,11 @@ const char* DumpCPURegs(x86emu_t* emu, uintptr_t ip)
|
||||
// start with FPU regs...
|
||||
if(emu->fpu_stack) {
|
||||
for (int i=0; i<emu->fpu_stack; i++) {
|
||||
#ifdef USE_FLOAT
|
||||
sprintf(tmp, "ST%d=%f", i, emu->fpu[(emu->top+i)&7].f);
|
||||
#else
|
||||
sprintf(tmp, "ST%d=%f", i, emu->fpu[(emu->top+i)&7].d);
|
||||
#endif
|
||||
strcat(buff, tmp);
|
||||
int c = 10-strlen(tmp);
|
||||
if(c<1) c=1;
|
||||
|
@ -23,8 +23,14 @@ void fpu_fbst(x86emu_t* emu, uint8_t* d) {
|
||||
// very aproximative... but should not be much used...
|
||||
uint8_t p;
|
||||
uint8_t sign = 0x00;
|
||||
#ifdef USE_FLOAT
|
||||
double tmp, v = ST0.f;
|
||||
if(ST0.f<0.0f)
|
||||
#else
|
||||
double tmp, v = ST0.d;
|
||||
if(ST0.d<0.0) {
|
||||
if(ST0.d<0.0)
|
||||
#endif
|
||||
{
|
||||
sign = 0x80;
|
||||
v = -v;
|
||||
}
|
||||
@ -56,23 +62,47 @@ void fpu_fbld(x86emu_t* emu, uint8_t* s) {
|
||||
tmp += m * ((p>>4)&0x0f);
|
||||
m *= 10;
|
||||
}
|
||||
#ifdef USE_FLOAT
|
||||
ST0.f = tmp;
|
||||
p =*(s++);
|
||||
ST0.f += m * (p&0x0f);
|
||||
if(p&0x80)
|
||||
ST0.f = -ST0.f;
|
||||
#else
|
||||
ST0.d = tmp;
|
||||
p =*(s++);
|
||||
ST0.d += m * (p&0x0f);
|
||||
if(p&0x80)
|
||||
ST0.d = -ST0.d;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_FLOAT
|
||||
typedef union {
|
||||
double d;
|
||||
struct {
|
||||
uint32_t lower;
|
||||
uint32_t upper;
|
||||
} l;
|
||||
struct {
|
||||
float lower;
|
||||
float upper;
|
||||
} f;
|
||||
int64_t ll;
|
||||
} FPU_t;
|
||||
#else
|
||||
#define fpu_reg_t FPU_t
|
||||
#endif
|
||||
#define BIAS80 16383
|
||||
#define BIAS64 1023
|
||||
// long double (80bits) -> double (64bits)
|
||||
void LD2D(void* ld, void* d)
|
||||
{
|
||||
fpu_reg_t result;
|
||||
FPU_t result;
|
||||
#pragma pack(push, 1)
|
||||
struct {
|
||||
fpu_reg_t f;
|
||||
FPU_t f;
|
||||
int16_t b;
|
||||
} val;
|
||||
#pragma pack(pop)
|
||||
@ -138,11 +168,11 @@ void D2LD(void* d, void* ld)
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct {
|
||||
fpu_reg_t f;
|
||||
FPU_t f;
|
||||
int16_t b;
|
||||
} val;
|
||||
#pragma pack(pop)
|
||||
fpu_reg_t s;
|
||||
FPU_t s;
|
||||
s.ll = *(uint64_t*)d; // use memcpy to avoid risk of Bus Error?
|
||||
// do special value first
|
||||
if((s.ll&0x7fffffffffffffffLL)==0) {
|
||||
@ -188,7 +218,6 @@ double FromLD(void* ld)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void fpu_loadenv(x86emu_t* emu, char* p, int b16)
|
||||
{
|
||||
emu->cw = *(uint16_t*)p;
|
||||
|
@ -50,9 +50,28 @@ static inline void fpu_do_pop(x86emu_t* emu)
|
||||
|
||||
void reset_fpu(x86emu_t* emu);
|
||||
|
||||
#ifdef USE_FLOAT
|
||||
static inline void fpu_fcom(x86emu_t* emu, float b)
|
||||
#else
|
||||
static inline void fpu_fcom(x86emu_t* emu, double b)
|
||||
#endif
|
||||
{
|
||||
emu->sw.f.F87_C1 = 0;
|
||||
#ifdef USE_FLOAT
|
||||
if(isnan(ST0.f) || isnan(b)) {
|
||||
emu->sw.f.F87_C0 = 1;
|
||||
emu->sw.f.F87_C2 = 1;
|
||||
emu->sw.f.F87_C3 = 1;
|
||||
} else if (isgreater(ST0.f, b)) {
|
||||
emu->sw.f.F87_C0 = 0;
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
emu->sw.f.F87_C3 = 0;
|
||||
} else if (isless(ST0.f, b)) {
|
||||
emu->sw.f.F87_C0 = 1;
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
emu->sw.f.F87_C3 = 0;
|
||||
}
|
||||
#else
|
||||
if(isnan(ST0.d) || isnan(b)) {
|
||||
emu->sw.f.F87_C0 = 1;
|
||||
emu->sw.f.F87_C2 = 1;
|
||||
@ -65,17 +84,38 @@ static inline void fpu_fcom(x86emu_t* emu, double b)
|
||||
emu->sw.f.F87_C0 = 1;
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
emu->sw.f.F87_C3 = 0;
|
||||
} else {
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
emu->sw.f.F87_C0 = 0;
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
emu->sw.f.F87_C3 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_FLOAT
|
||||
static inline void fpu_fcomi(x86emu_t* emu, float b)
|
||||
#else
|
||||
static inline void fpu_fcomi(x86emu_t* emu, double b)
|
||||
#endif
|
||||
{
|
||||
RESET_FLAGS(emu);
|
||||
emu->sw.f.F87_C1 = 0;
|
||||
#ifdef USE_FLOAT
|
||||
if(isnan(ST0.f) || isnan(b)) {
|
||||
emu->flags[F_CF] = 1;
|
||||
emu->flags[F_PF] = 1;
|
||||
emu->flags[F_ZF] = 1;
|
||||
} else if (isgreater(ST0.f, b)) {
|
||||
emu->flags[F_CF] = 0;
|
||||
emu->flags[F_PF] = 0;
|
||||
emu->flags[F_ZF] = 0;
|
||||
} else if (isless(ST0.f, b)) {
|
||||
emu->flags[F_CF] = 1;
|
||||
emu->flags[F_PF] = 0;
|
||||
emu->flags[F_ZF] = 0;
|
||||
}
|
||||
#else
|
||||
if(isnan(ST0.d) || isnan(b)) {
|
||||
emu->flags[F_CF] = 1;
|
||||
emu->flags[F_PF] = 1;
|
||||
@ -88,13 +128,31 @@ static inline void fpu_fcomi(x86emu_t* emu, double b)
|
||||
emu->flags[F_CF] = 1;
|
||||
emu->flags[F_PF] = 0;
|
||||
emu->flags[F_ZF] = 0;
|
||||
} else {
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
emu->flags[F_CF] = 0;
|
||||
emu->flags[F_PF] = 0;
|
||||
emu->flags[F_ZF] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_FLOAT
|
||||
static inline float fpu_round(x86emu_t* emu, float d) {
|
||||
if (!isfinite(d))
|
||||
return d;
|
||||
switch(emu->round) {
|
||||
case ROUND_Nearest:
|
||||
return floorf(d+0.5);
|
||||
case ROUND_Down:
|
||||
return floorf(d);
|
||||
case ROUND_Up:
|
||||
return ceilf(d);
|
||||
case ROUND_Chop:
|
||||
return roundf(d);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline double fpu_round(x86emu_t* emu, double d) {
|
||||
if (!isfinite(d))
|
||||
return d;
|
||||
@ -109,28 +167,48 @@ static inline double fpu_round(x86emu_t* emu, double d) {
|
||||
return round(d);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void fpu_fxam(x86emu_t* emu) {
|
||||
#ifdef USE_FLOAT
|
||||
emu->sw.f.F87_C1 = (ST0.ll&0x8000)?1:0;
|
||||
#else
|
||||
emu->sw.f.F87_C1 = (ST0.l.upper&0x80000000)?1:0;
|
||||
#endif
|
||||
if(!emu->fpu_stack) {
|
||||
emu->sw.f.F87_C3 = 1;
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
emu->sw.f.F87_C0 = 1;
|
||||
return;
|
||||
}
|
||||
if(isinf(ST0.d)) { // TODO: Unsuported and denormal not analysed...
|
||||
#ifdef USE_FLOAT
|
||||
if(isinf(ST0.f))
|
||||
#else
|
||||
if(isinf(ST0.d))
|
||||
#endif
|
||||
{ // TODO: Unsuported and denormal not analysed...
|
||||
emu->sw.f.F87_C3 = 0;
|
||||
emu->sw.f.F87_C2 = 1;
|
||||
emu->sw.f.F87_C0 = 1;
|
||||
return;
|
||||
}
|
||||
if(isnan(ST0.d)) { // TODO: Unsuported and denormal not analysed...
|
||||
#ifdef USE_FLOAT
|
||||
if(isnan(ST0.f))
|
||||
#else
|
||||
if(isnan(ST0.d))
|
||||
#endif
|
||||
{ // TODO: Unsuported and denormal not analysed...
|
||||
emu->sw.f.F87_C3 = 0;
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
emu->sw.f.F87_C0 = 1;
|
||||
return;
|
||||
}
|
||||
if(ST0.d==0.0) {
|
||||
#ifdef USE_FLOAT
|
||||
if(ST0.f==0.0f)
|
||||
#else
|
||||
if(ST0.d==0.0)
|
||||
#endif
|
||||
{
|
||||
emu->sw.f.F87_C3 = 1;
|
||||
emu->sw.f.F87_C2 = 0;
|
||||
emu->sw.f.F87_C0 = 0;
|
||||
|
10
src/x87run.c
10
src/x87run.c
@ -159,7 +159,12 @@ void Run66DD(x86emu_t *emu)
|
||||
char* p =(char*)op1;
|
||||
p += 14;
|
||||
for (int i=0; i<8; ++i) {
|
||||
#ifdef USE_FLOAT
|
||||
LD2D(p, &d);
|
||||
ST(i).f = d;
|
||||
#else
|
||||
LD2D(p, &ST(i).d);
|
||||
#endif
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
@ -173,7 +178,12 @@ void Run66DD(x86emu_t *emu)
|
||||
char* p =(char*)op1;
|
||||
p += 14;
|
||||
for (int i=0; i<8; ++i) {
|
||||
#ifdef USE_FLOAT
|
||||
d = ST(i).f;
|
||||
D2LD(&d, p);
|
||||
#else
|
||||
D2LD(&ST(i).d, p);
|
||||
#endif
|
||||
p+=10;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user