[LA64_DYNAREC] Added 1 more opcode and more fixes (#1305)

* Fixed printer name mapping

* Fixed emit_sub32c

* Remove a useless macro

* Added 85 TEST opcode
This commit is contained in:
Yang Liu 2024-03-01 02:33:36 +08:00 committed by GitHub
parent 92532b0fd1
commit c58adce8f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 88 additions and 5 deletions

View File

@ -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"
)

View File

@ -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);

View File

@ -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);

View File

@ -0,0 +1,70 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.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_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);
}
}

View File

@ -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);

View File

@ -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

View File

@ -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;