diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index c46794621..499751af5 100644 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -205,17 +205,25 @@ int convert_bitmask(uint64_t bitmask); #define SUBx_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(1, 1, 0, 0b00, Rm, 0, Rn, Rd)) #define SUBSx_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(1, 1, 1, 0b00, Rm, 0, Rn, Rd)) +#define SUBSx_REG_ASR(Rd, Rn, Rm, asr) FEMIT(ADDSUB_REG_gen(1, 1, 1, 0b10, Rm, asr, Rn, Rd)) #define SUBx_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(1, 1, 0, 0b00, Rm, lsl, Rn, Rd)) #define SUBw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(0, 1, 0, 0b00, Rm, 0, Rn, Rd)) #define SUBw_REG_LSL(Rd, Rn, Rm, lsl) EMIT(ADDSUB_REG_gen(0, 1, 0, 0b00, Rm, lsl, Rn, Rd)) #define SUBSw_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(0, 1, 1, 0b00, Rm, 0, Rn, Rd)) #define SUBSw_REG_LSL(Rd, Rn, Rm, lsl) FEMIT(ADDSUB_REG_gen(0, 1, 1, 0b00, Rm, lsl, Rn, Rd)) +#define SUBSw_REG_LSR(Rd, Rn, Rm, lsr) FEMIT(ADDSUB_REG_gen(0, 1, 1, 0b01, Rm, lsr, Rn, Rd)) +#define SUBSw_REG_ASR(Rd, Rn, Rm, asr) FEMIT(ADDSUB_REG_gen(0, 1, 1, 0b10, Rm, asr, Rn, Rd)) #define SUBxw_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(rex.w, 1, 0, 0b00, Rm, 0, Rn, Rd)) #define SUBz_REG(Rd, Rn, Rm) EMIT(ADDSUB_REG_gen(rex.is32bits?0:1, 1, 0, 0b00, Rm, 0, Rn, Rd)) #define SUBSxw_REG(Rd, Rn, Rm) FEMIT(ADDSUB_REG_gen(rex.w, 1, 1, 0b00, Rm, 0, Rn, Rd)) +#define SUBSxw_REG_ASR(Rd, Rn, Rm, asr) FEMIT(ADDSUB_REG_gen(rex.w, 1, 1, 0b10, Rm, asr, Rn, Rd)) #define CMPSx_REG(Rn, Rm) SUBSx_REG(xZR, Rn, Rm) +#define CMPSx_REG_ASR(Rn, Rm, asr) SUBSx_REG_ASR(xZR, Rn, Rm, asr) #define CMPSw_REG(Rn, Rm) SUBSw_REG(wZR, Rn, Rm) +#define CMPSw_REG_LSR(Rn, Rm, lsr) SUBSw_REG_LSR(wZR, Rn, Rm, lsr) +#define CMPSw_REG_ASR(Rn, Rm, asr) SUBSw_REG_ASR(wZR, Rn, Rm, asr) #define CMPSxw_REG(Rn, Rm) SUBSxw_REG(xZR, Rn, Rm) +#define CMPSxw_REG_ASR(Rn, Rm, asr) SUBSxw_REG_ASR(xZR, Rn, Rm, asr) #define NEGx_REG(Rd, Rm) SUBx_REG(Rd, xZR, Rm); #define NEGw_REG(Rd, Rm) SUBw_REG(Rd, wZR, Rm); #define NEGxw_REG(Rd, Rm) SUBxw_REG(Rd, xZR, Rm); diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 4abbaeaf9..cafd56329 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -836,8 +836,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BICw(xFlags, xFlags, x1); } IFX(X_CF | X_OF) { - ASRx(x4, gd, 63); - CMPSx_REG(x3, x4); + CMPSx_REG_ASR(x3, gd, 63); CSETw(x1, cNE); IFX(X_CF) { BFIw(xFlags, x1, F_CF, 1); @@ -861,8 +860,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BICw(xFlags, xFlags, x1); } IFX(X_CF | X_OF) { - ASRw(x4, gd, 31); - CMPSw_REG(x3, x4); + CMPSw_REG_ASR(x3, gd, 31); CSETw(x1, cNE); IFX(X_CF) { BFIw(xFlags, x1, F_CF, 1); @@ -902,8 +900,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BICw(xFlags, xFlags, x1); } IFX(X_CF | X_OF) { - ASRx(x4, gd, 63); - CMPSx_REG(x3, x4); + CMPSx_REG_ASR(x3, gd, 63); CSETw(x1, cNE); IFX(X_CF) { BFIw(xFlags, x1, F_CF, 1); @@ -927,8 +924,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BICw(xFlags, xFlags, x1); } IFX(X_CF | X_OF) { - ASRw(x4, gd, 31); - CMPSw_REG(x3, x4); + CMPSw_REG_ASR(x3, gd, 31); CSETw(x1, cNE); IFX(X_CF) { BFIw(xFlags, x1, F_CF, 1); @@ -3294,23 +3290,58 @@ 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_PENDING); + SETFLAGS(X_ALL, SF_SET); GETEB(x1, 0); UXTBw(x2, xRAX); MULw(x1, x2, x1); - UFLAG_RES(x1); BFIx(xRAX, x1, 0, 16); - UFLAG_DF(x1, d_mul8); + UFLAG_IF { + SET_DFNONE(x4); + IFX(X_CF|X_OF) { + CMPSw_REG_LSR(xZR, x1, 8); + 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(box64_dynarec_test) { + // to avoid noise during test + MOV32w(x3, (1<