diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-11 20:21:11 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-11 20:21:11 +0100 |
| commit | 9479d7ae07349cabe2165dd477fd210aea4665e0 (patch) | |
| tree | a5c7fa52135660f8ce3f95d936d2ff45ae0a48b0 /src | |
| parent | 4827427ac026eb4a47e25f868728d4455e968e91 (diff) | |
| download | box64-9479d7ae07349cabe2165dd477fd210aea4665e0.tar.gz box64-9479d7ae07349cabe2165dd477fd210aea4665e0.zip | |
Added more x87 opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/emu/x64run.c | 9 | ||||
| -rw-r--r-- | src/emu/x64run66.c | 6 | ||||
| -rw-r--r-- | src/emu/x64run66d9.c | 99 | ||||
| -rw-r--r-- | src/emu/x64run66dd.c | 117 | ||||
| -rwxr-xr-x | src/emu/x64run_private.h | 3 | ||||
| -rw-r--r-- | src/emu/x64runda.c | 139 | ||||
| -rw-r--r-- | src/emu/x64rundd.c | 2 | ||||
| -rw-r--r-- | src/emu/x64rundf.c | 35 |
8 files changed, 382 insertions, 28 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c index ccf03289..3baa0fb2 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -808,7 +808,14 @@ x64emurun: if(emu->quit) goto fini; break; - + case 0xDA: /* x87 opcodes */ + if(RunDA(emu, rex)) { + unimp = 1; + goto fini; + } + if(emu->quit) + goto fini; + break; case 0xDB: /* x87 opcodes */ if(RunDB(emu, rex)) { unimp = 1; diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c index c2e8a5a0..1cbe7eda 100644 --- a/src/emu/x64run66.c +++ b/src/emu/x64run66.c @@ -262,6 +262,12 @@ int Run66(x64emu_t *emu, rex_t rex) } break; + case 0xD9: /* x87 opcdes */ + return Run66D9(emu, rex); + + case 0xDD: /* x87 opcdes */ + return Run66DD(emu, rex); + case 0xF7: /* GRP3 Ew(,Iw) */ nextop = F8; tmp8u = (nextop>>3)&7; diff --git a/src/emu/x64run66d9.c b/src/emu/x64run66d9.c new file mode 100644 index 00000000..fae424ba --- /dev/null +++ b/src/emu/x64run66d9.c @@ -0,0 +1,99 @@ +#define _GNU_SOURCE +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <unistd.h> + +#include "debug.h" +#include "box64stack.h" +#include "x64emu.h" +#include "x64run.h" +#include "x64emu_private.h" +#include "x64run_private.h" +#include "x64primop.h" +#include "x64trace.h" +#include "x87emu_private.h" +#include "box64context.h" +//#include "my_cpuid.h" +#include "bridge.h" +//#include "signals.h" +#ifdef DYNAREC +#include "../dynarec/arm_lock_helper.h" +#endif + +#include "modrm.h" + +int Run66D9(x64emu_t *emu, rex_t rex) +{ + uint8_t nextop; + reg64_t *oped; + + nextop = F8; + switch (nextop) { + case 0xC0: + case 0xC1: + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: + case 0xC7: + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + case 0xD0: + case 0xE0: + case 0xE5: + case 0xE8: + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xED: + case 0xEE: + case 0xFC: + case 0xE1: + case 0xE4: + case 0xF0: + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + case 0xF5: + case 0xF6: + case 0xF7: + case 0xF8: + case 0xF9: + case 0xFA: + case 0xFB: + case 0xFD: + case 0xFE: + case 0xFF: + return 1; + default: + switch((nextop>>3)&7) { + case 4: /* FLDENV m */ + // warning, incomplete + GETEW(0); + fpu_loadenv(emu, (char*)ED, 1); + break; + case 6: /* FNSTENV m */ + // warning, incomplete + GETEW(0); + fpu_savenv(emu, (char*)ED, 1); + break; + default: + return 1; + } + } + return 0; +} diff --git a/src/emu/x64run66dd.c b/src/emu/x64run66dd.c new file mode 100644 index 00000000..1ef8e93c --- /dev/null +++ b/src/emu/x64run66dd.c @@ -0,0 +1,117 @@ +#define _GNU_SOURCE +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <unistd.h> + +#include "debug.h" +#include "box64stack.h" +#include "x64emu.h" +#include "x64run.h" +#include "x64emu_private.h" +#include "x64run_private.h" +#include "x64primop.h" +#include "x64trace.h" +#include "x87emu_private.h" +#include "box64context.h" +//#include "my_cpuid.h" +#include "bridge.h" +//#include "signals.h" +#ifdef DYNAREC +#include "../dynarec/arm_lock_helper.h" +#endif + +#include "modrm.h" + +int Run66DD(x64emu_t *emu, rex_t rex) +{ + uint8_t nextop; + reg64_t *oped; + + nextop = F8; + switch (nextop) { + case 0xC0: + case 0xC1: + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: + case 0xC7: + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + case 0xD0: + case 0xE0: + case 0xE5: + case 0xE8: + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xED: + case 0xEE: + case 0xFC: + case 0xE1: + case 0xE4: + case 0xF0: + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + case 0xF5: + case 0xF6: + case 0xF7: + case 0xF8: + case 0xF9: + case 0xFA: + case 0xFB: + case 0xFD: + case 0xFE: + case 0xFF: + return 1; + default: + switch((nextop>>3)&7) { + case 4: /* FRSTOR m94byte */ + GETEW(0); + fpu_loadenv(emu, (char*)ED, 1); + // get the STx + { + char* p =(char*)ED; + p += 14; + for (int i=0; i<8; ++i) { + LD2D(p, &ST(i).d); + p+=10; + } + } + break; + case 6: /* FNSAVE m94byte */ + GETEW(0); + // ENV first... + fpu_savenv(emu, (char*)ED, 1); + // save the STx + { + char* p =(char*)ED; + p += 14; + for (int i=0; i<8; ++i) { + D2LD(&ST(i).d, p); + p+=10; + } + } + reset_fpu(emu); + break; + default: + return 1; + } + } + return 0; +} diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index 7eb9a194..b1d798f0 100755 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -100,9 +100,12 @@ int Run64(x64emu_t *emu, rex_t rex); int Run66(x64emu_t *emu, rex_t rex); int Run660F(x64emu_t *emu, rex_t rex); int Run6664(x64emu_t *emu, rex_t rex); +int Run66D9(x64emu_t *emu, rex_t rex); +int Run66DD(x64emu_t *emu, rex_t rex); int Run67(x64emu_t *emu, rex_t rex); int RunD8(x64emu_t *emu, rex_t rex); int RunD9(x64emu_t *emu, rex_t rex); +int RunDA(x64emu_t *emu, rex_t rex); int RunDB(x64emu_t *emu, rex_t rex); int RunDD(x64emu_t *emu, rex_t rex); int RunDF(x64emu_t *emu, rex_t rex); diff --git a/src/emu/x64runda.c b/src/emu/x64runda.c new file mode 100644 index 00000000..65115b0c --- /dev/null +++ b/src/emu/x64runda.c @@ -0,0 +1,139 @@ +#define _GNU_SOURCE +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <unistd.h> + +#include "debug.h" +#include "box64stack.h" +#include "x64emu.h" +#include "x64run.h" +#include "x64emu_private.h" +#include "x64run_private.h" +#include "x64primop.h" +#include "x64trace.h" +#include "x87emu_private.h" +#include "box64context.h" +#include "bridge.h" +#ifdef DYNAREC +#include "../dynarec/arm_lock_helper.h" +#endif + +#include "modrm.h" + +int RunDA(x64emu_t *emu, rex_t rex) +{ + uint8_t nextop; + reg64_t *oped; + + nextop = F8; + switch (nextop) { + case 0xC0: /* FCMOVB ST(0), ST(i) */ + case 0xC1: + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: + case 0xC7: + CHECK_FLAGS(emu); + if(ACCESS_FLAG(F_CF)) + ST0.q = ST(nextop&7).q; + break; + case 0xC8: /* FCMOVE ST(0), ST(i) */ + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + CHECK_FLAGS(emu); + if(ACCESS_FLAG(F_ZF)) + ST0.q = ST(nextop&7).q; + break; + case 0xD0: /* FCMOVBE ST(0), ST(i) */ + case 0xD1: + case 0xD2: + case 0xD3: + case 0xD4: + case 0xD5: + case 0xD6: + case 0xD7: + CHECK_FLAGS(emu); + if(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)) + ST0.q = ST(nextop&7).q; + break; + case 0xD8: /* FCMOVU ST(0), ST(i) */ + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + CHECK_FLAGS(emu); + if(ACCESS_FLAG(F_PF)) + ST0.q = ST(nextop&7).q; + break; + + case 0xE9: /* FUCOMPP */ + fpu_fcom(emu, ST1.d); // bad, should handle QNaN and IA interrupt + fpu_do_pop(emu); + fpu_do_pop(emu); + break; + + case 0xE4: + case 0xF0: + case 0xF1: + case 0xF4: + case 0xF5: + case 0xF6: + case 0xF7: + case 0xF8: + case 0xF9: + case 0xFD: + return 1; + default: + switch((nextop>>3)&7) { + case 0: /* FIADD ST0, Ed int */ + GETED(0); + ST0.d += ED->sdword[0]; + break; + case 1: /* FIMUL ST0, Ed int */ + GETED(0); + ST0.d *= ED->sdword[0]; + break; + case 2: /* FICOM ST0, Ed int */ + GETED(0); + fpu_fcom(emu, ED->sdword[0]); + break; + case 3: /* FICOMP ST0, Ed int */ + GETED(0); + fpu_fcom(emu, ED->sdword[0]); + fpu_do_pop(emu); + break; + case 4: /* FISUB ST0, Ed int */ + GETED(0); + ST0.d -= ED->sdword[0]; + break; + case 5: /* FISUBR ST0, Ed int */ + GETED(0); + ST0.d = (double)ED->sdword[0] - ST0.d; + break; + case 6: /* FIDIV ST0, Ed int */ + GETED(0); + ST0.d /= ED->sdword[0]; + break; + case 7: /* FIDIVR ST0, Ed int */ + GETED(0); + ST0.d = (double)ED->sdword[0] / ST0.d; + break; + } + } + return 0; +} \ No newline at end of file diff --git a/src/emu/x64rundd.c b/src/emu/x64rundd.c index 8c5228c9..73678e2b 100644 --- a/src/emu/x64rundd.c +++ b/src/emu/x64rundd.c @@ -150,7 +150,6 @@ int RunDD(x64emu_t *emu, rex_t rex) } fpu_do_pop(emu); break; - #if 0 case 4: /* FRSTOR m108byte */ GETED(0); fpu_loadenv(emu, (char*)ED, 0); @@ -180,7 +179,6 @@ int RunDD(x64emu_t *emu, rex_t rex) } reset_fpu(emu); break; - #endif case 7: /* FNSTSW m2byte */ GETED(0); emu->sw.f.F87_TOP = emu->top&7; diff --git a/src/emu/x64rundf.c b/src/emu/x64rundf.c index a382169c..40186287 100644 --- a/src/emu/x64rundf.c +++ b/src/emu/x64rundf.c @@ -31,6 +31,7 @@ int RunDF(x64emu_t *emu, rex_t rex) { uint8_t nextop; int16_t tmp16s; + int64_t tmp64s; reg64_t *oped; nextop = F8; @@ -146,7 +147,6 @@ int RunDF(x64emu_t *emu, rex_t rex) EW->sword[0] = fpu_round(emu, ST0.d); fpu_do_pop(emu); break; - #if 0 case 4: /* FBLD ST0, tbytes */ GETED(0); fpu_do_push(emu); @@ -154,11 +154,11 @@ int RunDF(x64emu_t *emu, rex_t rex) break; case 5: /* FILD ST0, Gq */ GETED(0); - tmp64s = *(int64_t*)ED; + tmp64s = ED->sq[0]; fpu_do_push(emu); ST0.d = tmp64s; STll(0).ll = tmp64s; - STll(0).ref = ST0.ll; + STll(0).ref = ST0.q; break; case 6: /* FBSTP tbytes, ST0 */ GETED(0); @@ -167,31 +167,16 @@ int RunDF(x64emu_t *emu, rex_t rex) break; case 7: /* FISTP i64 */ GETED(0); - if((uintptr_t)ED & 0x7) { - // un-aligned! - if(STll(0).ref==ST(0).ll) - memcpy(ED, &STll(0).ll, sizeof(int64_t)); - else { - int64_t i64; - if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, -(double)(int64_t)0x7fffffffffffffffLL) || !isfinite(ST0.d)) - i64 = 0x8000000000000000LL; - else - i64 = fpu_round(emu, ST0.d); - memcpy(ED, &i64, sizeof(int64_t)); - } - } else { - if(STll(0).ref==ST(0).ll) - *(int64_t*)ED = STll(0).ll; - else { - if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, -(double)(int64_t)0x7fffffffffffffffLL) || !isfinite(ST0.d)) - *(int64_t*)ED = 0x8000000000000000LL; - else - *(int64_t*)ED = fpu_round(emu, ST0.d); - } + if(STll(0).ref==ST(0).q) + ED->sq[0] = STll(0).ll; + else { + if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, -(double)(int64_t)0x7fffffffffffffffLL) || !isfinite(ST0.d)) + ED->sq[0] = 0x8000000000000000LL; + else + ED->sq[0] = fpu_round(emu, ST0.d); } fpu_do_pop(emu); break; - #endif default: return 1; } |