diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-05-01 17:04:50 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-01 11:04:50 +0200 |
| commit | 0fe7e7a88df5404fbc49f0fc1e6a77fa2b20d75a (patch) | |
| tree | 14794dc5f86832369ca169c26ca265b55d1e7e09 /src | |
| parent | 08bc57045af7067adf3495d274a4800bb8385df0 (diff) | |
| download | box64-0fe7e7a88df5404fbc49f0fc1e6a77fa2b20d75a.tar.gz box64-0fe7e7a88df5404fbc49f0fc1e6a77fa2b20d75a.zip | |
[LA64_DYNAREC] Added more opcodes (#1480)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 51 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_660f.c | 302 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 7 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 22 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_printer.c | 4 |
5 files changed, 384 insertions, 2 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 721f3864..47a0548d 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -121,6 +121,15 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_or32(dyn, ninst, rex, ed, gd, x3, x4); WBACK; break; + case 0x0A: + INST_NAME("OR Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB(x1, 0); + GETGB(x2); + emit_or8(dyn, ninst, x2, x1, x4, x5); + GBBACK(); + break; case 0x0B: INST_NAME("OR Gd, Ed"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -553,6 +562,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0x80: nextop = F8; switch((nextop>>3)&7) { + case 0: // ADD + INST_NAME("ADD Eb, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEB(x1, 1); + u8 = F8; + emit_add8c(dyn, ninst, x1, u8, x2, x4, x5); + EBBACK(); + break; case 1: // OR INST_NAME("OR Eb, Ib"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -828,6 +845,40 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SMWRITELOCK(lock); } break; + case 0x8A: + INST_NAME("MOV Gb, Eb"); + nextop = F8; + if (rex.rex) { + gb1 = gd = TO_LA64(((nextop & 0x38) >> 3) + (rex.r << 3)); + gb2 = 0; + } else { + gd = (nextop & 0x38) >> 3; + gb1 = TO_LA64(gd & 3); + gb2 = ((gd & 4) << 1); + } + if (MODREG) { + if (rex.rex) { + wback = TO_LA64((nextop & 7) + (rex.b << 3)); + wb2 = 0; + } else { + wback = (nextop & 7); + wb2 = (wback >> 2); + wback = TO_LA64(wback & 3); + } + if (wb2) { + BSTRPICK_D(x4, wback, 7 + wb2 * 8, wb2 * 8); + ed = x4; + } else { + ed = wback; + } + } else { + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, &lock, 1, 0); + SMREADLOCK(lock); + LD_BU(x4, wback, fixedaddress); + ed = x4; + } + BSTRINS_D(gb1, ed, gb2 + 7, gb2); + break; case 0x8B: INST_NAME("MOV Gd, Ed"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c index 68f277bd..487e8195 100644 --- a/src/dynarec/la64/dynarec_la64_660f.c +++ b/src/dynarec/la64/dynarec_la64_660f.c @@ -194,6 +194,13 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int DEFAULT; } break; + case 0x60: + INST_NAME("PUNPCKLBW Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VILVL_B(v0, q0, v0); + break; case 0x61: INST_NAME("PUNPCKLWD Gx,Ex"); nextop = F8; @@ -201,6 +208,56 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(q0, 0, 0); VILVL_H(v0, q0, v0); break; + case 0x62: + INST_NAME("PUNPCKLDQ Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VILVL_W(v0, q0, v0); + break; + case 0x64: + INST_NAME("PCMPGTB Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(v1, 0, 0); + VSLT_B(v0, v1, v0); + break; + case 0x65: + INST_NAME("PCMPGTW Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(v1, 0, 0); + VSLT_H(v0, v1, v0); + break; + case 0x66: + INST_NAME("PCMPGTD Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(v1, 0, 0); + VSLT_W(v0, v1, v0); + break; + case 0x67: + INST_NAME("PACKUSWB Gx, Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(v1, 0, 0); + if (v0 == v1) { + VMAXI_H(v0, v0, 0); + VPICKEV_B(v0, v0, v0); + } else { + q1 = fpu_get_scratch(dyn); + VMAXI_H(v0, v0, 0); + VMAXI_H(q1, v1, 0); + VPICKEV_B(v0, q1, v0); + } + break; + case 0x68: + INST_NAME("PUNPCKHBW Gx,Ex"); + nextop = F8; + GETGX(q0, 1); + GETEX(q1, 0, 0); + VILVH_B(q0, q1, q0); + break; case 0x69: INST_NAME("PUNPCKHWD Gx,Ex"); nextop = F8; @@ -208,6 +265,13 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(q1, 0, 0); VILVH_H(q0, q1, q0); break; + case 0x6A: + INST_NAME("PUNPCKHDQ Gx,Ex"); + nextop = F8; + GETGX(q0, 1); + GETEX(q1, 0, 0); + VILVH_W(q0, q1, q0); + break; case 0x6C: INST_NAME("PUNPCKLQDQ Gx,Ex"); nextop = F8; @@ -259,6 +323,167 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int VLD(v0, ed, fixedaddress); } break; + case 0x70: + INST_NAME("PSHUFD Gx,Ex,Ib"); + nextop = F8; + GETGX(v0, 1); + GETEX(v1, 0, 1); + u8 = F8; + VSHUF4I_W(v0, v1, u8); + break; + case 0x71: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 2: + INST_NAME("PSRLW Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8) { + if (u8 > 15) { + VXOR_V(q0, q0, q0); + } else if (u8) { + VSRLI_H(q0, q0, u8); + } + PUTEX(q0); + } + break; + case 4: + INST_NAME("PSRAW Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8 > 15) u8 = 15; + if (u8) { + VSRAI_H(q0, q0, u8); + } + PUTEX(q0); + break; + case 6: + INST_NAME("PSLLW Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8) { + if (u8 > 15) { + VXOR_V(q0, q0, q0); + } else { + VSLLI_H(q0, q0, u8); + } + PUTEX(q0); + } + break; + default: + *ok = 0; + DEFAULT; + } + break; + case 0x72: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 2: + INST_NAME("PSRLD Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8) { + if (u8 > 31) { + VXOR_V(q0, q0, q0); + } else if (u8) { + VSRLI_W(q0, q0, u8); + } + PUTEX(q0); + } + break; + case 4: + INST_NAME("PSRAD Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8 > 31) u8 = 31; + if (u8) { + VSRAI_W(q0, q0, u8); + } + PUTEX(q0); + break; + case 6: + INST_NAME("PSLLD Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8) { + if (u8 > 31) { + VXOR_V(q0, q0, q0); + } else { + VSLLI_W(q0, q0, u8); + } + PUTEX(q0); + } + break; + default: + DEFAULT; + } + break; + case 0x73: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 2: + INST_NAME("PSRLQ Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8) { + if (u8 > 63) { + VXOR_V(q0, q0, q0); + } else { + VSRLI_D(q0, q0, u8); + } + PUTEX(q0); + } + break; + case 3: + INST_NAME("PSRLDQ Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8) { + if (u8 > 15) { + XVOR_V(q0, q0, q0); + } else { + VBSRL_V(q0, q0, u8); + } + PUTEX(q0); + } + break; + case 6: + INST_NAME("PSLLQ Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8) { + if (u8 > 63) { + XVOR_V(q0, q0, q0); + } else { + VSLLI_D(q0, q0, u8); + } + PUTEX(q0); + } + break; + case 7: + INST_NAME("PSLLDQ Ex, Ib"); + GETEX(q0, 1, 1); + u8 = F8; + if (u8) { + if (u8 > 15) { + VXOR_V(q0, q0, q0); + } else if (u8 > 0) { + VBSLL_V(q0, q0, u8); + } + PUTEX(q0); + } + break; + default: + DEFAULT; + } + break; + case 0x76: + INST_NAME("PCMPEQD Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VSEQ_W(v0, v0, q0); + break; case 0x7E: INST_NAME("MOVD Ed,Gx"); nextop = F8; @@ -318,6 +543,13 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(q0, 0, 0); VADD_D(v0, v0, q0); break; + case 0xD5: + INST_NAME("PMULLW Gx,Ex"); + nextop = F8; + GETGX(q0, 1); + GETEX(q1, 0, 0); + VMUL_H(q0, q0, q1); + break; case 0xD6: INST_NAME("MOVQ Ex, Gx"); nextop = F8; @@ -339,6 +571,27 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEX(q0, 0, 0); VAND_V(v0, v0, q0); break; + case 0xDF: + INST_NAME("PANDN Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VANDN_V(v0, v0, q0); + break; + case 0xE4: + INST_NAME("PMULHUW Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(v1, 0, 0); + VMUH_HU(v0, v0, v1); + break; + case 0xEB: + INST_NAME("POR Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VOR_V(v0, v0, q0); + break; case 0xEF: INST_NAME("PXOR Gx,Ex"); nextop = F8; @@ -353,6 +606,55 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int VXOR_V(q0, q0, q1); } break; + case 0xF8: + INST_NAME("PSUBB Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VSUB_B(v0, v0, q0); + break; + case 0xF9: + INST_NAME("PSUBW Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VSUB_H(v0, v0, q0); + break; + case 0xFA: + INST_NAME("PSUBD Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VSUB_W(v0, v0, q0); + break; + case 0xFB: + INST_NAME("PSUBQ Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VSUB_D(v0, v0, q0); + break; + case 0xFC: + INST_NAME("PADDB Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VADD_B(v0, v0, q0); + break; + case 0xFD: + INST_NAME("PADDW Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VADD_H(v0, v0, q0); + break; + case 0xFE: + INST_NAME("PADDD Gx,Ex"); + nextop = F8; + GETGX(v0, 1); + GETEX(q0, 0, 0); + VADD_W(v0, v0, q0); + break; default: DEFAULT; } diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index a7d55077..50405c1c 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -279,6 +279,13 @@ VLD(a, ed, fixedaddress); \ } +// Put Back EX if it was a memory and not an emm register +#define PUTEX(a) \ + if (!MODREG) { \ + VST(a, ed, fixedaddress); \ + SMWRITE2(); \ + } + // Get Ex as a double, not a quad (warning, x1 get used, x2 might too) #define GETEXSD(a, D) \ if (MODREG) { \ diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index afe2f5fd..93d50b99 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -1140,6 +1140,18 @@ LSX instruction starts with V, LASX instruction starts with XV. #define VSRA_H(vd, vj, vk) EMIT(type_3R(0b01110000111011001, vk, vj, vd)) #define VSRA_W(vd, vj, vk) EMIT(type_3R(0b01110000111011010, vk, vj, vd)) #define VSRA_D(vd, vj, vk) EMIT(type_3R(0b01110000111011011, vk, vj, vd)) +#define VSLLI_B(vd, vj, imm3) EMIT(type_2RI3(0b0111001100101100001, imm3, vj, vd)) +#define VSLLI_H(vd, vj, imm4) EMIT(type_2RI4(0b011100110010110001, imm4, vj, vd)) +#define VSLLI_W(vd, vj, imm5) EMIT(type_2RI5(0b01110011001011001, imm5, vj, vd)) +#define VSLLI_D(vd, vj, imm6) EMIT(type_2RI6(0b0111001100101101, imm6, vj, vd)) +#define VSRLI_B(vd, vj, imm3) EMIT(type_2RI3(0b0111001100110000001, imm3, vj, vd)) +#define VSRLI_H(vd, vj, imm4) EMIT(type_2RI4(0b011100110011000001, imm4, vj, vd)) +#define VSRLI_W(vd, vj, imm5) EMIT(type_2RI5(0b01110011001100001, imm5, vj, vd)) +#define VSRLI_D(vd, vj, imm6) EMIT(type_2RI6(0b0111001100110001, imm6, vj, vd)) +#define VSRAI_B(vd, vj, imm3) EMIT(type_2RI3(0b0111001100110100001, imm3, vj, vd)) +#define VSRAI_H(vd, vj, imm4) EMIT(type_2RI4(0b011100110011010001, imm4, vj, vd)) +#define VSRAI_W(vd, vj, imm5) EMIT(type_2RI5(0b01110011001101001, imm5, vj, vd)) +#define VSRAI_D(vd, vj, imm6) EMIT(type_2RI6(0b0111001100110101, imm6, vj, vd)) #define VROTR_B(vd, vj, vk) EMIT(type_3R(0b01110000111011100, vk, vj, vd)) #define VROTR_H(vd, vj, vk) EMIT(type_3R(0b01110000111011101, vk, vj, vd)) #define VROTR_W(vd, vj, vk) EMIT(type_3R(0b01110000111011110, vk, vj, vd)) @@ -1276,6 +1288,8 @@ LSX instruction starts with V, LASX instruction starts with XV. #define VSLT_HU(vd, vj, vk) EMIT(type_3R(0b01110000000010001, vk, vj, vd)) #define VSLT_WU(vd, vj, vk) EMIT(type_3R(0b01110000000010010, vk, vj, vd)) #define VSLT_DU(vd, vj, vk) EMIT(type_3R(0b01110000000010011, vk, vj, vd)) +#define VBSLL_V(vd, vj, imm5) EMIT(type_2RI5(0b01110010100011100, imm5, vj, vd)) +#define VBSRL_V(vd, vj, imm5) EMIT(type_2RI5(0b01110010100011101, imm5, vj, vd)) #define VPACKEV_B(vd, vj, vk) EMIT(type_3R(0b01110001000101100, vk, vj, vd)) #define VPACKEV_H(vd, vj, vk) EMIT(type_3R(0b01110001000101101, vk, vj, vd)) #define VPACKEV_W(vd, vj, vk) EMIT(type_3R(0b01110001000101110, vk, vj, vd)) @@ -1525,6 +1539,14 @@ LSX instruction starts with V, LASX instruction starts with XV. #define XVMOD_HU(vd, vj, vk) EMIT(type_3R(0b01110100111001101, vk, vj, vd)) #define XVMOD_WU(vd, vj, vk) EMIT(type_3R(0b01110100111001110, vk, vj, vd)) #define XVMOD_DU(vd, vj, vk) EMIT(type_3R(0b01110100111001111, vk, vj, vd)) +#define VSAT_B(vd, vj, imm3) EMIT(type_2RI3(0b0111001100100100001, imm3, vj, vd)) +#define VSAT_H(vd, vj, imm4) EMIT(type_2RI4(0b011100110010010001, imm4, vj, vd)) +#define VSAT_W(vd, vj, imm5) EMIT(type_2RI5(0b01110011001001001, imm5, vj, vd)) +#define VSAT_D(vd, vj, imm6) EMIT(type_2RI6(0b0111001100100101, imm6, vj, vd)) +#define VSAT_BU(vd, vj, imm3) EMIT(type_2RI3(0b0111001100101000001, imm3, vj, vd)) +#define VSAT_HU(vd, vj, imm4) EMIT(type_2RI4(0b011100110010100001, imm4, vj, vd)) +#define VSAT_WU(vd, vj, imm5) EMIT(type_2RI5(0b01110011001010001, imm5, vj, vd)) +#define VSAT_DU(vd, vj, imm6) EMIT(type_2RI6(0b0111001100101001, imm6, vj, vd)) #define XVSIGNCOV_B(vd, vj, vk) EMIT(type_3R(0b01110101001011100, vk, vj, vd)) #define XVSIGNCOV_H(vd, vj, vk) EMIT(type_3R(0b01110101001011101, vk, vj, vd)) #define XVSIGNCOV_W(vd, vj, vk) EMIT(type_3R(0b01110101001011110, vk, vj, vd)) diff --git a/src/dynarec/la64/la64_printer.c b/src/dynarec/la64/la64_printer.c index 247653b4..5c58541c 100644 --- a/src/dynarec/la64/la64_printer.c +++ b/src/dynarec/la64/la64_printer.c @@ -2157,11 +2157,11 @@ const char* la64_print(uint32_t opcode, uintptr_t addr) return buff; } if (isMask(opcode, "0010110000iiiiiiiiiiiijjjjjddddd", &a)) { - snprintf(buff, sizeof(buff), "%-15s %s, %s, %d", "VLD.D", Vt[Rd], Xt[Rj], signExtend(imm, 12)); + snprintf(buff, sizeof(buff), "%-15s %s, %s, %d", "VLD", Vt[Rd], Xt[Rj], signExtend(imm, 12)); return buff; } if (isMask(opcode, "0010110001iiiiiiiiiiiijjjjjddddd", &a)) { - snprintf(buff, sizeof(buff), "%-15s %s, %s, %d", "VST.D", Vt[Rd], Xt[Rj], signExtend(imm, 12)); + snprintf(buff, sizeof(buff), "%-15s %s, %s, %d", "VST", Vt[Rd], Xt[Rj], signExtend(imm, 12)); return buff; } if (isMask(opcode, "00000000000000001000000000101000", &a)) { |