diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-03-28 21:32:10 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-28 14:32:10 +0100 |
| commit | 0a59695fb37315962168188a1db6d2685d09c6c2 (patch) | |
| tree | 60f809b09dd50388497a355ae3ea69b317f6c0f9 /src | |
| parent | cfdeb3685cdfed402a01baa2fb693ef16f5ba7d7 (diff) | |
| download | box64-0a59695fb37315962168188a1db6d2685d09c6c2.tar.gz box64-0a59695fb37315962168188a1db6d2685d09c6c2.zip | |
[LA64_DYNAREC] Added more MMX opcodes (#2477)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 98 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 16 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 3 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_printer.c | 8 |
4 files changed, 125 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index c94ad178..3ae7cffc 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -716,6 +716,27 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni // empty MMX, FPU now usable mmx_purgecache(dyn, ninst, 0, x1); break; + case 0x7E: + INST_NAME("MOVD Ed, Gm"); + nextop = F8; + GETGM(v0); + if (MODREG) { + ed = TO_NAT((nextop & 0x07) + (rex.b << 3)); + if (rex.w) { + MOVFR2GR_D(ed, v0); + } else { + MOVFR2GR_S(ed, v0); + ZEROUP(ed); + } + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x3, x2, &fixedaddress, rex, NULL, 1, 0); + if (rex.w) + FST_D(v0, ed, fixedaddress); + else + FST_S(v0, ed, fixedaddress); + SMWRITE2(); + } + break; #define GO(GETFLAGS, NO, YES, NATNO, NATYES, F, I) \ READFLAGS_FUSION(F, x1, x2, x3, x4, x5); \ @@ -1419,6 +1440,83 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni gd = TO_NAT((opcode & 7) + (rex.b << 3)); REVBxw(gd, gd); break; + case 0xD1: + INST_NAME("PSRLW Gm, Em"); + nextop = F8; + GETGM(d0); + GETEM(d1, 0); + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + VSLEI_DU(v0, d1, 15); + VREPLVEI_H(v1, d1, 0); + VSRL_H(d0, d0, v1); + VAND_V(d0, d0, v0); + break; + case 0xD2: + INST_NAME("PSRLD Gm, Em"); + nextop = F8; + GETGM(d0); + GETEM(d1, 0); + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + VSLEI_DU(v0, d1, 31); + VREPLVEI_W(v1, d1, 0); + VSRL_W(d0, d0, v1); + VAND_V(d0, d0, v0); + break; + case 0xD3: + INST_NAME("PSRLQ Gm, Em"); + nextop = F8; + GETGM(d0); + GETEM(d1, 0); + v0 = fpu_get_scratch(dyn); + VLDI(v0, 0b0110000111111); // broadcast 63 as 64bit imm + VSLE_DU(v0, d1, v0); + VSRL_D(d0, d0, d1); + VAND_V(d0, d0, v0); + break; + case 0xF1: + INST_NAME("PSLLW Gm,Em"); + nextop = F8; + GETGM(d0); + GETEM(d1, 0); + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + VSLEI_DU(v0, d1, 15); + VREPLVEI_H(v1, d1, 0); + VSLL_H(d0, d0, v1); + VAND_V(d0, d0, v0); + break; + case 0xF2: + INST_NAME("PSLLD Gm,Em"); + nextop = F8; + GETGM(d0); + GETEM(d1, 0); + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + VSLEI_DU(v0, d1, 31); + VREPLVEI_W(v1, d1, 0); + VSLL_W(d0, d0, v1); + VAND_V(d0, d0, v0); + break; + case 0xF3: + INST_NAME("PSLLQ Gm, Em"); + nextop = F8; + GETGM(d0); + GETEM(d1, 0); + v0 = fpu_get_scratch(dyn); + VLDI(v0, 0b0110000111111); // broadcast 63 as 64bit imm + VSLE_DU(v0, d1, v0); + VSLL_D(d0, d0, d1); + VAND_V(d0, d0, v0); + break; + case 0xFC: + INST_NAME("PADDB Gm, Em"); + nextop = F8; + GETGM(v0); + GETEM(v1, 0); + VADD_B(v0, v0, v1); + break; default: DEFAULT; } diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 4f5e9b08..40568420 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -395,6 +395,22 @@ MOVGR2FR_D(a, x2); \ } +// Get GM, might use x1, x2 and x3 +#define GETGM(a) \ + gd = ((nextop & 0x38) >> 3); \ + a = mmx_get_reg(dyn, ninst, x1, x2, x3, gd) + +// Get EM, might use x1, x2 and x3 +#define GETEM(a, D) \ + if (MODREG) { \ + a = mmx_get_reg(dyn, ninst, x1, x2, x3, (nextop & 7)); \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \ + a = fpu_get_scratch(dyn); \ + FLD_D(a, ed, fixedaddress); \ + } + // Write gb (gd) back to original register / memory, using s1 as scratch #define GBBACK() BSTRINS_D(gb1, gd, gb2 + 7, gb2); diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index 54240f96..39e53ff9 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -1436,6 +1436,9 @@ LSX instruction starts with V, LASX instruction starts with XV. #define VSLE_HU(vd, vj, vk) EMIT(type_3R(0b01110000000001001, vk, vj, vd)) #define VSLE_WU(vd, vj, vk) EMIT(type_3R(0b01110000000001010, vk, vj, vd)) #define VSLE_DU(vd, vj, vk) EMIT(type_3R(0b01110000000001011, vk, vj, vd)) +#define VSLEI_BU(vd, vj, imm5) EMIT(type_2RI5(0b01110010100001000, imm5, vj, vd)) +#define VSLEI_HU(vd, vj, imm5) EMIT(type_2RI5(0b01110010100001001, imm5, vj, vd)) +#define VSLEI_WU(vd, vj, imm5) EMIT(type_2RI5(0b01110010100001010, imm5, vj, vd)) #define VSLEI_DU(vd, vj, imm5) EMIT(type_2RI5(0b01110010100001011, imm5, vj, vd)) #define VSLT_B(vd, vj, vk) EMIT(type_3R(0b01110000000001100, vk, vj, vd)) #define VSLT_H(vd, vj, vk) EMIT(type_3R(0b01110000000001101, vk, vj, vd)) diff --git a/src/dynarec/la64/la64_printer.c b/src/dynarec/la64/la64_printer.c index c88b95ba..93aab1a3 100644 --- a/src/dynarec/la64/la64_printer.c +++ b/src/dynarec/la64/la64_printer.c @@ -691,6 +691,14 @@ const char* la64_print(uint32_t opcode, uintptr_t addr) snprintf(buff, sizeof(buff), "%-15s %s, %s, %s", "FCOPYSIGN.D", Ft[Rd], Ft[Rj], Ft[Rk]); return buff; } + if (isMask(opcode, "0000000100010100100101jjjjjddddd", &a)) { + snprintf(buff, sizeof(buff), "%-15s %s, %s", "FMOV.S", Ft[Rd], Ft[Rj]); + return buff; + } + if (isMask(opcode, "0000000100010100100110jjjjjddddd", &a)) { + snprintf(buff, sizeof(buff), "%-15s %s, %s", "FMOV.D", Ft[Rd], Ft[Rj]); + return buff; + } if (isMask(opcode, "0000000100010100101001jjjjjddddd", &a)) { snprintf(buff, sizeof(buff), "%-15s %s, %s", "MOVGR2FR.W", Ft[Rd], Xt[Rj]); return buff; |