diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_660f.c | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index bb833844..1383294c 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -234,24 +234,30 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VFCVTZSQD(q0, v1); SQXTN_32(q0, q0); } else { - MRS_fpsr(x5); - BFCw(x5, FPSR_IOC, 1); // reset IOC bit - MSR_fpsr(x5); - ORRw_mask(x2, xZR, 1, 0); //0x80000000 - d0 = fpu_get_scratch(dyn); - for (int i=0; i<2; ++i) { + if(arm64_frintts) { + VFRINT32ZD(q0, q0); + VFCVTZSQD(q0, q0); + SQXTN_32(q0, q0); + } else { + MRS_fpsr(x5); BFCw(x5, FPSR_IOC, 1); // reset IOC bit - if (i) { - VMOVeD(d0, 0, v1, i); - FRINTZD(d0, d0); - } else { - FRINTZD(d0, v1); + MSR_fpsr(x5); + ORRw_mask(x2, xZR, 1, 0); //0x80000000 + d0 = fpu_get_scratch(dyn); + for (int i=0; i<2; ++i) { + BFCw(x5, FPSR_IOC, 1); // reset IOC bit + if (i) { + VMOVeD(d0, 0, v1, i); + FRINTZD(d0, d0); + } else { + FRINTZD(d0, v1); + } + FCVTZSwD(x1, d0); + MRS_fpsr(x5); // get back FPSR to check the IOC bit + TBZ(x5, FPSR_IOC, 4+4); + MOVw_REG(x1, x2); + VMOVQSfrom(q0, i, x1); } - FCVTZSwD(x1, d0); - MRS_fpsr(x5); // get back FPSR to check the IOC bit - TBZ(x5, FPSR_IOC, 4+4); - MOVw_REG(x1, x2); - VMOVQSfrom(q0, i, x1); } } break; @@ -268,24 +274,30 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VFCVTZSS(q0, q0); } else { u8 = sse_setround(dyn, ninst, x1, x2, x3); - MRS_fpsr(x5); - BFCw(x5, FPSR_IOC, 1); // reset IOC bit - MSR_fpsr(x5); - ORRw_mask(x2, xZR, 1, 0); //0x80000000 - d0 = fpu_get_scratch(dyn); - for (int i=0; i<2; ++i) { + if(arm64_frintts) { + VFRINT32XD(q0, q0); + VFCVTZSQD(q0, q0); + SQXTN_32(q0, q0); + } else { + MRS_fpsr(x5); BFCw(x5, FPSR_IOC, 1); // reset IOC bit - if (i) { - VMOVeD(d0, 0, v1, i); - FRINTID(d0, d0); - } else { - FRINTID(d0, v1); + MSR_fpsr(x5); + ORRw_mask(x2, xZR, 1, 0); //0x80000000 + d0 = fpu_get_scratch(dyn); + for (int i=0; i<2; ++i) { + BFCw(x5, FPSR_IOC, 1); // reset IOC bit + 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 + TBZ(x5, FPSR_IOC, 4+4); + MOVw_REG(x1, x2); + VMOVQSfrom(q0, i, x1); } - FCVTZSwD(x1, d0); - MRS_fpsr(x5); // get back FPSR to check the IOC bit - TBZ(x5, FPSR_IOC, 4+4); - MOVw_REG(x1, x2); - VMOVQSfrom(q0, i, x1); } x87_restoreround(dyn, ninst, u8); } |