From a552e5a48f92004a1a76778bece8bf12a1a62ef2 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 17 Mar 2021 10:11:11 +0100 Subject: [DYNAREC] Various fixes, around GETED and other stuff (vvvvvv.x86_64 works again) --- src/dynarec/arm64_printer.c | 14 ++++++++------ src/dynarec/dynarec_arm64_00.c | 2 +- src/dynarec/dynarec_arm64_emit_math.c | 13 +++++++++---- src/dynarec/dynarec_arm64_emit_tests.c | 2 +- src/dynarec/dynarec_arm64_helper.c | 20 ++++++++++---------- src/dynarec/dynarec_arm64_helper.h | 12 +++++++++++- src/dynarec/dynarec_arm64_pass2.h | 2 +- src/dynarec/dynarec_arm64_pass3.h | 2 +- 8 files changed, 42 insertions(+), 25 deletions(-) (limited to 'src') 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)<>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)<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<>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 && ((tmpabsmax) || (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 -- cgit 1.4.1