diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-12-02 15:16:51 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-12-02 15:16:51 +0100 |
| commit | 76eb623de6d6db256c38aab066560991c45bdfcf (patch) | |
| tree | c17133bb23efce5546e28a9e80aa20d93c7cee63 | |
| parent | 9e45c053838ae15a9fadb6ed413867465cb54ef8 (diff) | |
| download | box64-76eb623de6d6db256c38aab066560991c45bdfcf.tar.gz box64-76eb623de6d6db256c38aab066560991c45bdfcf.zip | |
[ARM64_DYNAREC] Generalized the use of Flag Manipulation Extension (if present)
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_logic.c | 60 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_math.c | 175 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_shift.c | 176 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_emit_tests.c | 50 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 26 |
5 files changed, 84 insertions, 403 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_logic.c b/src/dynarec/arm64/dynarec_arm64_emit_logic.c index e8af51f5..fb3f4545 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_logic.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_logic.c @@ -230,15 +230,7 @@ void emit_or8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF)); BICw(xFlags, xFlags, s3); } - IFX(X_ZF) { - TSTw_REG(s1, s1); - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -261,15 +253,7 @@ void emit_or8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4) MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF)); BICw(xFlags, xFlags, s3); } - IFX(X_ZF) { - TSTw_REG(s1, s1); - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -292,15 +276,7 @@ void emit_xor8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF)); BICw(xFlags, xFlags, s3); } - IFX(X_ZF) { - TSTw_REG(s1, s1); - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -323,15 +299,7 @@ void emit_xor8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4 MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF)); BICw(xFlags, xFlags, s3); } - IFX(X_ZF) { - TSTw_REG(s1, s1); - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -423,15 +391,7 @@ void emit_or16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF)); BICw(xFlags, xFlags, s3); } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 15); //mask=0xffff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 15); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -500,15 +460,7 @@ void emit_xor16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF)); BICw(xFlags, xFlags, s3); } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 15); //mask=0xffff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 15); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } diff --git a/src/dynarec/arm64/dynarec_arm64_emit_math.c b/src/dynarec/arm64/dynarec_arm64_emit_math.c index b8215ef2..1248ef63 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_math.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_math.c @@ -278,38 +278,22 @@ void emit_add8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) } else IFX(X_ALL) { SET_DFNONE(s3); } - if(arm64_flagm && 0) { - IFX(X_AF) { - ORRw_REG(s3, s1, s2); // s3 = op1 | op2 - ANDw_REG(s4, s1, s2); // s4 = op1 & op2 - } - } else { - IFX(X_AF | X_OF) { - ORRw_REG(s3, s1, s2); // s3 = op1 | op2 - ANDw_REG(s4, s1, s2); // s4 = op1 & op2 - } + IFX(X_AF | X_OF) { + ORRw_REG(s3, s1, s2); // s3 = op1 | op2 + ANDw_REG(s4, s1, s2); // s4 = op1 & op2 } ADDw_REG(s1, s1, s2); - if(arm64_flagm && 0) { // disable O flag there, it needs singned 8bits values + IFX(X_AF|X_OF) { + BICw_REG(s3, s3, s1); // s3 = (op1 | op2) & ~ res + ORRw_REG(s3, s3, s4); // s3 = (op1 & op2) | ((op1 | op2) & ~ res) IFX(X_AF) { - BICw_REG(s3, s3, s1); // s3 = (op1 | op2) & ~ res - ORRw_REG(s3, s3, s4); // s3 = (op1 & op2) | ((op1 | op2) & ~ res) LSRw(s4, s3, 3); BFIw(xFlags, s4, F_AF, 1); // AF: bc & 0x08 } - } else { - IFX(X_AF|X_OF) { - BICw_REG(s3, s3, s1); // s3 = (op1 | op2) & ~ res - ORRw_REG(s3, s3, s4); // s3 = (op1 & op2) | ((op1 | op2) & ~ res) - IFX(X_AF) { - LSRw(s4, s3, 3); - BFIw(xFlags, s4, F_AF, 1); // AF: bc & 0x08 - } - IFX(X_OF) { - LSRw(s4, s3, 6); - EORw_REG_LSR(s4, s4, s4, 1); - BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1 - } + IFX(X_OF) { + LSRw(s4, s3, 6); + EORw_REG_LSR(s4, s4, s4, 1); + BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1 } } IFX(X_CF) { @@ -319,33 +303,7 @@ void emit_add8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - if(arm64_flagm) { - IFX(X_ZF|X_SF/*|X_OF*/) { - SETF8(s1); - } - IFX(X_ZF) { - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - CSETw(s3, cMI); - BFIw(xFlags, s3, F_SF, 1); - } - /*IFX(X_OF) { - CSETw(s3, cVS); - BFIw(xFlags, s3, F_OF, 1); - }*/ - } else { - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 7); //mask=0xff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -389,15 +347,7 @@ void emit_add8c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4) IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 0b000111); //mask=000000ff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -441,15 +391,7 @@ void emit_sub8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1 } } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 7); //mask=0xff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -499,15 +441,7 @@ void emit_sub8c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4, in BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1 } } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 0b000111); //mask=000000ff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -550,15 +484,7 @@ void emit_add16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_PEND) { STRw_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 15); //mask=0xffff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 15); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -668,15 +594,7 @@ void emit_sub16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1 } } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 15); //mask=0xffff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 15); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -826,16 +744,7 @@ void emit_inc8(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1 } } - - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 7); //mask=0xff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -872,15 +781,7 @@ void emit_inc16(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1 } } - IFX(X_ZF) { - TSTw_mask(s1, 0, 0b001111); // mask=0xffff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 15); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -1196,15 +1097,7 @@ void emit_adc8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) LSRw(s3, s1, 8); BFIw(xFlags, s3, F_CF, 1); } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 7); //mask=0xff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -1258,15 +1151,7 @@ void emit_adc16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) LSRw(s3, s1, 16); BFIw(xFlags, s3, F_CF, 1); } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 15); //mask=0xffff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 15); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -1508,15 +1393,7 @@ void emit_sbb8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1 } } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 7); //mask=0xff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -1571,15 +1448,7 @@ void emit_sbb16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFIw(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1 } } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 15); //mask=0xffff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 15); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c index cc583c45..778583b4 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c @@ -286,19 +286,11 @@ void emit_shl8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_PEND) { STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 7); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 7); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_OF) { CMPSw_U12(s2, 1); // if s2==1 - IFX(X_SF) {} else {LSRw(s4, s1, 7);} - EORw_REG(s4, s4, xFlags); // CF is set if OF is asked + IFX(X_SF && !arm64_flagm) {} else {LSRw(s3, s1, 7);} + EORw_REG(s4, s3, xFlags); // CF is set if OF is asked CSELw(s4, s4, wZR, cEQ); BFIw(xFlags, s4, F_OF, 1); } @@ -329,19 +321,11 @@ void emit_shl8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s IFX(X_PEND) { STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 7); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 7); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_OF) { if(c==1) { - IFX(X_SF) {} else {LSRw(s4, s1, 7);} - EORw_REG(s4, s4, xFlags); // CF is set if OF is asked + IFX(X_SF && !arm64_flagm) {} else {LSRw(s3, s1, 7);} + EORw_REG(s4, s3, xFlags); // CF is set if OF is asked BFIw(xFlags, s4, F_OF, 1); } else { BFCw(xFlags, F_OF, 1); @@ -403,15 +387,7 @@ void emit_shr8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_PEND) { STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 7); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 7); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -448,15 +424,7 @@ void emit_shr8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s IFX(X_PEND) { STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 7); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 7); - BFIx(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -481,15 +449,7 @@ void emit_sar8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_PEND) { STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 7); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 7); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_OF) { CMPSw_U12(s2, 1); Bcond(cNE, 4+4); @@ -521,15 +481,7 @@ void emit_sar8c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int s IFX(X_PEND) { STRB_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 7); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 7); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_OF) if(c==1) { BFCw(xFlags, F_OF, 1); @@ -559,19 +511,11 @@ void emit_shl16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_OF) { CMPSw_U12(s2, 1); // if s2==1 - IFX(X_SF) {} else {LSRw(s4, s1, 15);} - EORw_REG(s4, s4, xFlags); // CF is set if OF is asked + IFX(X_SF && !arm64_flagm) {} else {LSRw(s3, s1, 15);} + EORw_REG(s4, s3, xFlags); // CF is set if OF is asked CSELw(s4, s4, wZR, cEQ); BFIw(xFlags, s4, F_OF, 1); } @@ -603,19 +547,11 @@ void emit_shl16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_OF) { if(c==1) { - IFX(X_SF) {} else {LSRw(s4, s1, 15);} - EORw_REG(s4, s4, xFlags); // CF is set if OF is asked + IFX(X_SF && !arm64_flagm) {} else {LSRw(s3, s1, 15);} + EORw_REG(s4, s3, xFlags); // CF is set if OF is asked BFIw(xFlags, s4, F_OF, 1); } else { BFCw(xFlags, F_OF, 1); @@ -673,15 +609,7 @@ void emit_shr16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -718,15 +646,7 @@ void emit_shr16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIx(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -751,15 +671,7 @@ void emit_sar16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_OF) { CMPSw_U12(s2, 1); Bcond(cNE, 4+4); @@ -791,15 +703,7 @@ void emit_sar16c(dynarec_arm_t* dyn, int ninst, int s1, uint32_t c, int s3, int IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_OF) if(c==1) { BFCw(xFlags, F_OF, 1); @@ -1233,15 +1137,7 @@ void emit_shrd16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); // 0xffff - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_OF) { if(c==1) { LSRw(s4, s1, 15); @@ -1279,15 +1175,7 @@ void emit_shrd16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3, IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); // 0xffff - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_OF) { CMPSw_U12(s5, 1); Bcond(cNE, 4+3*4); @@ -1334,15 +1222,7 @@ void emit_shld16c(dynarec_arm_t* dyn, int ninst, int s1, int s2, uint32_t c, int IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); // 0xffff - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_OF) { if(c==1) { LSRw(s3, s1, 15); @@ -1384,15 +1264,7 @@ void emit_shld16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s5, int s3, IFX(X_PEND) { STRH_U12(s1, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - TSTw_mask(s1, 0, 15); // 0xffff - CSETw(s4, cEQ); - BFIw(xFlags, s4, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_OF) { CMPSw_U12(s5, 1); Bcond(cNE, 4+3*4); diff --git a/src/dynarec/arm64/dynarec_arm64_emit_tests.c b/src/dynarec/arm64/dynarec_arm64_emit_tests.c index bf190586..5c6c602f 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_tests.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_tests.c @@ -111,22 +111,11 @@ void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, i } else { SET_DFNONE(s3); } - IFX(X_ZF) { - SUBSw_REG(s5, s1, s2); // res = s1 - s2 - } else { - SUBw_REG(s5, s1, s2); // res = s1 - s2 - } + SUBw_REG(s5, s1, s2); // res = s1 - s2 IFX_PENDOR0 { STRH_U12(s5, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s5, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s5, 16) // bc = (res & (~d | s)) | (~d & s) IFX(X_CF|X_AF|X_OF) { MVNw_REG(s4, s1); // s4 = ~d @@ -170,15 +159,7 @@ void emit_cmp16_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF)); BICw(xFlags, xFlags, s3); } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 15); //mask=0xffff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s4, s1, 15); - BFIw(xFlags, s4, F_SF, 1); - } + COMP_ZFSF(s1, 16) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -194,22 +175,11 @@ void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, in } else { SET_DFNONE(s4); } - IFX(X_ZF) { - SUBSw_REG(s5, s1, s2); // res = s1 - s2 - } else { - SUBw_REG(s5, s1, s2); // res = s1 - s2 - } + SUBw_REG(s5, s1, s2); // res = s1 - s2 IFX_PENDOR0 { STRB_U12(s5, xEmu, offsetof(x64emu_t, res)); } - IFX(X_ZF) { - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s5, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s5, 8) // bc = (res & (~d | s)) | (~d & s) IFX(X_CF|X_AF|X_OF) { ORNw_REG(s4, s2, s1); // s4 = ~d | s @@ -251,15 +221,7 @@ void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) MOV32w(s3, (1<<F_CF)|(1<<F_AF)|(1<<F_OF)); BICw(xFlags, xFlags, s3); } - IFX(X_ZF) { - ANDSw_mask(s1, s1, 0, 0b000111); //mask=000000ff - CSETw(s3, cEQ); - BFIw(xFlags, s3, F_ZF, 1); - } - IFX(X_SF) { - LSRw(s3, s1, 7); - BFIw(xFlags, s3, F_SF, 1); - } + COMP_ZFSF(s1, 8) IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index c8320b57..b511457d 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -1465,4 +1465,30 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n opcode = F8; \ } +#define COMP_ZFSF(s1, A) \ + IFX(X_ZF|X_SF) { \ + if(arm64_flagm) { \ + SETF##A(s1); \ + IFX(X_ZF) { \ + CSETw(s3, cEQ); \ + BFIw(xFlags, s3, F_ZF, 1); \ + } \ + IFX(X_SF) { \ + CSETw(s3, cMI); \ + BFIw(xFlags, s3, F_SF, 1); \ + } \ + } else { \ + IFX(X_ZF) { \ + ANDSw_mask(s1, s1, 0, (A)-1); \ + CSETw(s3, cEQ); \ + BFIw(xFlags, s3, F_ZF, 1); \ + } \ + IFX(X_SF) { \ + LSRw(s3, s1, (A)-1); \ + BFIw(xFlags, s3, F_SF, 1); \ + } \ + } \ + } + + #endif //__DYNAREC_ARM64_HELPER_H__ |