diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-21 08:47:04 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-21 08:47:04 +0100 |
| commit | bf6ac0d608a73b5c524719326ed1b7d49c589693 (patch) | |
| tree | 639c015c868624b4690b8c7eecaae2e55ff15868 /src | |
| parent | cb7c7ad91336ed20541685f2a1020bc7759cd546 (diff) | |
| download | box64-bf6ac0d608a73b5c524719326ed1b7d49c589693.tar.gz box64-bf6ac0d608a73b5c524719326ed1b7d49c589693.zip | |
[DYNAREC] Added 67 E0..E3 opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 6 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_0f.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_66.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_660f.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_67.c | 110 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 32 |
6 files changed, 133 insertions, 21 deletions
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 304a6478..dcf74f1c 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -159,7 +159,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x0F: - addr = dynarec64_0F(dyn, addr, ip, ninst, rex, ok, need_epilog); + addr = dynarec64_0F(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); break; case 0x10: INST_NAME("ADC Eb, Gb"); @@ -517,7 +517,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0x66: addr = dynarec64_66(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); break; - + case 0x67: + addr = dynarec64_67(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); + break; case 0x68: INST_NAME("PUSH Id"); i64 = F32S; diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c index 28e8f7cc..bc7da54d 100755 --- a/src/dynarec/dynarec_arm64_0f.c +++ b/src/dynarec/dynarec_arm64_0f.c @@ -51,7 +51,7 @@ VST1_64(a, ed); \ } -uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) +uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { uint8_t opcode = F8; uint8_t nextop, u8; diff --git a/src/dynarec/dynarec_arm64_66.c b/src/dynarec/dynarec_arm64_66.c index edcbd1b7..19e08670 100755 --- a/src/dynarec/dynarec_arm64_66.c +++ b/src/dynarec/dynarec_arm64_66.c @@ -110,7 +110,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x0F: - addr = dynarec64_660F(dyn, addr, ip, ninst, rex, ok, need_epilog); + addr = dynarec64_660F(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); break; case 0x11: INST_NAME("ADC Ew, Gw"); diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c index 50333692..6dba108f 100755 --- a/src/dynarec/dynarec_arm64_660f.c +++ b/src/dynarec/dynarec_arm64_660f.c @@ -35,7 +35,7 @@ gd = ((nextop&0x38)>>3)+(rex.r<<3); \ a = sse_get_reg(dyn, ninst, x1, gd) -uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) +uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { uint8_t opcode = F8; uint8_t nextop, u8; diff --git a/src/dynarec/dynarec_arm64_67.c b/src/dynarec/dynarec_arm64_67.c new file mode 100755 index 00000000..1b691710 --- /dev/null +++ b/src/dynarec/dynarec_arm64_67.c @@ -0,0 +1,110 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <pthread.h> +#include <errno.h> + +#include "debug.h" +#include "box64context.h" +#include "dynarec.h" +#include "emu/x64emu_private.h" +#include "emu/x64run_private.h" +#include "x64run.h" +#include "x64emu.h" +#include "box64stack.h" +#include "callback.h" +#include "emu/x64run_private.h" +#include "x64trace.h" +#include "dynarec_arm64.h" +#include "dynarec_arm64_private.h" +#include "arm64_printer.h" + +#include "dynarec_arm64_helper.h" +#include "dynarec_arm64_functions.h" + + +uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) +{ + uint8_t opcode = F8; + uint8_t nextop, u8; + int8_t i8; + uint32_t u32; + int32_t i32, j32; + int16_t i16; + uint16_t u16; + uint8_t gd, ed; + uint8_t wback, wb1; + int fixedaddress; + MAYUSE(u16); + MAYUSE(u8); + MAYUSE(j32); + + // REX prefix before the 67 are ignored + rex.rex = 0; + while(opcode>=0x40 && opcode<=0x4f) { + rex.rex = opcode; + opcode = F8; + } + + switch(opcode) { + + #define GO(NO, YES) \ + BARRIER(2); \ + JUMP(addr+i8);\ + if(dyn->insts) { \ + if(dyn->insts[ninst].x64.jmp_insts==-1) { \ + /* out of the block */ \ + i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \ + Bcond(NO, i32); \ + jump_to_next(dyn, addr+i8, 0, ninst); \ + } else { \ + /* inside the block */ \ + i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \ + Bcond(YES, i32); \ + } \ + } + case 0xE0: + INST_NAME("LOOPNZ (32bits)"); + READFLAGS(X_ZF); + i8 = F8S; + MOVw_REG(x1, xRCX); + SUBSw_U12(x1, x1, 1); + BFIx(xRCX, x1, 0, 32); + B_NEXT(cEQ); // ECX is 0, no LOOP + TSTw_mask(xFlags, 0b011010, 0); //mask=0x40 + GO(cNE, cEQ); + break; + case 0xE1: + INST_NAME("LOOPZ (32bits)"); + READFLAGS(X_ZF); + i8 = F8S; + MOVw_REG(x1, xRCX); + SUBSw_U12(x1, x1, 1); + BFIx(xRCX, x1, 0, 32); + B_NEXT(cEQ); // ECX is 0, no LOOP + TSTw_mask(xFlags, 0b011010, 0); //mask=0x40 + GO(cEQ, cNE); + break; + case 0xE2: + INST_NAME("LOOP (32bits)"); + i8 = F8S; + MOVw_REG(x1, xRCX); + SUBSw_U12(x1, x1, 1); + BFIx(xRCX, x1, 0, 32); + GO(cEQ, cNE); + break; + case 0xE3: + INST_NAME("JECXZ"); + i8 = F8S; + MOVw_REG(x1, xRCX); + TSTw_REG(x1, x1); + GO(cNE, cEQ); + break; + #undef GO + + default: + DEFAULT; + } + return addr; +} + diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index 1206858c..46febe3a 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -757,23 +757,23 @@ void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1); void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1); uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog); -uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_FS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_GS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); +uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +//uintptr_t dynarec64_FS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +//uintptr_t dynarec64_GS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); -//uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -//uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); +uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +//uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); +//uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); +//uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); +//uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); +//uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); +//uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); +//uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); +//uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); +//uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep int* ok, int* need_epilog); +uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +//uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +//uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); #if STEP < 2 #define PASS2(A) |