diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-06 18:26:07 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-06 18:26:07 +0100 |
| commit | 395d9eb6224841edf72d5494bf306cf1ff79915e (patch) | |
| tree | 2e292320c497a0979933d499f9e0a0ac1ae17616 /src | |
| parent | 7ca8dc90439ceb97d359f89555f8059f4db955bf (diff) | |
| download | box64-395d9eb6224841edf72d5494bf306cf1ff79915e.tar.gz box64-395d9eb6224841edf72d5494bf306cf1ff79915e.zip | |
Added some DF x87 opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/emu/x64run.c | 9 | ||||
| -rwxr-xr-x | src/emu/x64run_private.h | 1 | ||||
| -rw-r--r-- | src/emu/x64rundf.c | 200 |
3 files changed, 210 insertions, 0 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 77c6db62..0795cdb9 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -628,6 +628,15 @@ x64emurun: goto fini; break; + case 0xDF: /* x87 opcodes */ + if(RunDF(emu, rex)) { + unimp = 1; + goto fini; + } + if(emu->quit) + goto fini; + break; + case 0xE8: /* CALL Id */ tmp32s = F32S; // call is relative Push(emu, R_RIP); diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index b7c7ee5f..e85dcfce 100755 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -102,6 +102,7 @@ int Run660F(x64emu_t *emu, rex_t rex); //int Run67(x64emu_t *emu, rex_t rex); int RunD9(x64emu_t *emu, rex_t rex); int RunDB(x64emu_t *emu, rex_t rex); +int RunDF(x64emu_t *emu, rex_t rex); int RunF0(x64emu_t *emu, rex_t rex); int RunF20F(x64emu_t *emu, rex_t rex); int RunF30F(x64emu_t *emu, rex_t rex); diff --git a/src/emu/x64rundf.c b/src/emu/x64rundf.c new file mode 100644 index 00000000..a382169c --- /dev/null +++ b/src/emu/x64rundf.c @@ -0,0 +1,200 @@ +#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 RunDF(x64emu_t *emu, rex_t rex) +{ + uint8_t nextop; + int16_t tmp16s; + reg64_t *oped; + + nextop = F8; + switch(nextop) { + case 0xC0: /* FFREEP STx */ + case 0xC1: + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: + case 0xC7: + fpu_do_free(emu, nextop-0xC0); + fpu_do_pop(emu); + break; + + case 0xE0: /* FNSTSW AX */ + emu->sw.f.F87_TOP = emu->top&7; + R_AX = emu->sw.x16; + break; + + case 0xE8: /* FUCOMIP ST0, STx */ + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xED: + case 0xEE: + case 0xEF: + fpu_fcomi(emu, ST(nextop&7).d); // bad, should handle QNaN and IA interrupt + fpu_do_pop(emu); + break; + + case 0xF0: /* FCOMIP ST0, STx */ + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + case 0xF5: + case 0xF6: + case 0xF7: + fpu_fcomi(emu, ST(nextop&7).d); + fpu_do_pop(emu); + break; + + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + case 0xD0: + case 0xD1: + case 0xD2: + case 0xD3: + case 0xD4: + case 0xD5: + case 0xD6: + case 0xD7: + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + case 0xF8: + case 0xF9: + case 0xFA: + case 0xFB: + case 0xFC: + case 0xFD: + case 0xFE: + case 0xFF: + return 1; + + default: + switch((nextop>>3)&7) { + case 0: /* FILD ST0, Gw */ + GETEW(0); + tmp16s = EW->sword[0]; + fpu_do_push(emu); + ST0.d = tmp16s; + break; + case 1: /* FISTTP Ew, ST0 */ + GETEW(0); + tmp16s = ST0.d; + EW->sword[0] = tmp16s; + fpu_do_pop(emu); + break; + case 2: /* FIST Ew, ST0 */ + GETEW(0); + if(isgreater(ST0.d, (double)(int32_t)0x7fff) || isless(ST0.d, -(double)(int32_t)0x7fff) || !isfinite(ST0.d)) + EW->sword[0] = 0x8000; + else + EW->sword[0] = fpu_round(emu, ST0.d); + break; + case 3: /* FISTP Ew, ST0 */ + GETEW(0); + if(isgreater(ST0.d, (double)(int32_t)0x7fff) || isless(ST0.d, -(double)(int32_t)0x7fff) || !isfinite(ST0.d)) + EW->sword[0] = 0x8000; + else + 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); + fpu_fbld(emu, (uint8_t*)ED); + break; + case 5: /* FILD ST0, Gq */ + GETED(0); + tmp64s = *(int64_t*)ED; + fpu_do_push(emu); + ST0.d = tmp64s; + STll(0).ll = tmp64s; + STll(0).ref = ST0.ll; + break; + case 6: /* FBSTP tbytes, ST0 */ + GETED(0); + fpu_fbst(emu, (uint8_t*)ED); + fpu_do_pop(emu); + 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); + } + } + fpu_do_pop(emu); + break; + #endif + default: + return 1; + } + } + return 0; +} \ No newline at end of file |