diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-17 10:11:11 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-17 10:11:11 +0100 |
| commit | a552e5a48f92004a1a76778bece8bf12a1a62ef2 (patch) | |
| tree | 86937dda75b5fd8ce22fb031770aab64bf18a2ab /src | |
| parent | b553c3f3ac7fe752dca6c27be72bec5969a1c955 (diff) | |
| download | box64-a552e5a48f92004a1a76778bece8bf12a1a62ef2.tar.gz box64-a552e5a48f92004a1a76778bece8bf12a1a62ef2.zip | |
[DYNAREC] Various fixes, around GETED and other stuff (vvvvvv.x86_64 works again)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64_printer.c | 14 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_emit_math.c | 13 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_emit_tests.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.c | 20 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 12 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_pass2.h | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_pass3.h | 2 |
8 files changed, 42 insertions, 25 deletions
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c index 2e0c62c1..9530b039 100755 --- a/src/dynarec/arm64_printer.c +++ b/src/dynarec/arm64_printer.c @@ -13,6 +13,8 @@ static const char* WtSp[] = {"w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8 static const char* conds[] = {"cEQ", "cNE", "cCS", "cCC", "cMI", "cPL", "cVS", "cVC", "cHI", "cLS", "cGE", "cLT", "cGT", "cLE", "c__", "inv"}; +#define abs(A) (((A)<0)?(-(A)):(A)) + typedef struct arm64_print_s { int N, S; int t, n, m, d; @@ -108,20 +110,20 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) if(isMask(opcode, "1x111000010iiiiiiiii01nnnnnttttt", &a)) { int size = (opcode>>30)&3; int offset = signExtend(imm, 9); - snprintf(buff, sizeof(buff), "LDR %s, [%s], %d", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset); + snprintf(buff, sizeof(buff), "LDR %s, [%s], %s0x%x", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset)); return buff; } if(isMask(opcode, "1x111000010iiiiiiiii11nnnnnttttt", &a)) { int size = (opcode>>30)&3; int offset = signExtend(imm, 9); - snprintf(buff, sizeof(buff), "LDR %s, [%s, %d]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset); + snprintf(buff, sizeof(buff), "LDR %s, [%s, %s0x%x]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset)); return buff; } if(isMask(opcode, "1x11100101iiiiiiiiiiiinnnnnttttt", &a)) { int size = (opcode>>30)&3; int offset = (imm)<<size; if(offset) - snprintf(buff, sizeof(buff), "LDR %s, [%s, %d]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset); + snprintf(buff, sizeof(buff), "LDR %s, [%s, 0x%x]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset); else snprintf(buff, sizeof(buff), "LDR %s, [%s]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn]); return buff; @@ -148,20 +150,20 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr) if(isMask(opcode, "1x111000000iiiiiiiii01nnnnnttttt", &a)) { int size = (opcode>>30)&3; int offset = signExtend(imm, 9); - snprintf(buff, sizeof(buff), "STR %s, [%s], %d", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset); + snprintf(buff, sizeof(buff), "STR %s, [%s], %s0x%x", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset)); return buff; } if(isMask(opcode, "1x111000000iiiiiiiii11nnnnnttttt", &a)) { int size = (opcode>>30)&3; int offset = signExtend(imm, 9); - snprintf(buff, sizeof(buff), "STR %s, [%s, %d]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset); + snprintf(buff, sizeof(buff), "STR %s, [%s, %s0x%x]!", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], (offset<0)?"-":"", abs(offset)); return buff; } if(isMask(opcode, "1x11100100iiiiiiiiiiiinnnnnttttt", &a)) { int size = (opcode>>30)&3; int offset = (imm)<<size; if(offset) - snprintf(buff, sizeof(buff), "STR %s, [%s, %d]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset); + snprintf(buff, sizeof(buff), "STR %s, [%s, 0x%x]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn], offset); else snprintf(buff, sizeof(buff), "STR %s, [%s]", (size==0b10)?Wt[Rt]:Xt[Rt], XtSp[Rn]); return buff; diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index b3a4f6f5..c9802203 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -324,7 +324,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin // calling a native function x87_forget(dyn, ninst, x3, x4, 0); sse_purge07cache(dyn, ninst, x3); - GETIP(dyn->insts[ninst].natcall); // read the 0xCC already + GETIP_(dyn->insts[ninst].natcall); // read the 0xCC already STORE_XEMU_MINIMUM(xRIP); CALL_S(x64Int3, -1); LOAD_XEMU_MINIMUM(xRIP); diff --git a/src/dynarec/dynarec_arm64_emit_math.c b/src/dynarec/dynarec_arm64_emit_math.c index 0d867ecc..d83187f2 100755 --- a/src/dynarec/dynarec_arm64_emit_math.c +++ b/src/dynarec/dynarec_arm64_emit_math.c @@ -161,7 +161,7 @@ void emit_sub32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3 IFX(X_PEND) { STRxw_U12(s1, xEmu, offsetof(x64emu_t, op1)); STRxw_U12(s2, xEmu, offsetof(x64emu_t, op2)); - SET_DF(s3, d_sub32); + SET_DF(s3, rex.w?d_sub64:d_sub32); } else IFX(X_ALL) { SET_DFNONE(s3); } @@ -225,10 +225,15 @@ void emit_sub32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in return; } IFX(X_PEND) { + if(rex.w) { + STRx_U12(s1, xEmu, offsetof(x64emu_t, op1)); + } else { + MOVw(s3, s1); + STRx_U12(s3, xEmu, offsetof(x64emu_t, op1)); + } MOV64x(s3, c); - STRx_U12(s1, xEmu, offsetof(x64emu_t, op1)); STRx_U12(s3, xEmu, offsetof(x64emu_t, op2)); - SET_DF(s4, d_sub32); + SET_DF(s4, rex.w?d_sub64:d_sub32); } else IFX(X_ALL) { SET_DFNONE(s4); } @@ -262,7 +267,7 @@ void emit_sub32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in BFIw(xFlags, s4, F_AF, 1); // AF: bc & 0x08 } IFX(X_ZF|X_CF|X_OF) { - MOVw(s5, (1<<F_ZF)|(1<<F_CF)|(1<<F_OF)); + MOV32w(s5, (1<<F_ZF)|(1<<F_CF)|(1<<F_OF)); BICx(xFlags, xFlags, s5); } IFX(X_ZF) { diff --git a/src/dynarec/dynarec_arm64_emit_tests.c b/src/dynarec/dynarec_arm64_emit_tests.c index 986334e2..1c014b9f 100755 --- a/src/dynarec/dynarec_arm64_emit_tests.c +++ b/src/dynarec/dynarec_arm64_emit_tests.c @@ -300,7 +300,7 @@ void emit_test32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) { IFX(X_PEND) { - SET_DF(s3, d_tst32); + SET_DF(s3, rex.w?d_tst64:d_tst32); } else { SET_DFNONE(s4); } diff --git a/src/dynarec/dynarec_arm64_helper.c b/src/dynarec/dynarec_arm64_helper.c index 1bf37ab3..2b5fd809 100755 --- a/src/dynarec/dynarec_arm64_helper.c +++ b/src/dynarec/dynarec_arm64_helper.c @@ -39,15 +39,15 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u if(!(nextop&0xC0)) { if((nextop&7)==4) { uint8_t sib = F8; - int sib_reg = (sib>>3)&7; + int sib_reg = ((sib>>3)&7)+(rex.x<<3); if((sib&0x7)==5) { uint64_t tmp = F32S64; if (sib_reg!=4) { if(tmp && ((tmp<absmin) || (tmp>absmax) || (tmp&mask))) { MOV64x(scratch, tmp); - ADDx_REG_LSL(ret, scratch, xRAX+sib_reg+(rex.x<<3), (sib>>6)); + ADDx_REG_LSL(ret, scratch, xRAX+sib_reg, (sib>>6)); } else { - LSLx(ret, xRAX+sib_reg+(rex.x<<3), (sib>>6)); + LSLx(ret, xRAX+sib_reg, (sib>>6)); *fixaddress = tmp; } } else { @@ -55,7 +55,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u } } else { if (sib_reg!=4) { - ADDx_REG_LSL(ret, xRAX+(sib&0x7)+(rex.b<<3), xRAX+sib_reg+(rex.x<<3), (sib>>6)); + ADDx_REG_LSL(ret, xRAX+(sib&0x7)+(rex.b<<3), xRAX+sib_reg, (sib>>6)); } else { ret = xRAX+(sib&0x7)+(rex.b<<3); } @@ -74,7 +74,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u int sib_reg = 0; if((nextop&7)==4) { sib = F8; - sib_reg = (sib>>3)&7; + sib_reg = ((sib>>3)&7)+(rex.x<<3); } if(nextop&0x80) i64 = F32S; @@ -84,7 +84,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u *fixaddress = i64; if((nextop&7)==4) { if (sib_reg!=4) { - ADDx_REG_LSL(ret, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg+(rex.x<<3), (sib>>6)); + ADDx_REG_LSL(ret, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg, (sib>>6)); } else { ret = xRAX+(sib&0x07)+(rex.b<<3); } @@ -96,7 +96,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u if(i64<0x1000) { if((nextop&7)==4) { if (sib_reg!=4) { - ADDx_REG_LSL(scratch, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg+(rex.x<<3), (sib>>6)); + ADDx_REG_LSL(scratch, xRAX+(sib&0x07)+(rex.b<<3), xRAX+sib_reg, (sib>>6)); } else { scratch = xRAX+(sib&0x07)+(rex.b<<3); } @@ -116,7 +116,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u } else { ADDx_REG(scratch, scratch, xRAX+(sib&0x07)+(rex.b<<3)); } - ADDx_REG_LSL(ret, scratch, xRAX+sib_reg+(rex.x<<3), (sib>>6)); + ADDx_REG_LSL(ret, scratch, xRAX+sib_reg, (sib>>6)); } else { PASS3(int tmp = xRAX+(sib&0x07)+(rex.b<<3)); if(sub) { @@ -225,7 +225,7 @@ void jump_to_epilog(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst) MOVx(xRIP, reg); } } else { - GETIP(ip); + GETIP_(ip); } TABLE64(x2, (uintptr_t)arm64_epilog); BR(x2); @@ -251,7 +251,7 @@ void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst) } else { uintptr_t p = getJumpTableAddress64(ip); TABLE64(x2, p); - GETIP(ip); + GETIP_(ip); LDRx_U12(x3, x2, 0); } MOVx(x1, xRIP); diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index 4fef2acb..5f1b8e20 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -427,16 +427,26 @@ #if STEP < 2 #define GETIP(A) +#define GETIP_(A) #else #define GETIP(A) \ if(dyn->last_ip && (A-dyn->last_ip)<0x1000) { \ uint64_t delta = A-dyn->last_ip; \ dyn->last_ip += delta; \ - ADDx_U12(xRIP, xRIP, delta); \ + if(delta) { \ + ADDx_U12(xRIP, xRIP, delta); \ + } \ } else { \ dyn->last_ip = A; \ TABLE64(xRIP, dyn->last_ip); \ } +#define GETIP_(A) \ + if(dyn->last_ip && (A-dyn->last_ip)<0x1000) { \ + uint64_t delta = A-dyn->last_ip; \ + ADDx_U12(xRIP, xRIP, delta); \ + } else { \ + TABLE64(xRIP, A); \ + } #endif #if STEP < 2 diff --git a/src/dynarec/dynarec_arm64_pass2.h b/src/dynarec/dynarec_arm64_pass2.h index f0bf7fbd..838ed665 100755 --- a/src/dynarec/dynarec_arm64_pass2.h +++ b/src/dynarec/dynarec_arm64_pass2.h @@ -7,4 +7,4 @@ #define INST_EPILOG dyn->insts[ninst].epilog = dyn->arm_size; #define INST_NAME(name) #define NEW_BARRIER_INST if(ninst) ++dyn->sons_size -#define TABLE64(A, V) {Table64(dyn, (V)); EMIT(0);} \ No newline at end of file +#define TABLE64(A, V) if((V)>0xffffffffL) {Table64(dyn, (V)); EMIT(0);} else {MOV64x(A, V);} \ No newline at end of file diff --git a/src/dynarec/dynarec_arm64_pass3.h b/src/dynarec/dynarec_arm64_pass3.h index a94c61c7..f58e9364 100755 --- a/src/dynarec/dynarec_arm64_pass3.h +++ b/src/dynarec/dynarec_arm64_pass3.h @@ -32,4 +32,4 @@ ++dyn->sons_size; \ } -#define TABLE64(A, V) {int val64offset = Table64(dyn, (V)); MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); LDRx_literal(A, val64offset);} \ No newline at end of file +#define TABLE64(A, V) if((V)>0xffffffffL) {int val64offset = Table64(dyn, (V)); MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); LDRx_literal(A, val64offset);} else {MOV64x(A, V);} \ No newline at end of file |