diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-04-06 14:49:37 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-06 08:49:37 +0200 |
| commit | 2a75d283867fc7a09b53a3a446989cf1b1b9998d (patch) | |
| tree | b7ec427141179ddbceacf7a2c03db03b9be33b20 /src | |
| parent | 3e412891674af3d4eb77675853c1f10715dfabce (diff) | |
| download | box64-2a75d283867fc7a09b53a3a446989cf1b1b9998d.tar.gz box64-2a75d283867fc7a09b53a3a446989cf1b1b9998d.zip | |
[LA64_DYNAREC] Fixed missing LBT path and more (#1419)
* [LA64_DYNAREC] Fixed missing LBT path and more * Fixed D3 /4/6 SHL opcode * LA64 qemu is not stable too
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 22 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 18 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_emit_shift.c | 1 |
3 files changed, 25 insertions, 16 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 6940839d..69394021 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -332,25 +332,25 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni break; break; case 0x63: - if(rex.is32bits) { + if (rex.is32bits) { // this is ARPL opcode DEFAULT; } else { INST_NAME("MOVSXD Gd, Ed"); nextop = F8; GETGD; - if(rex.w) { - if(MODREG) { // reg <= reg - ADDI_W(gd, TO_LA64((nextop&7)+(rex.b<<3)), 0); - } else { // mem <= reg + if (rex.w) { + if (MODREG) { // reg <= reg + ADDI_W(gd, TO_LA64((nextop & 7) + (rex.b << 3)), 0); + } else { // mem <= reg SMREAD(); addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); LD_W(gd, ed, fixedaddress); } } else { - if(MODREG) { // reg <= reg - AND(gd, xRAX+(nextop&7)+(rex.b<<3), xMASK); - } else { // mem <= reg + if (MODREG) { // reg <= reg + AND(gd, TO_LA64((nextop & 7) + (rex.b << 3)), xMASK); + } else { // mem <= reg SMREAD(); addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); LD_WU(gd, ed, fixedaddress); @@ -1038,10 +1038,10 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 4: case 6: INST_NAME("SHL Ed, CL"); - SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined - ANDI(x3, xRCX, rex.w?0x3f:0x1f); + SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined + ANDI(x3, xRCX, rex.w ? 0x3f : 0x1f); GETED(0); - if(!rex.w && MODREG) { ZEROUP(ed); } + if (!rex.w && MODREG) { ZEROUP(ed); } CBZ_NEXT(x3); emit_shl32(dyn, ninst, rex, ed, x3, x5, x4, x6); WBACK; diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index ef466ea8..c6879562 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -279,7 +279,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } ANDI(x2, gd, rex.w ? 0x3f : 0x1f); SRLIxw(x4, ed, x2); - BSTRINS_D(xFlags, x4, F_CF, F_CF); + if (la64_lbt) + X64_SET_EFLAGS(x4, X_CF); + else + BSTRINS_D(xFlags, x4, F_CF, F_CF); break; case 0xAF: INST_NAME("IMUL Gd, Ed"); @@ -294,6 +297,9 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if (rex.w) { // 64bits imul UFLAG_IF { + if (la64_lbt) { + X64_MUL_D(gd, ed); + } MULH_D(x3, gd, ed); MUL_D(gd, gd, ed); IFX (X_PEND) { @@ -303,7 +309,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SET_DFNONE(); } - IFX (X_CF | X_OF) { + IFXA (X_CF | X_OF, !la64_lbt) { SRAI_D(x4, gd, 63); XOR(x3, x3, x4); SNEZ(x3, x3); @@ -320,6 +326,9 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { // 32bits imul UFLAG_IF { + if (la64_lbt) { + X64_MUL_W(gd, ed); + } MUL_D(gd, gd, ed); SRLI_D(x3, gd, 32); SLLI_W(gd, gd, 0); @@ -330,7 +339,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else IFX (X_CF | X_OF) { SET_DFNONE(); } - IFX (X_CF | X_OF) { + IFXA (X_CF | X_OF, !la64_lbt) { SRAI_W(x4, gd, 31); SUB_D(x3, x3, x4); SNEZ(x3, x3); @@ -344,8 +353,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { MULxw(gd, gd, ed); } - SLLI_D(gd, gd, 32); - SRLI_D(gd, gd, 32); + ZEROUP(gd); } break; case 0xB6: diff --git a/src/dynarec/la64/dynarec_la64_emit_shift.c b/src/dynarec/la64/dynarec_la64_emit_shift.c index dff76a5a..377250d5 100644 --- a/src/dynarec/la64/dynarec_la64_emit_shift.c +++ b/src/dynarec/la64/dynarec_la64_emit_shift.c @@ -41,6 +41,7 @@ void emit_shl32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s X64_SLL_W(s1, s2); } SLL_D(s1, s1, s2); + if (!rex.w) { ZEROUP(s1); } IFX(X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } |