diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-02-17 20:49:12 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-17 13:49:12 +0100 |
| commit | 26dd597a1b27fe8e3be0df1f3640428d2791e497 (patch) | |
| tree | afe05e55f11153fc0e8c1397f612be92efa1f229 /src | |
| parent | 040f8d9a9f84a43bac88a7614711b442cc750519 (diff) | |
| download | box64-26dd597a1b27fe8e3be0df1f3640428d2791e497.tar.gz box64-26dd597a1b27fe8e3be0df1f3640428d2791e497.zip | |
[LA64_DYNAREC] Added more opcodes (#2374)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_660f.c | 86 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 15 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 3 |
3 files changed, 96 insertions, 8 deletions
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c index 86c37c06..0c19b1c5 100644 --- a/src/dynarec/la64/dynarec_la64_660f.c +++ b/src/dynarec/la64/dynarec_la64_660f.c @@ -456,6 +456,30 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int GETGX_empty(q0); VSIGNCOV_W(q0, q1, q1); break; + case 0x20: + INST_NAME("PMOVSXBW Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX64(q1, 0, 0); + GETGX_empty(q0); + VSLLWIL_H_B(q0, q1, 0); + break; + case 0x21: + INST_NAME("PMOVSXBD Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX32(q1, 0, 0); + GETGX_empty(q0); + VSLLWIL_H_B(q0, q1, 0); + VSLLWIL_W_H(q0, q0, 0); + break; + case 0x22: + INST_NAME("PMOVSXBQ Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX16(q1, 0, 0); + GETGX_empty(q0); + VSLLWIL_H_B(q0, q1, 0); + VSLLWIL_W_H(q0, q0, 0); + VSLLWIL_D_W(q0, q0, 0); + break; case 0x23: INST_NAME("PMOVSXWD Gx, Ex"); // SSE4 opcode! nextop = F8; @@ -464,22 +488,22 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int VSLLWIL_W_H(q0, q1, 0); break; case 0x24: - INST_NAME("PMOVSXWQ Gx, Ex"); + INST_NAME("PMOVSXWQ Gx, Ex"); // SSE4 opcode! nextop = F8; - GETEXSS(q1, 0, 0); + GETEX32(q1, 0, 0); GETGX_empty(q0); - VSLLWIL_W_H(q0, q1, 0); // 16bits->32bits - VSLLWIL_D_W(q0, q0, 0); // 32bits->64bits + VSLLWIL_W_H(q0, q1, 0); + VSLLWIL_D_W(q0, q0, 0); break; case 0x25: - INST_NAME("PMOVSXDQ Gx, Ex"); + INST_NAME("PMOVSXDQ Gx, Ex"); // SSE4 opcode! nextop = F8; GETEX64(q1, 0, 0); GETGX_empty(q0); - VSLLWIL_D_W(q0, q1, 0); // 32bits->64bits + VSLLWIL_D_W(q0, q1, 0); break; case 0x29: - INST_NAME("PCMPEQQ Gx, Ex"); // SSE4 opcode! + INST_NAME("PCMPEQQ Gx, Ex"); // SSE4 opcode! nextop = F8; GETEX(q1, 0, 0); GETGX_empty(q0); @@ -505,12 +529,58 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int } break; case 0x30: - INST_NAME("PMOVZXBW Gx, Ex"); + INST_NAME("PMOVZXBW Gx, Ex"); // SSE4 opcode! nextop = F8; GETEX(q1, 0, 0); GETGX_empty(q0); VEXT2XV_HU_BU(q0, q1); break; + case 0x31: + INST_NAME("PMOVZXBD Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX32(q1, 0, 0); + GETGX_empty(q0); + VSLLWIL_HU_BU(q0, q1, 0); + VSLLWIL_WU_HU(q0, q0, 0); + break; + case 0x32: + INST_NAME("PMOVZXBQ Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX16(q1, 0, 0); + GETGX_empty(q0); + VSLLWIL_HU_BU(q0, q1, 0); + VSLLWIL_WU_HU(q0, q0, 0); + VSLLWIL_DU_WU(q0, q0, 0); + break; + case 0x33: + INST_NAME("PMOVZXWD Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX64(q1, 0, 0); + GETGX_empty(q0); + VSLLWIL_WU_HU(q0, q1, 0); + break; + case 0x34: + INST_NAME("PMOVZXWQ Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX32(q1, 0, 0); + GETGX_empty(q0); + VSLLWIL_WU_HU(q0, q1, 0); + VSLLWIL_DU_WU(q0, q0, 0); + break; + case 0x35: + INST_NAME("PMOVZXDQ Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX64(q1, 0, 0); + GETGX_empty(q0); + VSLLWIL_DU_WU(q0, q1, 0); + break; + case 0x39: + INST_NAME("PMINSD Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX(q1, 0, 0); + GETGX(q0, 1); + VMIN_W(q0, q0, q1); + break; case 0x3A: INST_NAME("PMINUW Gx, Ex"); // SSE4 opcode! nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index b912fe8a..98be10b3 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -381,6 +381,21 @@ FLD_S(a, ed, fixedaddress); \ } +// Get Ex as 32bits, not a quad (warning, x1 get used) +#define GETEX32(a, w, D) GETEXSS(a, w, D) + +// Get Ex as 16bits, not a quad (warning, x1 get used) +#define GETEX16(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); \ + LD_HU(x2, ed, fixedaddress); \ + MOVGR2FR_D(a, x2); \ + } + // 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 db82087f..54240f96 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -1921,6 +1921,9 @@ LSX instruction starts with V, LASX instruction starts with XV. #define VSLLWIL_H_B(vd, vj, imm3) EMIT(type_2RI3(0b0111001100001000001, imm3, vj, vd)) #define VSLLWIL_W_H(vd, vj, imm4) EMIT(type_2RI4(0b011100110000100001, imm4, vj, vd)) #define VSLLWIL_D_W(vd, vj, imm5) EMIT(type_2RI5(0b01110011000010001, imm5, vj, vd)) +#define VSLLWIL_HU_BU(vd, vj, imm3) EMIT(type_2RI3(0b0111001100001100001, imm3, vj, vd)) +#define VSLLWIL_WU_HU(vd, vj, imm4) EMIT(type_2RI4(0b011100110000110001, imm4, vj, vd)) +#define VSLLWIL_DU_WU(vd, vj, imm5) EMIT(type_2RI5(0b01110011000011001, imm5, vj, vd)) #define VNEG_B(vd, vj) EMIT(type_2R(0b0111011010011100001100, vj, vd)) #define VNEG_H(vd, vj) EMIT(type_2R(0b0111011010011100001101, vj, vd)) #define VNEG_W(vd, vj) EMIT(type_2R(0b0111011010011100001110, vj, vd)) |