diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-02-08 22:45:21 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-08 15:45:21 +0100 |
| commit | 58b24c85a2407a6c2ab6dfc2f18555dd929ad7e1 (patch) | |
| tree | 1ac38a6cdbd07097cc6141dc4a0749aac5a37248 /src | |
| parent | 28ebc1a0b779d6fca2f0b7e45291df6795be6c0a (diff) | |
| download | box64-58b24c85a2407a6c2ab6dfc2f18555dd929ad7e1.tar.gz box64-58b24c85a2407a6c2ab6dfc2f18555dd929ad7e1.zip | |
[LA64_DYNAREC] Added more opcodes (#2328)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_660f.c | 25 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 3 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 7 |
3 files changed, 35 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c index ccb36ad6..b5fbce5b 100644 --- a/src/dynarec/la64/dynarec_la64_660f.c +++ b/src/dynarec/la64/dynarec_la64_660f.c @@ -456,6 +456,13 @@ 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 0x23: + INST_NAME("PMOVSXWD Gx, Ex"); // SSE4 opcode! + nextop = F8; + GETEX64(q1, 0, 0); + GETGX_empty(q0); + VSLLWIL_W_H(q0, q1, 0); + break; case 0x2B: INST_NAME("PACKUSDW Gx, Ex"); // SSE4 opcode! nextop = F8; @@ -840,6 +847,24 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int GOCOND(0x40, "CMOV", "Gd, Ed"); #undef GO + case 0x51: + INST_NAME("SQRTPD Gx, Ex"); + nextop = F8; + GETEX(q0, 0, 0); + GETGX_empty(q1); + if (!BOX64ENV(dynarec_fastnan)) { + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + VFCMP_D(v0, q0, q0, cEQ); + VFSQRT_D(q1, q0); + VFCMP_D(v1, q1, q1, cEQ); + VANDN_V(v1, v1, v0); + VSLLI_D(v1, v1, 63); + VOR_V(q1, q1, v1); + } else { + VFSQRT_D(q1, q0); + } + break; case 0x54: INST_NAME("ANDPD Gx, Ex"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 495fa44e..4653759d 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -355,6 +355,9 @@ FLD_D(a, ed, fixedaddress); \ } +// Get Ex as 64bits, not a quad (warning, x1 get used, x2 might too) +#define GETEX64(a, w, D) GETEXSD(a, w, D) + // Get Ex as a single, not a quad (warning, x1 get used) #define GETEXSS(a, w, D) \ if (MODREG) { \ diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index 257fcae6..2a59c5ed 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -1908,6 +1908,13 @@ LSX instruction starts with V, LASX instruction starts with XV. #define VREPLGR2VR_H(vd, rj) EMIT(type_2R(0b0111001010011111000001, rj, vd)) #define VREPLGR2VR_W(vd, rj) EMIT(type_2R(0b0111001010011111000010, rj, vd)) #define VREPLGR2VR_D(vd, rj) EMIT(type_2R(0b0111001010011111000011, rj, vd)) +#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 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)) +#define VNEG_D(vd, vj) EMIT(type_2R(0b0111011010011100001111, vj, vd)) //////////////////////////////////////////////////////////////////////////////// // (undocumented) LBT extension instructions |