diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-05-02 03:37:41 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-01 21:37:41 +0200 |
| commit | 2405e6c8e84ff6901ee58c98b207195f564eb702 (patch) | |
| tree | 7eae7ada131989d8c02438becaad2c76623e05cd | |
| parent | 817408d2471819f0c5f34f787b479dd11324b489 (diff) | |
| download | box64-2405e6c8e84ff6901ee58c98b207195f564eb702.tar.gz box64-2405e6c8e84ff6901ee58c98b207195f564eb702.zip | |
[LA64_DYNAREC] Added more opcodes (#1482)
| -rw-r--r-- | src/core.c | 2 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 15 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_f30f.c | 38 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 20 |
4 files changed, 74 insertions, 1 deletions
diff --git a/src/core.c b/src/core.c index 7b8b954c..bc58b040 100644 --- a/src/core.c +++ b/src/core.c @@ -690,7 +690,7 @@ void LoadLogEnv() box64_dynarec_fastround = p[0]-'0'; } if(!box64_dynarec_fastround) - printf_log(LOG_INFO, "Dynarec will try tp generate x86 precise IEEE->int rounding\n"); + printf_log(LOG_INFO, "Dynarec will try to generate x86 precise IEEE->int rounding\n"); } p = getenv("BOX64_DYNAREC_SAFEFLAGS"); if(p) { diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index 731e0f72..fb8cf96d 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -134,6 +134,14 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni VEXTRINS_D(v0, q1, 0); } break; + case 0x14: + INST_NAME("UNPCKLPS Gx, Ex"); + nextop = F8; + SMREAD(); + GETEX(q0, 0, 0); + GETGX(v0, 1); + VILVL_W(v0, q0, v0); + break; case 0x16: nextop = F8; if (MODREG) { @@ -271,6 +279,13 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni VXOR_V(q0, q0, q1); } break; + case 0x5A: + INST_NAME("CVTPS2PD Gx, Ex"); + nextop = F8; + GETEX(q0, 0, 0); + GETGX(q1, 1); + VFCVTL_D_S(q1, q0); + break; #define GO(GETFLAGS, NO, YES, F, I) \ if (box64_dynarec_test == 2) { NOTEST(x1); } \ diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c index 496fb001..b3be296f 100644 --- a/src/dynarec/la64/dynarec_la64_f30f.c +++ b/src/dynarec/la64/dynarec_la64_f30f.c @@ -99,6 +99,35 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int } VEXTRINS_W(v0, d1, 0); break; + case 0x2C: + INST_NAME("CVTTSS2SI Gd, Ex"); + nextop = F8; + GETGD; + GETEXSS(d0, 0, 0); + if (!box64_dynarec_fastround) { + MOVGR2FCSR(FCSR2, xZR); // reset all bits + } + d1 = fpu_get_scratch(dyn); + if (rex.w) { + FTINTRZ_L_S(d1, d0); + MOVFR2GR_D(gd, d1); + } else { + FTINTRZ_W_S(d1, d0); + MOVFR2GR_S(gd, d1); + } + if (!rex.w) ZEROUP(gd); + if (!box64_dynarec_fastround) { + MOVFCSR2GR(x5, FCSR2); // get back FPSR to check + MOV32w(x3, (1 << FR_V) | (1 << FR_O)); + AND(x5, x5, x3); + CBZ_NEXT(x5); + if (rex.w) { + MOV64x(gd, 0x8000000000000000LL); + } else { + MOV32w(gd, 0x80000000); + } + } + break; case 0x59: INST_NAME("MULSS Gx, Ex"); nextop = F8; @@ -117,6 +146,15 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int FCVT_D_S(d1, v1); VEXTRINS_D(v0, d1, 0); break; + case 0x5C: + INST_NAME("SUBSS Gx, Ex"); + nextop = F8; + GETGX(v0, 1); + d1 = fpu_get_scratch(dyn); + GETEXSS(d0, 0, 0); + FSUB_S(d1, v0, d0); + VEXTRINS_W(v0, d1, 0); + break; case 0x5D: INST_NAME("MINSS Gx, Ex"); nextop = F8; diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index 93d50b99..9951f070 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -141,6 +141,22 @@ f24-f31 fs0-fs7 Static registers Callee #define sOR 0x15 #define sUNE 0x19 +#define FCSR0 0 +#define FCSR1 1 +#define FCSR2 2 +#define FCSR3 3 + +#define FR_V 28 +#define FR_Z 27 +#define FR_O 26 +#define FR_U 25 +#define FR_I 24 + +#define RM_RNE 0b0000000000 +#define RM_RZ 0b0100000000 +#define RM_RP 0b1000000000 +#define RM_RM 0b1100000000 + // split a 32bits value in 20bits + 12bits, adjust the upper part is 12bits is negative #define SPLIT20(A) (((A) + 0x800) >> 12) #define SPLIT12(A) ((A) & 0xfff) @@ -1230,6 +1246,10 @@ LSX instruction starts with V, LASX instruction starts with XV. #define VFMAXA_D(vd, vj, vk) EMIT(type_3R(0b01110001010000010, vk, vj, vd)) #define VFMINA_S(vd, vj, vk) EMIT(type_3R(0b01110001010000101, vk, vj, vd)) #define VFMINA_D(vd, vj, vk) EMIT(type_3R(0b01110001010000110, vk, vj, vd)) +#define VFCVTL_S_H(vd, vj) EMIT(type_2R(0b0111001010011101111010, vj, vd)) +#define VFCVTH_S_H(vd, vj) EMIT(type_2R(0b0111001010011101111011, vj, vd)) +#define VFCVTL_D_S(vd, vj) EMIT(type_2R(0b0111001010011101111100, vj, vd)) +#define VFCVTH_D_S(vd, vj) EMIT(type_2R(0b0111001010011101111101, vj, vd)) #define VFCVT_H_S(vd, vj, vk) EMIT(type_3R(0b01110001010001100, vk, vj, vd)) #define VFCVT_S_D(vd, vj, vk) EMIT(type_3R(0b01110001010001101, vk, vj, vd)) #define VFTINT_W_S(vd, vj) EMIT(type_2R(0b0111001010011110001100, vj, vd)) |