diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 8bef8bc86..30fd5f6be 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -3521,7 +3521,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 4: INST_NAME("MUL AL, Eb"); - SETFLAGS(X_ALL, SF_SET); + if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) { + SETFLAGS(X_OF|X_CF, SF_SET); + } else { + SETFLAGS(X_ALL, SF_SET); + } GETEB(x1, 0); UXTBw(x2, xRAX); MULw(x1, x2, x1); @@ -3537,16 +3541,17 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFIw(xFlags, x3, F_OF, 1); } } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x3, (1<1 && BOX64ENV(cputype)) { + if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) { SETFLAGS(X_OF|X_CF, SF_SET); } else { SETFLAGS(X_ALL, SF_SET); @@ -3570,7 +3575,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin IFX2(X_AF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_AF, 1);} IFX2(X_ZF, && !BOX64ENV(cputype)) {BFCw(xFlags, F_ZF, 1);} IFX2(X_SF, && !BOX64ENV(cputype)) { - LSRxw(x3, xRAX, 15); + LSRxw(x3, xRAX, 7); BFIw(xFlags, x3, F_SF, 1); } IFX2(X_PF, && !BOX64ENV(cputype)) emit_pf(dyn, ninst, xRAX, x3); @@ -3595,16 +3600,24 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFIx(xRAX, x3, 0, 8); BFIx(xRAX, x4, 8, 8); SET_DFNONE(); - IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) - if (BOX64ENV(dynarec_test)) { - MOV32w(x1, (1<1 && BOX64ENV(cputype)) { + if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) { SETFLAGS(X_OF|X_CF, SF_SET); } else { SETFLAGS(X_ALL, SF_SET); @@ -3804,16 +3821,24 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } } SET_DFNONE(); - IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) - if (BOX64ENV(dynarec_test)) { - MOV32w(x1, (1<1 && BOX64ENV(cputype)) { + if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) { SETFLAGS(X_OF|X_CF, SF_SET); } else { SETFLAGS(X_ALL, SF_SET); diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c index ee1d22f14..6c50e374a 100644 --- a/src/dynarec/arm64/dynarec_arm64_64.c +++ b/src/dynarec/arm64/dynarec_arm64_64.c @@ -1334,7 +1334,11 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 4: INST_NAME("MUL EAX, Ed"); - SETFLAGS(X_ALL, SF_SET); + if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) { + SETFLAGS(X_OF|X_CF, SF_SET); + } else { + SETFLAGS(X_ALL, SF_SET); + } GETEDO(x6, 0); if(rex.w) { if(ed==xRDX) gd=x3; else gd=xRDX; @@ -1346,29 +1350,28 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MOVw_REG(xRAX, xRDX); LSRx(xRDX, xRDX, 32); } - UFLAG_IF { - SET_DFNONE(); - IFX(X_CF|X_OF) { - CMPSxw_U12(xRDX, 0); - CSETw(x3, cNE); - IFX(X_CF) { - BFIw(xFlags, x3, F_CF, 1); - } - IFX(X_OF) { - BFIw(xFlags, x3, F_OF, 1); - } + SET_DFNONE(); + IFX(X_CF|X_OF) { + CMPSxw_U12(xRDX, 0); + CSETw(x3, cNE); + IFX(X_CF) { + BFIw(xFlags, x3, F_CF, 1); + } + IFX(X_OF) { + BFIw(xFlags, x3, F_OF, 1); } - IFX(X_AF | X_PF | X_ZF | X_SF) - if (BOX64ENV(dynarec_test)) { - // to avoid noise during test - MOV32w(x3, (1<1 && BOX64ENV(cputype)) { + if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) { SETFLAGS(X_OF|X_CF, SF_SET); } else { SETFLAGS(X_ALL, SF_SET); @@ -1471,16 +1474,24 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } } SET_DFNONE(); - IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) - if (BOX64ENV(dynarec_test)) { - MOV32w(x1, (1<1 && BOX64ENV(cputype)) { + if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) { SETFLAGS(X_OF|X_CF, SF_SET); } else { SETFLAGS(X_ALL, SF_SET); @@ -1515,16 +1518,24 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFIz(xRAX, x3, 0, 16); BFIz(xRDX, x4, 0, 16); SET_DFNONE(); - IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) - if (BOX64ENV(dynarec_test)) { - MOV32w(x1, (1<1 && BOX64ENV(cputype)) { + if(BOX64ENV(dynarec_safeflags) && BOX64ENV(cputype)) { SETFLAGS(X_OF|X_CF, SF_SET); } else { SETFLAGS(X_ALL, SF_SET); @@ -1572,16 +1575,24 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } } SET_DFNONE(); - IFX(X_AF | X_SF | X_CF | X_PF | X_ZF | X_OF) - if (BOX64ENV(dynarec_test)) { - MOV32w(x1, (1<> 7)) & 0x1, F_OF); - - } + if(BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((cf ^ (res >> 7)) & 0x1, F_OF); + else + CONDITIONAL_SET_FLAG((XOR2(d >> 6)), F_OF); + } else if(s && BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 7)) & 0x1, F_OF); return (uint8_t)res; } @@ -547,7 +550,8 @@ uint16_t rcl16(x64emu_t *emu, uint16_t d, uint8_t s) CONDITIONAL_SET_FLAG((cf ^ (res >> 15)) & 0x1, F_OF); else CONDITIONAL_SET_FLAG((XOR2(d >> 14)), F_OF); - } + } else if(s && BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((ACCESS_FLAG(F_CF) ^ (res >> 15)) & 0x1, F_OF); return (uint16_t)res; } @@ -679,9 +683,9 @@ uint8_t rcr8(x64emu_t *emu, uint8_t d, uint8_t s) /* set the new carry flag, based on the variable "cf" */ CONDITIONAL_SET_FLAG(cf, F_CF); - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG((XOR2(res >> 6)), F_OF); } + if(s && BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((XOR2(res >> 6)), F_OF); return (uint8_t)res; } @@ -709,9 +713,9 @@ uint16_t rcr16(x64emu_t *emu, uint16_t d, uint8_t s) res |= 1 << (16 - cnt); } CONDITIONAL_SET_FLAG(cf, F_CF); - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG((XOR2(res >> 14)), F_OF); } + if(s && BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((XOR2(res >> 14)), F_OF); return (uint16_t)res; } @@ -741,9 +745,9 @@ uint32_t rcr32(x64emu_t *emu, uint32_t d, uint8_t s) res |= 1 << (32 - cnt); } CONDITIONAL_SET_FLAG(cf, F_CF); - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG((XOR2(res >> 30)), F_OF); } + if(s && BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((XOR2(res >> 30)), F_OF); return res; } @@ -773,9 +777,9 @@ uint64_t rcr64(x64emu_t *emu, uint64_t d, uint8_t s) res |= 1LL << (64 - cnt); } CONDITIONAL_SET_FLAG(cf, F_CF); - if(BOX64ENV(cputype)) - CONDITIONAL_SET_FLAG((XOR2(res >> 62)), F_OF); } + if(s && BOX64ENV(cputype)) + CONDITIONAL_SET_FLAG((XOR2(res >> 62)), F_OF); return res; } /****************************************************************************