diff options
Diffstat (limited to 'src/dynarec/arm64/dynarec_arm64_helper.h')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 267d873b..77cedbf1 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -880,7 +880,7 @@ #endif // Generate FCOM with s1 and s2 scratch regs (the VCMP is already done) -#define FCOM(s1, s2, s3) \ +#define FCOM(s1, s2, s3, s4, v1, v2, is_f) \ LDRH_U12(s3, xEmu, offsetof(x64emu_t, sw)); /*offset is 8bits right?*/\ MOV32w(s1, 0b0100011100000000); \ BICw_REG(s3, s3, s1); \ @@ -890,11 +890,33 @@ CSELw(s1, s2, s1, cEQ); \ MOV32w(s2, 0b01000101); /* unordered */ \ CSELw(s1, s2, s1, cVS); \ + if(v1||v2) { \ + Bcond(cVS, 10*4); \ + if(is_f) { \ + ORRw_mask(s4, xZR, 12, 10); /*+inf*/ \ + FMOVwS(s2, v1); \ + CMPSw_REG(s2, s4); \ + Bcond(cEQ, 5*4); /* same */ \ + FMOVwS(s2, v2); \ + ORRw_mask(s4, s4, 1, 0); /*-inf*/ \ + CMPSw_REG(s2, s4); \ + } else { \ + ORRx_mask(s4, xZR, 1, 12, 10); /*+inf*/ \ + FMOVxD(s2, v1); \ + CMPSx_REG(s2, s4); \ + Bcond(cEQ, 5*4); /* same */ \ + FMOVxD(s2, v2); \ + ORRx_mask(s4, s4, 1, 1, 0); /*-inf*/ \ + CMPSx_REG(s2, s4); \ + } \ + Bcond(cNE, 4+4); /* same */ \ + MOVZw(s2, 0); \ + } \ ORRw_REG_LSL(s3, s3, s1, 8); \ STRH_U12(s3, xEmu, offsetof(x64emu_t, sw)) // Generate FCOMI with s1 and s2 scratch regs (the VCMP is already done) -#define FCOMI(s1, s2) \ +#define FCOMI(s1, s2, s4, v1, v2, is_f) \ IFX(X_OF|X_AF|X_SF|X_PEND) { \ MOV32w(s2, 0b100011010101); \ BICw_REG(xFlags, xFlags, s2); \ @@ -914,6 +936,28 @@ MOV32w(s2, 0b01000000); /* zero */ \ CSELw(s1, s2, s1, cEQ); \ /* greater than leave 0 */ \ + if(s4) { \ + Bcond(cVS, 10*4); \ + if(is_f) { \ + ORRw_mask(s4, xZR, 12, 10); /*+inf*/ \ + FMOVwS(s2, v1); \ + CMPSw_REG(s2, s4); \ + Bcond(cEQ, 5*4); /* same */ \ + FMOVwS(s2, v2); \ + ORRw_mask(s4, s4, 1, 0); /*-inf*/ \ + CMPSw_REG(s2, s4); \ + } else { \ + ORRx_mask(s4, xZR, 1, 12, 10); /*+inf*/ \ + FMOVxD(s2, v1); \ + CMPSx_REG(s2, s4); \ + Bcond(cEQ, 5*4); /* same */ \ + FMOVxD(s2, v2); \ + ORRx_mask(s4, s4, 1, 1, 0); /*-inf*/ \ + CMPSx_REG(s2, s4); \ + } \ + Bcond(cNE, 4+4); /* same */ \ + MOVZw(s1, 0); \ + } \ ORRw_REG(xFlags, xFlags, s1); \ } \ SET_DFNONE(s1); \ |