diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-04-12 19:55:46 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-12 13:55:46 +0200 |
| commit | 139197230d19e99122abc141fabb0fcafcd01767 (patch) | |
| tree | db992a8a8e5100477dfac6e642b3fb83b9777f72 /src | |
| parent | 1d0e0307c4f2279803a1aa57533c45c6edeea12a (diff) | |
| download | box64-139197230d19e99122abc141fabb0fcafcd01767.tar.gz box64-139197230d19e99122abc141fabb0fcafcd01767.zip | |
[LA64_DYNAREC] Added more opcodes and fixed more issues (#1439)
* Added F3 0F 10 MOVSS opcodes * Added F3 0F 2A CVTSI2SS opcode * Added F3 0F 5E opcode * Added F3 0F 11 MOVSS opcode * Added 0C OR opcode * Added F3 0F 59 MULSS opcode * Added 81,83 /3 SBB opcode * Fixed 2 typos
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 37 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_emit_math.c | 8 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_f30f.c | 63 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 11 |
4 files changed, 113 insertions, 6 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index bf9722f6..f4987cc6 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -128,6 +128,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETED(0); emit_or32(dyn, ninst, rex, gd, ed, x3, x4); break; + case 0x0C: + INST_NAME("OR AL, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + ANDI(x1, xRAX, 0xff); + emit_or8c(dyn, ninst, x1, u8, x3, x4, x5); + BSTRINS_D(xRAX, x1, 7, 0); + break; case 0x0D: INST_NAME("OR EAX, Id"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -593,7 +601,11 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni WBACK; break; case 1: // OR - if (opcode == 0x81) { INST_NAME("OR Ed, Id"); } else { INST_NAME("OR Ed, Ib"); } + if (opcode == 0x81) { + INST_NAME("OR Ed, Id"); + } else { + INST_NAME("OR Ed, Ib"); + } SETFLAGS(X_ALL, SF_SET_PENDING); GETED((opcode == 0x81) ? 4 : 1); if (opcode == 0x81) i64 = F32S; else i64 = F8S; @@ -601,13 +613,34 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni WBACK; break; case 4: // AND - if (opcode == 0x81) { INST_NAME("AND Ed, Id"); } else { INST_NAME("AND Ed, Ib"); } + if (opcode == 0x81) { + INST_NAME("AND Ed, Id"); + } else { + INST_NAME("AND Ed, Ib"); + } SETFLAGS(X_ALL, SF_SET_PENDING); GETED((opcode == 0x81) ? 4 : 1); if (opcode == 0x81) i64 = F32S; else i64 = F8S; emit_and32c(dyn, ninst, rex, ed, i64, x3, x4); WBACK; break; + case 3: // SBB + if (opcode == 0x81) { + INST_NAME("SBB Ed, Id"); + } else { + INST_NAME("SBB Ed, Ib"); + } + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETED((opcode == 0x81) ? 4 : 1); + if (opcode == 0x81) + i64 = F32S; + else + i64 = F8S; + MOV64xw(x5, i64); + emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4, x6); + WBACK; + break; case 5: // SUB if (opcode == 0x81) { INST_NAME("SUB Ed, Id"); diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c index 2e670bf4..ca26ecc8 100644 --- a/src/dynarec/la64/dynarec_la64_emit_math.c +++ b/src/dynarec/la64/dynarec_la64_emit_math.c @@ -536,9 +536,9 @@ void emit_sub32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i IFX(X_PEND) {} else {MOV64xw(s2, c);} IFX(X_ALL) { if (rex.w) { - X64_SUB_WU(s1, s2); - } else { X64_SUB_DU(s1, s2); + } else { + X64_SUB_WU(s1, s2); } } SUBxw(s1, s1, s2); @@ -664,9 +664,9 @@ void emit_sbb32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s if (la64_lbt) { if (rex.w) { - SBC_W(s3, s1, s2); - } else { SBC_D(s3, s1, s2); + } else { + SBC_W(s3, s1, s2); } IFX (X_ALL) { if (rex.w) diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c index f406dead..47670a31 100644 --- a/src/dynarec/la64/dynarec_la64_f30f.c +++ b/src/dynarec/la64/dynarec_la64_f30f.c @@ -48,11 +48,74 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int MAYUSE(j64); switch (opcode) { + case 0x10: + INST_NAME("MOVSS Gx, Ex"); + nextop = F8; + GETG; + if(MODREG) { + v0 = sse_get_reg(dyn, ninst, x1, gd, 1); + v1 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0); + } else { + v0 = sse_get_reg_empty(dyn, ninst, x1, gd); + v1 = fpu_get_scratch(dyn); + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); + VXOR_V(v0, v0, v0); + FLD_S(v1, ed, fixedaddress); + } + VEXTRINS_W(v0, v1, 0); + break; + case 0x11: + INST_NAME("MOVSS Ex, Gx"); + nextop = F8; + GETG; + v0 = sse_get_reg(dyn, ninst, x1, gd, 0); + if (MODREG) { + q0 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 1); + VEXTRINS_W(q0, v0, 0); + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0); + FST_S(v0, ed, fixedaddress); + SMWRITE2(); + } + break; case 0x1E: INST_NAME("NOP / ENDBR32 / ENDBR64"); nextop = F8; FAKEED; break; + case 0x2A: + INST_NAME("CVTSI2SS Gx, Ed"); + nextop = F8; + GETGX(v0, 1); + GETED(0); + d1 = fpu_get_scratch(dyn); + MOVGR2FR_D(d1, ed); + if(rex.w) { + FFINT_S_L(d1, d1); + } else { + FFINT_S_W(d1, d1); + } + VEXTRINS_W(v0, d1, 0); + break; + case 0x59: + INST_NAME("MULSS Gx, Ex"); + nextop = F8; + GETGX(v0, 1); + d1 = fpu_get_scratch(dyn); + GETEXSS(d0, 0, 0); + FMUL_S(d1, v0, d0); + VEXTRINS_W(v0, d1, 0); + break; + case 0x5E: + INST_NAME("DIVSS Gx, Ex"); + nextop = F8; + GETGX(v0, 1); + d1 = fpu_get_scratch(dyn); + GETEXSS(d0, 0, 0); + FDIV_S(d1, v0, d0); + VEXTRINS_W(v0, d1, 0); + break; case 0x6F: INST_NAME("MOVDQU Gx, Ex"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index bf5e5abb..d5089d40 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -271,6 +271,17 @@ FLD_D(a, ed, fixedaddress); \ } +// Get Ex as a single, not a quad (warning, x1 get used) +#define GETEXSS(a, w, D) \ + if (MODREG) { \ + a = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), w); \ + } else { \ + SMREAD(); \ + a = fpu_get_scratch(dyn); \ + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \ + FLD_S(a, ed, fixedaddress); \ + } + // Write gb (gd) back to original register / memory, using s1 as scratch #define GBBACK() BSTRINS_D(gb1, gd, gb2 + 7, gb2); |