diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-06-06 13:47:14 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-06-06 13:47:14 +0200 |
| commit | 1612687acfd6200515fc38fd46180f09f5a41661 (patch) | |
| tree | 6aee8c56bf64a97f80d6cc5deb94da277e6ed0a7 /src | |
| parent | 67d587cd9bfd5d8594df7ec1ba78ebe002b7dbee (diff) | |
| download | box64-1612687acfd6200515fc38fd46180f09f5a41661.tar.gz box64-1612687acfd6200515fc38fd46180f09f5a41661.zip | |
[ARM64_DYNAREC] Fixed VCMPSS opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_avx_f2_0f.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_avx_f2_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_f2_0f.c index 3391a293..816b695c 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_f2_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_f2_0f.c @@ -348,6 +348,56 @@ uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, YMM0(gd); break; + case 0xE6: + INST_NAME("VCVTPD2DQ Gx, Ex"); + nextop = F8; + u8 = sse_setround(dyn, ninst, x1, x2, x6); + for(int l=0; l<1+vex.l; ++l) { + if(!l) { + GETEX_Y(v1, 0, 0); + GETGX_empty(v0); + } else { + if(box64_dynarec_fastround) + d0 = fpu_get_scratch(dyn, ninst); + GETEY(v1); + } + if(box64_dynarec_fastround) { + VFRINTIDQ(v0, v1); + VFCVTNSQD(v0, v0); // convert double -> int64 + if(!l) + SQXTN_32(v0, v0); // convert int64 -> int32 with saturation in lower part, RaZ high part + else + SQXTN2_32(v0, d0); // convert int64 -> int32 with saturation in higher part + } else { + if(!l) { + MRS_fpsr(x5); + BFCw(x5, FPSR_IOC, 1); // reset IOC bit + MSR_fpsr(x5); + ORRw_mask(x4, xZR, 1, 0); //0x80000000 + d0 = fpu_get_scratch(dyn, ninst); + } + for(int i=0; i<2; ++i) { + BFCw(x5, FPSR_IOC, 1); // reset IOC bit + MSR_fpsr(x5); + if(i) { + VMOVeD(d0, 0, v1, i); + FRINTID(d0, d0); + } else { + FRINTID(d0, v1); + } + FCVTZSwD(x1, d0); + MRS_fpsr(x5); // get back FPSR to check the IOC bit + TSTw_mask(x5, 0, 0); // mask = 1 = FPSR_IOC + CSELx(x1, x1, x4, cEQ); + VMOVQSfrom(v0, i+l*2, x1); + } + if(!vex.l && !l) VMOVQDfrom(v0, 1, xZR); + } + } + x87_restoreround(dyn, ninst, u8); + YMM0(gd); + break; + default: DEFAULT; } |