diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-03-02 17:31:47 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-03-02 17:31:47 +0100 |
| commit | b72d3a77e91b4a80576c97b3da5cae34ef072c2d (patch) | |
| tree | b4f548ace11fd7a48ff3e043c65fff54119ec154 /src | |
| parent | 64fdf541561d9c8858e2498ef18587c00964ee17 (diff) | |
| download | box64-b72d3a77e91b4a80576c97b3da5cae34ef072c2d.tar.gz box64-b72d3a77e91b4a80576c97b3da5cae34ef072c2d.zip | |
[ARM64_DYNAREC] More fixes and optim on IMUL flags
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 57 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 5 |
2 files changed, 49 insertions, 13 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 527c21ba..20c15e26 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -862,10 +862,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin // 32bits imul UFLAG_IF { SMULL(gd, ed, x4); - UFLAG_RES(gd); LSRx(x3, gd, 32); MOVw_REG(gd, gd); IFX(X_PEND) { + UFLAG_RES(gd); UFLAG_OP1(x3); UFLAG_DF(x1, d_imul32); } else { @@ -876,10 +876,9 @@ 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(x3, x3, 31); ASRw(x4, gd, 31); CMPSw_REG(x3, x4); - CSETw(x3, cNE); + CSETw(x1, cNE); IFX(X_CF) { BFIw(xFlags, x1, F_CF, 1); } @@ -902,7 +901,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x6B: INST_NAME("IMUL Gd, Ed, Ib"); - SETFLAGS(X_ALL, SF_PENDING); + SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; GETGD; GETED(1); @@ -913,9 +912,28 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin UFLAG_IF { SMULH(x3, ed, x4); MULx(gd, ed, x4); - UFLAG_OP1(x3); - UFLAG_RES(gd); - UFLAG_DF(x3, d_imul64); + IFX(X_PEND) { + UFLAG_OP1(x3); + UFLAG_RES(gd); + UFLAG_DF(x1, d_imul64); + } else { + SET_DFNONE(x1); + } + IFX(X_ZF | X_PF | X_AF | X_SF) { + MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); + BICw(xFlags, xFlags, x1); + } + IFX(X_CF | X_OF) { + ASRx(x4, gd, 63); + CMPSx_REG(x3, x4); + CSETw(x1, cNE); + IFX(X_CF) { + BFIw(xFlags, x1, F_CF, 1); + } + IFX(X_OF) { + BFIw(xFlags, x1, F_OF, 1); + } + } } else { MULxw(gd, ed, x4); } @@ -923,11 +941,30 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin // 32bits imul UFLAG_IF { SMULL(gd, ed, x4); - UFLAG_RES(gd); LSRx(x3, gd, 32); - UFLAG_OP1(x3); - UFLAG_DF(x3, d_imul32); MOVw_REG(gd, gd); + IFX(X_PEND) { + UFLAG_RES(gd); + UFLAG_OP1(x3); + UFLAG_DF(x1, d_imul32); + } else { + SET_DFNONE(x1); + } + IFX(X_ZF | X_PF | X_AF | X_SF) { + MOV32w(x1, (1<<F_ZF)|(1<<F_AF)|(1<<F_PF)|(1<<F_SF)); + BICw(xFlags, xFlags, x1); + } + IFX(X_CF | X_OF) { + ASRw(x4, gd, 31); + CMPSw_REG(x3, x4); + CSETw(x1, cNE); + IFX(X_CF) { + BFIw(xFlags, x1, F_CF, 1); + } + IFX(X_OF) { + BFIw(xFlags, x1, F_OF, 1); + } + } } else { MULxw(gd, ed, x4); } diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 0d857fba..9e4bd704 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -1847,16 +1847,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin // 32bits imul UFLAG_IF { SMULL(gd, gd, ed); + LSRx(x3, gd, 32); + MOVw_REG(gd, gd); IFX(X_PEND) { UFLAG_RES(gd); - LSRx(x3, gd, 32); UFLAG_OP1(x3); UFLAG_DF(x4, d_imul32); } else IFX(X_CF|X_OF) { SET_DFNONE(x4); } IFX(X_CF|X_OF) { - ASRx(x3, gd, 63); ASRw(x4, gd, 31); CMPSw_REG(x3, x4); CSETw(x3, cNE); @@ -1874,7 +1874,6 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin BFCw(xFlags, F_ZF, 1); BFCw(xFlags, F_SF, 1); } - MOVw_REG(gd, gd); } else { MULxw(gd, gd, ed); } |