[ARM64_DYNAREC] Some more FRINTTS and AVX/SSE fixes (might help #2520)

This commit is contained in:
ptitSeb 2025-04-11 11:22:27 +02:00
parent 51d9eb966d
commit fa85d4d900
5 changed files with 22 additions and 30 deletions

View File

@ -2434,24 +2434,18 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 1: VFCMGTQS(v0, v1, v0); break; // Less than
case 2: VFCMGEQS(v0, v1, v0); break; // Less or equal
case 3: if(v0!=v1) {
q0 = fpu_get_scratch(dyn, ninst);
VFMAXQS(q0, v0, v1); // propagate NAN
VFCMEQQS(v0, q0, q0);
} else {
VFCMEQQS(v0, v0, v0);
VFMAXQS(v0, v0, v1); // propagate NAN
}
VFCMEQQS(v0, v0, v0);
VMVNQ(v0, v0);
break; // NaN (NaN is not equal to himself)
case 4: VFCMEQQS(v0, v0, v1); VMVNQ(v0, v0); break; // Not Equal (or unordered on ARM, not on X86...)
case 5: VFCMGTQS(v0, v1, v0); VMVNQ(v0, v0); break; // Greater or equal or unordered
case 6: VFCMGEQS(v0, v1, v0); VMVNQ(v0, v0); break; // Greater or unordered
case 7: if(v0!=v1) {
q0 = fpu_get_scratch(dyn, ninst);
VFMAXQS(q0, v0, v1); // propagate NAN
VFCMEQQS(v0, q0, q0);
} else {
VFCMEQQS(v0, v0, v0);
VFMAXQS(v0, v0, v1); // propagate NAN
}
VFCMEQQS(v0, v0, v0);
break; // not NaN
}
break;

View File

@ -2825,24 +2825,18 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
case 1: VFCMGTQD(v0, v1, v0); break; // Less than
case 2: VFCMGEQD(v0, v1, v0); break; // Less or equal
case 3: if(v0!=v1) {
q0 = fpu_get_scratch(dyn, ninst);
VFMAXQD(q0, v0, v1); // propagate NAN
VFCMEQQD(v0, q0, q0);
} else {
VFCMEQQD(v0, v0, v0);
VFMAXQD(v0, v0, v1); // propagate NAN
}
VFCMEQQD(v0, v0, v0);
VMVNQ(v0, v0);
break; // NaN (NaN is not equal to himself)
case 4: VFCMEQQD(v0, v0, v1); VMVNQ(v0, v0); break; // Not Equal (or unordered on ARM, not on X86...)
case 5: VFCMGTQD(v0, v1, v0); VMVNQ(v0, v0); break; // Greater or equal or unordered
case 6: VFCMGEQD(v0, v1, v0); VMVNQ(v0, v0); break; // Greater or unordered
case 7: if(v0!=v1) {
q0 = fpu_get_scratch(dyn, ninst);
VFMAXQD(q0, v0, v1); // propagate NAN
VFCMEQQD(v0, q0, q0);
} else {
VFCMEQQD(v0, v0, v0);
VFMAXQD(v0, v0, v1); // propagate NAN
}
VFCMEQQD(v0, v0, v0);
break; // not NaN
}
break;

View File

@ -416,8 +416,10 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
}
if(vex.l) {
GETEY(v1);
FCVTXN2(v0, v1);
if(BOX64ENV(dynarec_fastround)<2) {
if(BOX64ENV(dynarec_fastround)==2) {
FCVTXN2(v0, v1);
} else {
FCVTN2(v0, v1);
x87_restoreround(dyn, ninst, u8);
}
}

View File

@ -152,9 +152,9 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
if(!BOX64ENV(dynarec_fastround) && arm64_frintts) {
v0 = fpu_get_scratch(dyn, ninst);
if(rex.w) {
FRINT64ZS(v0, q0);
FRINT64ZS(v0, d0);
} else {
FRINT32ZS(v0, q0);
FRINT32ZS(v0, d0);
}
FCVTZSxwS(gd, v0);
} else {
@ -334,13 +334,15 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
VFRINT32ZSQ(v0, v1);
VFCVTZSQS(v0, v0);
} else {
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
for(int i=0; i<4; ++i) {
BFCw(x5, FPSR_IOC, 1); // reset IOC bit
MSR_fpsr(x5);
VMOVeS(d0, 0, v1, i);
VFCVTZSs(d0, d0);
if(i) {
VMOVeS(d0, 0, v1, i);
VFCVTZSs(d0, d0);
} else {
VFCVTZSs(d0, v1);
}
MRS_fpsr(x5); // get back FPSR to check the IOC bit
TBZ(x5, FPSR_IOC, 4+4);
VMOVQSfrom(d0, 0, x4);

View File

@ -143,9 +143,9 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
if(!BOX64ENV(dynarec_fastround) && arm64_frintts) {
v0 = fpu_get_scratch(dyn, ninst);
if(rex.w) {
FRINT64ZS(v0, q0);
FRINT64ZS(v0, d0);
} else {
FRINT32ZS(v0, q0);
FRINT32ZS(v0, d0);
}
FCVTZSxwS(gd, v0);
} else {