From 55580e1aba4c6a7d4e46cf229ef8a371a27caad1 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 1 Mar 2024 02:06:36 +0800 Subject: [PATCH 1/4] Fixed printer name mapping --- src/dynarec/la64/la64_printer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dynarec/la64/la64_printer.c b/src/dynarec/la64/la64_printer.c index 5e1231bd7..277921ddf 100644 --- a/src/dynarec/la64/la64_printer.c +++ b/src/dynarec/la64/la64_printer.c @@ -6,7 +6,7 @@ #include "la64_printer.h" #include "debug.h" -static const char* Xt[] = {"xZR", "r1", "r2", "sp", "xEmu", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "xRAX", "xRCX", "xRDX", "xRBX", "xRSP", "xRBP", "xRSI", "xRDI", "xR8", "r21", "xR9", "xR10", "xR11", "xR12", "xR13", "xR14", "xR15", "xFlags", "xRIP", "r31"}; +static const char* Xt[] = {"xZR", "r1", "r2", "sp", "xEmu", "x1_r5", "x2_r6", "x3_r7", "x4_r8", "x5_r9", "x6_r10", "xMASK_r11", "xRAX_r12", "xRCX_r13", "xRDX_r14", "xRBX_r15", "xRSP_r16", "xRBP_r17", "xRSI_r18", "xRDI_r19", "xRIP_r20", "r21", "r22", "xR8_r23", "xR9_r24", "xR10_r25", "xR11_r26", "xR12_r27", "xR13_r28", "xR14_r29", "xR15_r30", "xFlags_r31"}; typedef struct la64_print_s { int d, j, k, a; From 591960d2cdb825ff6ae6df6d2ff9c6bfe4e054db Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 1 Mar 2024 02:07:13 +0800 Subject: [PATCH 2/4] Fixed emit_sub32c --- src/dynarec/la64/dynarec_la64_emit_math.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c index b3db124c7..9543d5f16 100644 --- a/src/dynarec/la64/dynarec_la64_emit_math.c +++ b/src/dynarec/la64/dynarec_la64_emit_math.c @@ -549,8 +549,8 @@ void emit_sub32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i } if (la64_lbt) { + IFX(X_PEND) {} else {MOV64xw(s2, c);} IFX(X_ALL) { - IFX(X_PEND) {} else {MOV64xw(s2, c);} X64_SUB_WU(s1, s2); X64_GET_EFLAGS(s3, X_ALL); ORI(xFlags, xFlags, s3); From 9927463e4f253c612ab5e988d40e0aa5f1d3d56b Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 1 Mar 2024 02:07:32 +0800 Subject: [PATCH 3/4] Remove a useless macro --- src/dynarec/la64/la64_emitter.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index 6adcdf7f5..656607f40 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -53,8 +53,6 @@ f24-f31 fs0-fs7 Static registers Callee #define xRIP 20 // function to move from x86 regs number to LA64 reg number #define TO_LA64(A) (((A)>7)?((A)+15):((A)+12)) -// function to move from LA64 regs number to x86 reg number -#define FROM_LA64(A) (((A)>22)?((A)-15):((A)-12)) // 32bits version #define wEAX xRAX #define wECX xRCX From 4e85386549f1898de5ade1d41f2771e644db764f Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 1 Mar 2024 02:07:53 +0800 Subject: [PATCH 4/4] Added 85 TEST opcode --- CMakeLists.txt | 1 + src/dynarec/la64/dynarec_la64_00.c | 10 +++- src/dynarec/la64/dynarec_la64_emit_tests.c | 70 ++++++++++++++++++++++ src/dynarec/la64/dynarec_la64_helper.h | 6 ++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/dynarec/la64/dynarec_la64_emit_tests.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 6179d5fac..9068fc5e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -835,6 +835,7 @@ if(LARCH64_DYNAREC) set(DYNAREC_PASS "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_helper.c" + "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_emit_tests.c" "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_emit_math.c" "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_00.c" ) diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index bcfd9e7b6..268c89ac8 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -193,6 +193,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni DEFAULT; } break; + case 0x85: + INST_NAME("TEST Ed, Gd"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED(0); + emit_test32(dyn, ninst, rex, ed, gd, x3, x4, x5); + break; case 0x89: INST_NAME("MOV Ed, Gd"); nextop = F8; @@ -214,7 +222,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop=F8; GETGD; if(MODREG) { - MVxw(gd, xRAX + TO_LA64((nextop&7) + (rex.b<<3))); + MVxw(gd, TO_LA64((nextop&7) + (rex.b<<3))); } else { addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0); SMREADLOCK(lock); diff --git a/src/dynarec/la64/dynarec_la64_emit_tests.c b/src/dynarec/la64/dynarec_la64_emit_tests.c new file mode 100644 index 000000000..f7e1938e0 --- /dev/null +++ b/src/dynarec/la64/dynarec_la64_emit_tests.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +#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_native.h" + +#include "la64_printer.h" +#include "dynarec_la64_private.h" +#include "dynarec_la64_functions.h" +#include "dynarec_la64_helper.h" + + +// emit TEST32 instruction, from test s1, s2, using s3 and s4 as scratch +void emit_test32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) +{ + CLEAR_FLAGS(); + IFX_PENDOR0 { + SET_DF(s3, rex.w?d_tst64:d_tst32); + } else { + SET_DFNONE(); + } + + if (la64_lbt) { + IFX(X_ALL) { + if (rex.w) X64_AND_D(s1, s2); else X64_AND_W(s1, s2); + X64_GET_EFLAGS(s3, X_ALL); + ORI(xFlags, xFlags, s3); + } + + AND(s3, s1, s2); + + IFX_PENDOR0 { + SDxw(s3, xEmu, offsetof(x64emu_t, res)); + } + return; + } + + AND(s3, s1, s2); // res = s1 & s2 + + IFX_PENDOR0 { + SDxw(s3, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_SF | X_ZF) { + if (!rex.w) ZEROUP(s3); + } + IFX(X_SF) { + SRLI_D(s4, s3, rex.w?63:31); + BEQZ(s4, 8); + ORI(xFlags, xFlags, 1 << F_SF); + } + IFX(X_ZF) { + BNEZ(s3, 8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s3, s4, s5); + } +} \ No newline at end of file diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 5306814de..76f71d32d 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -212,6 +212,10 @@ #define GETMARKLOCK dyn->insts[ninst].marklock #define IFX(A) if ((dyn->insts[ninst].x64.gen_flags & (A))) +#define IFX_PENDOR0 if ((dyn->insts[ninst].x64.gen_flags & (X_PEND) || !dyn->insts[ninst].x64.gen_flags)) +#define IFXX(A) if ((dyn->insts[ninst].x64.gen_flags == (A))) +#define IFX2X(A, B) if ((dyn->insts[ninst].x64.gen_flags == (A) || dyn->insts[ninst].x64.gen_flags == (B) || dyn->insts[ninst].x64.gen_flags == ((A) | (B)))) +#define IFXN(A, B) if ((dyn->insts[ninst].x64.gen_flags & (A) && !(dyn->insts[ninst].x64.gen_flags & (B)))) #define STORE_REG(A) ST_D(x##A, xEmu, offsetof(x64emu_t, regs[_##A])) #define LOAD_REG(A) LD_D(x##A, xEmu, offsetof(x64emu_t, regs[_##A])) @@ -376,6 +380,7 @@ void* la64_next(x64emu_t* emu, uintptr_t addr); #define jump_to_epilog STEPNAME(jump_to_epilog) #define jump_to_next STEPNAME(jump_to_next) #define call_c STEPNAME(call_c) +#define emit_test32 STEPNAME(emit_test32) #define emit_add32 STEPNAME(emit_add32) #define emit_add32c STEPNAME(emit_add32c) #define emit_add8 STEPNAME(emit_add8) @@ -405,6 +410,7 @@ uintptr_t geted32(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop void jump_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst); void jump_to_next(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst, int is32bits); void call_c(dynarec_la64_t* dyn, int ninst, void* fnc, int reg, int ret, int saveflags, int save_reg); +void emit_test32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s2, int s3, int s4, int s5); void emit_add8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4);