diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-11-29 02:34:14 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-28 19:34:14 +0100 |
| commit | a070066b715bd0185b4a06fe684868803d921567 (patch) | |
| tree | 2282189892837973cfa5ed02453ffd4c9331c4f9 /src | |
| parent | 4e92269ae1d7957c5d37cb116fa25c5976785e95 (diff) | |
| download | box64-a070066b715bd0185b4a06fe684868803d921567.tar.gz box64-a070066b715bd0185b4a06fe684868803d921567.zip | |
[DYNAREC][INTERPRETER] Rework on 6C/6D/6E/6F opcodes (#1098)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 15 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_1.c | 25 | ||||
| -rw-r--r-- | src/emu/x64run.c | 77 |
3 files changed, 45 insertions, 72 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 2f05ee1f..0044b080 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -817,8 +817,21 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; + case 0x6C: case 0x6D: - INST_NAME("INSD"); + INST_NAME(opcode == 0x6C ? "INSB" : "INSD"); + SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + GETIP(ip); + STORE_XEMU_CALL(xRIP); + CALL(native_priv, -1); + LOAD_XEMU_CALL(xRIP); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; + break; + case 0x6E: + case 0x6F: + INST_NAME(opcode == 0x6C ? "OUTSB" : "OUTSD"); SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state GETIP(ip); STORE_XEMU_CALL(xRIP); diff --git a/src/dynarec/rv64/dynarec_rv64_00_1.c b/src/dynarec/rv64/dynarec_rv64_00_1.c index 4cc3a66c..be17f156 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_1.c +++ b/src/dynarec/rv64/dynarec_rv64_00_1.c @@ -263,6 +263,31 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } break; + case 0x6C: + case 0x6D: + INST_NAME(opcode == 0x6C ? "INSB" : "INSD"); + SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + GETIP(ip); + STORE_XEMU_CALL(x3); + CALL(native_priv, -1); + LOAD_XEMU_CALL(); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; + break; + case 0x6E: + case 0x6F: + INST_NAME(opcode == 0x6C ? "OUTSB" : "OUTSD"); + SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + GETIP(ip); + STORE_XEMU_CALL(x3); + CALL(native_priv, -1); + LOAD_XEMU_CALL(); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; + break; + #define GO(GETFLAGS, NO, YES, F) \ READFLAGS(F); \ i8 = F8S; \ diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 312eac33..f48460c4 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -515,78 +515,13 @@ x64emurun: GD->q[0] = imul32(emu, ED->dword[0], (uint32_t)tmp64s); break; case 0x6C: /* INSB DX */ - if(rex.is32bits) { - tmp32u = rep?R_ECX:1; - while(tmp32u--) { - *(int8_t*)(R_EDI+GetESBaseEmu(emu)) = 0; // faking port read, using explicit ES segment - if(ACCESS_FLAG(F_DF)) - R_EDI-=1; - else - R_EDI+=1; - } - if(rep) - R_ECX = 0; - } else { - // this is a privilege opcode in 64bits, but not in 32bits... - #ifndef TEST_INTERPRETOR - emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); - STEP; - #endif - } - break; - case 0x6D: /* INSL DX */ - if(rex.is32bits) { - tmp32u = rep?R_ECX:1; - while(tmp32u--) { - *(int32_t*)(R_EDI+GetESBaseEmu(emu)) = 0; // faking port read, using explicit ES segment - if(ACCESS_FLAG(F_DF)) - R_EDI-=4; - else - R_EDI+=4; - } - if(rep) - R_ECX = 0; - } else { - // this is a privilege opcode in 64bits, but not in 32bits... - #ifndef TEST_INTERPRETOR - emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); - STEP; - #endif - } - break; + case 0x6D: /* INSD DX */ case 0x6E: /* OUTSB DX */ - if(rex.is32bits) { - // faking port write, using explicit ES segment - if(ACCESS_FLAG(F_DF)) - R_ESI-=rep?R_ECX:1; - else - R_ESI+=1?R_ECX:1; - if(rep) - R_ECX = 0; - } else { - // this is a privilege opcode in 64bits, but not in 32bits... - #ifndef TEST_INTERPRETOR - emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); - STEP; - #endif - } - break; - case 0x6F: /* OUTSL DX */ - if(rex.is32bits) { - // faking port write, using explicit ES segment - if(ACCESS_FLAG(F_DF)) - R_ESI-=(rep?R_ECX:1)*4; - else - R_ESI+=(rep?R_ECX:1)*4; - if(rep) - R_ECX = 0; - } else { - // this is a privilege opcode in 64bits, but not in 32bits... - #ifndef TEST_INTERPRETOR - emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); - STEP; - #endif - } + case 0x6F: /* OUTSD DX */ + #ifndef TEST_INTERPRETOR + emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); + STEP; + #endif break; GOCOND(0x70 |