diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-01-23 15:58:30 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-23 08:58:30 +0100 |
| commit | 276191cdcfb0338243b4368672c4eb9159b7a692 (patch) | |
| tree | bbe2d6df5e74726fec952e8a5db651d8f99f8a78 /src | |
| parent | 8438b6174759b6c21d2239939bba4f1b37c4fcd1 (diff) | |
| download | box64-276191cdcfb0338243b4368672c4eb9159b7a692.tar.gz box64-276191cdcfb0338243b4368672c4eb9159b7a692.zip | |
[LA64_DYNAREC] Added fastnan handling to more 0F opcodes (fixes CI) (#2285)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index 70b20bd7..a899a365 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -563,8 +563,22 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni INST_NAME("MULPS Gx, Ex"); nextop = F8; GETEX(q0, 0, 0); - GETGX(v0, 1); - VFMUL_S(v0, v0, q0); + GETGX(q1, 1); + if (!BOX64ENV(dynarec_fastnan)) { + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + VFCMP_S(v0, q0, q1, cUN); + } + VFMUL_S(q1, q1, q0); + if (!BOX64ENV(dynarec_fastnan)) { + VFCMP_S(v1, q1, q1, cUN); + VANDN_V(v0, v0, v1); + VLDI(v1, 0b011111111100); // broadcast 0xFFFFFFFFFFFFFFFC + VSLLI_W(v1, v1, 20); + VAND_V(v1, v0, v1); + VANDN_V(v0, v0, q1); + VOR_V(q1, v0, v1); + } break; case 0x5A: INST_NAME("CVTPS2PD Gx, Ex"); @@ -584,8 +598,22 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni INST_NAME("SUBPS Gx, Ex"); nextop = F8; GETEX(q0, 0, 0); - GETGX(v0, 1); - VFSUB_S(v0, v0, q0); + GETGX(q1, 1); + if (!BOX64ENV(dynarec_fastnan)) { + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + VFCMP_S(v0, q0, q1, cUN); + } + VFSUB_S(q1, q1, q0); + if (!BOX64ENV(dynarec_fastnan)) { + VFCMP_S(v1, q1, q1, cUN); + VANDN_V(v0, v0, v1); + VLDI(v1, 0b011111111100); // broadcast 0xFFFFFFFFFFFFFFFC + VSLLI_W(v1, v1, 20); + VAND_V(v1, v0, v1); + VANDN_V(v0, v0, q1); + VOR_V(q1, v0, v1); + } break; case 0x5D: INST_NAME("MINPS Gx, Ex"); @@ -606,8 +634,22 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni INST_NAME("DIVPS Gx, Ex"); nextop = F8; GETEX(q0, 0, 0); - GETGX(v0, 1); - VFDIV_S(v0, v0, q0); + GETGX(q1, 1); + if (!BOX64ENV(dynarec_fastnan)) { + v0 = fpu_get_scratch(dyn); + v1 = fpu_get_scratch(dyn); + VFCMP_S(v0, q0, q1, cUN); + } + VFDIV_S(q1, q1, q0); + if (!BOX64ENV(dynarec_fastnan)) { + VFCMP_S(v1, q1, q1, cUN); + VANDN_V(v0, v0, v1); + VLDI(v1, 0b011111111100); // broadcast 0xFFFFFFFFFFFFFFFC + VSLLI_W(v1, v1, 20); + VAND_V(v1, v0, v1); + VANDN_V(v0, v0, q1); + VOR_V(q1, v0, v1); + } break; case 0x5F: INST_NAME("MAXPS Gx, Ex"); |