diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-25 13:53:48 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-25 13:53:48 +0100 |
| commit | 11cfae2a984359483b88971fbde3a4e454979ce5 (patch) | |
| tree | 8b5fb03a10fb695da6800fedcad116255fb51305 /src | |
| parent | 348bd64449843f70e08dd591c867973d83ea87eb (diff) | |
| download | box64-11cfae2a984359483b88971fbde3a4e454979ce5.tar.gz box64-11cfae2a984359483b88971fbde3a4e454979ce5.zip | |
[DYNAREC] Added some mecanism to handle weird 66 REX mixing
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 15 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_66.c | 7 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_pass.c | 18 |
4 files changed, 26 insertions, 16 deletions
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 38c6a447..6c690a54 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -24,7 +24,7 @@ #include "dynarec_arm64_functions.h" #include "dynarec_arm64_helper.h" -uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog) +uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { uint8_t nextop, opcode; uint8_t gd, ed; @@ -37,8 +37,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uint64_t u64; uint8_t wback, wb1, wb2; int fixedaddress; - rex_t rex; - int rep; // 0 none, 1=F2 prefix, 2=F3 prefix opcode = F8; MAYUSE(eb1); @@ -47,17 +45,6 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MAYUSE(tmp); MAYUSE(j32); - rep = 0; - while((opcode==0xF2) || (opcode==0xF3)) { - rep = opcode-0xF1; - opcode = F8; - } - rex.rex = 0; - while(opcode>=0x40 && opcode<=0x4f) { - rex.rex = opcode; - opcode = F8; - } - switch(opcode) { case 0x00: INST_NAME("ADD Eb, Gb"); diff --git a/src/dynarec/dynarec_arm64_66.c b/src/dynarec/dynarec_arm64_66.c index 5a230a65..d1c16122 100755 --- a/src/dynarec/dynarec_arm64_66.c +++ b/src/dynarec/dynarec_arm64_66.c @@ -51,6 +51,9 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin opcode = F8; } + if(rex.w) + return dynarec64_00(dyn, addr-1, ip, ninst, rex, rep, ok, need_epilog); + switch(opcode) { case 0x01: INST_NAME("ADD Ew, Gw"); @@ -286,6 +289,10 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; + case 0x66: + addr = dynarec64_66(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); + break; + case 0x69: INST_NAME("IMUL Gw,Ew,Iw"); SETFLAGS(X_ALL, SF_PENDING); diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index d51260bf..a06d54ea 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -814,7 +814,7 @@ void fpu_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3); 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_00(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_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_64(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_65(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog); diff --git a/src/dynarec/dynarec_arm64_pass.c b/src/dynarec/dynarec_arm64_pass.c index 8f7af07c..97404224 100755 --- a/src/dynarec/dynarec_arm64_pass.c +++ b/src/dynarec/dynarec_arm64_pass.c @@ -30,6 +30,8 @@ void arm_pass(dynarec_arm_t* dyn, uintptr_t addr) int ok = 1; int ninst = 0; uintptr_t ip = addr; + rex_t rex; + int rep; // 0 none, 1=F2 prefix, 2=F3 prefix int need_epilog = 1; dyn->sons_size = 0; // Clean up (because there are multiple passes) @@ -65,7 +67,21 @@ void arm_pass(dynarec_arm_t* dyn, uintptr_t addr) } #endif - addr = dynarec64_00(dyn, addr, ip, ninst, &ok, &need_epilog); + rep = 0; + uint8_t pk = PK(0); + while((pk==0xF2) || (pk==0xF3)) { + rep = pk-0xF1; + ++addr; + pk = PK(0); + } + rex.rex = 0; + while(pk>=0x40 && pk<=0x4f) { + rex.rex = pk; + ++addr; + pk = PK(0); + } + + addr = dynarec64_00(dyn, addr, ip, ninst, rex, rep, &ok, &need_epilog); INST_EPILOG; |