From 4abaa3d83504250cf30241a0ea5831d6ec904803 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 22 May 2024 11:08:24 +0200 Subject: [PATCH] [DYNAREC] Simplified emit_pf helper --- src/dynarec/dynarec_arm_emit_logic.c | 36 ++++++------ src/dynarec/dynarec_arm_emit_math.c | 66 +++++++++++----------- src/dynarec/dynarec_arm_emit_shift.c | 42 +++++++------- src/dynarec/dynarec_arm_emit_tests.c | 84 ++++++---------------------- src/dynarec/dynarec_arm_helper.c | 15 +++-- src/dynarec/dynarec_arm_helper.h | 2 +- src/emu/x86emu.c | 5 -- src/include/x86emu.h | 1 - 8 files changed, 96 insertions(+), 155 deletions(-) diff --git a/src/dynarec/dynarec_arm_emit_logic.c b/src/dynarec/dynarec_arm_emit_logic.c index 569c164465..a67dd175f9 100755 --- a/src/dynarec/dynarec_arm_emit_logic.c +++ b/src/dynarec/dynarec_arm_emit_logic.c @@ -53,7 +53,7 @@ void emit_or32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -96,7 +96,7 @@ void emit_or32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4 BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -130,7 +130,7 @@ void emit_xor32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -173,7 +173,7 @@ void emit_xor32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -207,7 +207,7 @@ void emit_and32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -258,7 +258,7 @@ void emit_and32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -292,7 +292,7 @@ void emit_or8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -326,7 +326,7 @@ void emit_or8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -360,7 +360,7 @@ void emit_xor8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -394,7 +394,7 @@ void emit_xor8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4 BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -428,7 +428,7 @@ void emit_and8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -462,7 +462,7 @@ void emit_and8c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4 BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -497,7 +497,7 @@ void emit_or16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -540,7 +540,7 @@ void emit_or16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s4 BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -574,7 +574,7 @@ void emit_xor16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -617,7 +617,7 @@ void emit_xor16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -651,7 +651,7 @@ void emit_and16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -694,6 +694,6 @@ void emit_and16c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } \ No newline at end of file diff --git a/src/dynarec/dynarec_arm_emit_math.c b/src/dynarec/dynarec_arm_emit_math.c index dca173e889..428875cf7d 100755 --- a/src/dynarec/dynarec_arm_emit_math.c +++ b/src/dynarec/dynarec_arm_emit_math.c @@ -69,7 +69,7 @@ void emit_add32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -151,7 +151,7 @@ void emit_add32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -203,7 +203,7 @@ void emit_sub32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -288,7 +288,7 @@ void emit_sub32c(dynarec_arm_t* dyn, int ninst, int s1, int32_t c, int s3, int s BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -338,7 +338,7 @@ void emit_add8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, in BFI(xFlags, s3, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } IFX(X_AF|X_OF|X_PF){if(save_s4) {POP(xSP, 1<x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0) - IFX(X_CF|X_AF) { - SUB_REG_LSL_IMM5(s3, s1, s2, 0); - } - AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied - MOV32(s4, GetParityTab()); - LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer - SUB_REG_LSL_IMM5(s3, s1, s2, 0); - AND_IMM8(s3, s3, 31); - MVN_REG_LSR_REG(s4, s4, s3); - BFI(xFlags, s4, F_PF, 1); - } } // emit CMP32 instruction, from cmp s1 , 0, using s3 and s4 as scratch @@ -112,7 +102,7 @@ void emit_cmp32_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) BFI(xFlags, s4, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -140,6 +130,9 @@ void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) MOV_REG_LSR_IMM5(s4, s3, 15); BFI(xFlags, s4, F_SF, 1); } + IFX(X_PF) { + emit_pf(dyn, ninst, s3, s4); + } // bc = (res & (~d | s)) | (~d & s) IFX(X_CF|X_AF|X_OF) { MVN_REG_LSL_IMM5(s4, s1, 0); // s4 = ~d @@ -161,18 +154,6 @@ void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s4, F_OF, 1); // OF: ((bc >> 14) ^ ((bc>>14)>>1)) & 1 } } - IFX(X_PF) { - IFX(X_CF|X_AF|X_OF) { - SUB_REG_LSL_IMM5(s3, s1, s2, 0); - } - AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied - MOV32(s4, GetParityTab()); - LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer - SUB_REG_LSL_IMM5(s3, s1, s2, 0); - AND_IMM8(s3, s3, 31); - MVN_REG_LSR_REG(s4, s4, s3); - BFI(xFlags, s4, F_PF, 1); - } } // emit CMP16 instruction, from cmp s1 , #0, using s3 and s4 as scratch @@ -204,7 +185,7 @@ void emit_cmp16_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) BFI(xFlags, s4, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } // emit CMP8 instruction, from cmp s1 , s2, using s3 and s4 as scratch @@ -230,6 +211,9 @@ void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) MOV_REG_LSR_IMM5(s4, s3, 7); BFI(xFlags, s4, F_SF, 1); } + IFX(X_PF) { + emit_pf(dyn, ninst, s3, s4); + } // bc = (res & (~d | s)) | (~d & s) IFX(X_CF|X_AF|X_OF) { MVN_REG_LSL_IMM5(s4, s1, 0); // s4 = ~d @@ -251,18 +235,6 @@ void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) BFI(xFlags, s4, F_OF, 1); // OF: ((bc >> 6) ^ ((bc>>6)>>1)) & 1 } } - IFX(X_PF) { - IFX(X_CF|X_AF|X_OF) { - SUB_REG_LSL_IMM5(s3, s1, s2, 0); - } - AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied - MOV32(s4, GetParityTab()); - LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer - SUB_REG_LSL_IMM5(s3, s1, s2, 0); - AND_IMM8(s3, s3, 31); - MVN_REG_LSR_REG(s4, s4, s3); - BFI(xFlags, s4, F_PF, 1); - } } // emit CMP8 instruction, from cmp s1 , 0, using s3 and s4 as scratch void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) @@ -292,7 +264,7 @@ void emit_cmp8_0(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) BFI(xFlags, s4, F_SF, 1); } IFX(X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, s1, s4); } } @@ -321,19 +293,8 @@ void emit_test32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) MOV_REG_LSR_IMM5(s4, s3, 31); BFI(xFlags, s4, F_SF, 1); } - // PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0) IFX(X_PF) { - AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied - MOV32(s4, GetParityTab()); - LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer - if(s1==s2) { - AND_IMM8(s3, s1, 31); - } else { - AND_REG_LSL_IMM5(s3, s1, s2, 0); - AND_IMM8(s3, s3, 31); - } - MVN_REG_LSR_REG(s4, s4, s3); - BFI(xFlags, s4, F_PF, 1); + emit_pf(dyn, ninst, s1, s4); } } @@ -362,15 +323,8 @@ void emit_test16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) MOV_REG_LSR_IMM5(s4, s3, 15); BFI(xFlags, s4, F_SF, 1); } - // PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0) IFX(X_PF) { - AND_IMM8(s3, s3, 0xE0); // lsr 5 masking pre-applied - MOV32(s4, GetParityTab()); - LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer - AND_REG_LSL_IMM5(s3, s1, s2, 0); - AND_IMM8(s3, s3, 31); - MVN_REG_LSR_REG(s4, s4, s3); - BFI(xFlags, s4, F_PF, 1); + emit_pf(dyn, ninst, s1, s4); } } @@ -399,13 +353,7 @@ void emit_test8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4) MOV_REG_LSR_IMM5(s4, s3, 7); BFI(xFlags, s4, F_SF, 1); } - // PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0) IFX(X_PF) { - AND_IMM8(s2, s3, 0xE0); // lsr 5 masking pre-applied - MOV32(s4, GetParityTab()); - LDR_REG_LSR_IMM5(s4, s4, s2, 5-2); // x/32 and then *4 because array is integer - AND_IMM8(s3, s3, 31); - MVN_REG_LSR_REG(s4, s4, s3); - BFI(xFlags, s4, F_PF, 1); + emit_pf(dyn, ninst, s1, s4); } } diff --git a/src/dynarec/dynarec_arm_helper.c b/src/dynarec/dynarec_arm_helper.c index fa73d6b636..fe3beb7b1f 100755 --- a/src/dynarec/dynarec_arm_helper.c +++ b/src/dynarec/dynarec_arm_helper.c @@ -2118,14 +2118,13 @@ void fpu_putback_single_reg(dynarec_arm_t* dyn, int ninst, int reg, int idx, int } } -void emit_pf(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4) -{ - // PF: (((emu->x86emu_parity_tab[(res) / 32] >> ((res) % 32)) & 1) == 0) - AND_IMM8(s3, s1, 0xE0); // lsr 5 masking pre-applied - MOV32(s4, GetParityTab()); - LDR_REG_LSR_IMM5(s4, s4, s3, 5-2); // x/32 and then *4 because array is integer - AND_IMM8(s3, s1, 31); - MVN_REG_LSR_REG(s4, s4, s3); +void emit_pf(dynarec_arm_t* dyn, int ninst, int s1, int s4) +{ + // by xor'ing all the bit 2 by two with a shift, pair of bits are removed, and only 1 is left if bit number if odd + XOR_REG_LSR_IMM8(s4, s1, s1, 4); + XOR_REG_LSR_IMM8(s4, s4, s4, 2); + XOR_REG_LSR_IMM8(s4, s4, s4, 1); + MVN_REG_LSL_IMM5(s4, s4, 0); BFI(xFlags, s4, F_PF, 1); } diff --git a/src/dynarec/dynarec_arm_helper.h b/src/dynarec/dynarec_arm_helper.h index 586a1f2a42..4d07a292fe 100755 --- a/src/dynarec/dynarec_arm_helper.h +++ b/src/dynarec/dynarec_arm_helper.h @@ -745,7 +745,7 @@ void emit_shld32c(dynarec_arm_t* dyn, int ninst, int s1, int s2, int32_t c, int void emit_shrd32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4); void emit_shld32(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4); -void emit_pf(dynarec_arm_t* dyn, int ninst, int s1, int s3, int s4); +void emit_pf(dynarec_arm_t* dyn, int ninst, int s1, int s4); // x87 helper // cache of the local stack counter, to avoid upadte at every call diff --git a/src/emu/x86emu.c b/src/emu/x86emu.c index 9c85347a20..42ac542009 100755 --- a/src/emu/x86emu.c +++ b/src/emu/x86emu.c @@ -49,11 +49,6 @@ static uint32_t x86emu_parity_tab[8] = 0x69969669, }; -uint32_t* GetParityTab() -{ - return x86emu_parity_tab; -} - static void internalX86Setup(x86emu_t* emu, box86context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack) { emu->context = context; diff --git a/src/include/x86emu.h b/src/include/x86emu.h index 7a02cd7a69..2747cc1058 100755 --- a/src/include/x86emu.h +++ b/src/include/x86emu.h @@ -14,7 +14,6 @@ void CopyEmu(x86emu_t *newemu, const x86emu_t* emu); void SetTraceEmu(uintptr_t trace_start, uintptr_t trace_end); box86context_t* GetEmuContext(x86emu_t* emu); -uint32_t* GetParityTab(); uint32_t GetEAX(x86emu_t *emu); uint64_t GetEDXEAX(x86emu_t *emu);