diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-02-29 23:11:52 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-29 16:11:52 +0100 |
| commit | da1ac7beee6c1710329f6794a27a8b1296d649ce (patch) | |
| tree | 08bd507f0f04dcd5b4e0da39c30441e36cab270c /src | |
| parent | 28b79626d9c77abb63b1d3212bbbd7dfa2e96687 (diff) | |
| download | box64-da1ac7beee6c1710329f6794a27a8b1296d649ce.tar.gz box64-da1ac7beee6c1710329f6794a27a8b1296d649ce.zip | |
[LA64_DYNAREC] Added basic LBT support, setup xMASK (#1302)
* [LA64] Added basic LBT support, setup xMASK * [CI] Run tests without LBT
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_emit_math.c | 25 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.c | 3 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 8 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_prolog.S | 3 | ||||
| -rw-r--r-- | src/include/debug.h | 2 | ||||
| -rw-r--r-- | src/main.c | 10 |
6 files changed, 37 insertions, 14 deletions
diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c index 9fe6ce2f..45e09758 100644 --- a/src/dynarec/la64/dynarec_la64_emit_math.c +++ b/src/dynarec/la64/dynarec_la64_emit_math.c @@ -40,6 +40,21 @@ void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s { SET_DFNONE(); } + + if (la64_lbt) { + IFX(X_ALL) { + X64_ADD_WU(s1, s2); + X64_GET_EFLAGS(s3, X_ALL); + ORI(xFlags, xFlags, s3); + } + ADDxw(s1, s1, s2); + if (!rex.w) ZEROUP(s1); + + IFX(X_PEND) + SDxw(s1, xEmu, offsetof(x64emu_t, res)); + return; + } + IFX(X_CF) { if (rex.w) { @@ -68,17 +83,11 @@ void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s AND(s4, s1, s2); // s4 = op1 & op2 } - if (rex.w) - ADD_D(s1, s1, s2); - else - ADD_W(s1, s1, s2); + ADDxw(s1, s1, s2); IFX(X_PEND) { - if (rex.w) - ST_D(s1, xEmu, offsetof(x64emu_t, res)); - else - ST_W(s1, xEmu, offsetof(x64emu_t, res)); + SDxw(s1, xEmu, offsetof(x64emu_t, res)); } IFX(X_AF | X_OF) { diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index 0d3a8dd3..5ab4e320 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -444,6 +444,9 @@ void call_c(dynarec_la64_t* dyn, int ninst, void* fnc, int reg, int ret, int sav LD_D(xRIP, xEmu, offsetof(x64emu_t, ip)); #undef GO } + // regenerate mask + ADDI_W(xMASK, xZR, -1); + LU32I_D(xMASK, 0); fpu_popcache(dyn, ninst, reg, 0); if (saveflags) { diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index 2717a4b2..5e826734 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -80,6 +80,8 @@ f24-f31 fs0-fs7 Static registers Callee #define x4 8 #define x5 9 #define x6 10 +// used to clear the upper 32bits +#define xMASK 11 // 32bits version of scratch #define w1 x1 #define w2 x2 @@ -104,11 +106,7 @@ f24-f31 fs0-fs7 Static registers Callee #define SPLIT12(A) ((A) & 0xfff) // ZERO the upper part -#define ZEROUP(r) \ - do { \ - MOV32w(x2, 0xffffffff); \ - AND(r, r, x2); \ - } while (0); +#define ZEROUP(r) AND(r, r, xMASK); // Standard formats #define type_4R(opc, ra, rk, rj, rd) ((opc) << 20 | (ra) << 15 | (rk) << 10 | (rj) << 5 | (rd)) diff --git a/src/dynarec/la64/la64_prolog.S b/src/dynarec/la64/la64_prolog.S index b1dd3450..354e5518 100644 --- a/src/dynarec/la64/la64_prolog.S +++ b/src/dynarec/la64/la64_prolog.S @@ -56,5 +56,8 @@ la64_prolog: st.d $r11, $sp, -16 st.d $r0, $sp, -8 addi.d $sp, $sp, -16 + // setup xMASK + addi.w $r11, $r0, -1 + lu32i.d $r4, 0 //jump to function jirl $r0, $a1, 0 diff --git a/src/include/debug.h b/src/include/debug.h index 0f0526f7..2c5746a0 100644 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -60,6 +60,8 @@ extern int rv64_xtheadmempair; extern int rv64_xtheadfmemidx; extern int rv64_xtheadmac; extern int rv64_xtheadfmv; +#elif defined(LA64) +extern int la64_lbt; #endif #endif extern int box64_libcef; diff --git a/src/main.c b/src/main.c index bf628181..9450bfa4 100644 --- a/src/main.c +++ b/src/main.c @@ -106,6 +106,8 @@ int rv64_xtheadmempair = 0; int rv64_xtheadfmemidx = 0; int rv64_xtheadmac = 0; int rv64_xtheadfmv = 0; +#elif defined(LA64) +int la64_lbt = 0; #endif #else //DYNAREC int box64_dynarec = 0; @@ -444,9 +446,15 @@ HWCAP2_ECV printf_log(LOG_INFO, " AFP"); #elif defined(LA64) printf_log(LOG_INFO, "Dynarec for LoongArch"); + char *p = getenv("BOX64_DYNAREC_LA64NOEXT"); + if(p == NULL || p[0] == '0') { + // We don't bother to detect it, it's there. + la64_lbt = 1; + } #elif defined(RV64) void RV64_Detect_Function(); - if(!getenv("BOX64_DYNAREC_RV64NOEXT")) + char *p = getenv("BOX64_DYNAREC_RV64NOEXT"); + if(p == NULL || p[0] == '0') RV64_Detect_Function(); printf_log(LOG_INFO, "Dynarec for RISC-V "); printf_log(LOG_INFO, "With extension: I M A F D C"); |