mirror of
https://github.com/ptitSeb/box64.git
synced 2024-11-23 01:45:20 +08:00
[ARM64_DYNAREC] More optimizations on strongmem emulation (#2051)
This commit is contained in:
parent
5422b108af
commit
9757d1b67a
@ -169,15 +169,15 @@ Define Box64's Dynarec max allowed forward value when building Block.
|
||||
#### BOX64_DYNAREC_STRONGMEM *
|
||||
Enable/Disable simulation of Strong Memory model
|
||||
* 0 : Don't try anything special (Default.)
|
||||
* 1 : Enable some memory barriers when writting to memory to simulate the Strong Memory Model in a limited way (Default when libmonobdwgc-2.0.so is loaded)
|
||||
* 1 : Enable some memory barriers when writing to memory to simulate the Strong Memory Model in a limited way (Default when libmonobdwgc-2.0.so is loaded)
|
||||
* 2 : All 1. plus memory barriers on SIMD instructions
|
||||
* 3 : All 2. plus more memory barriers on a regular basis
|
||||
|
||||
#### BOX64_DYNAREC_WEAKBARRIER *
|
||||
Use weak memory barriers to reduce the performance impact by STRONGMEM
|
||||
Tweaking the memory barriers to reduce the performance impact by STRONGMEM
|
||||
* 0 : Use regular safe barrier (Default.)
|
||||
* 1 : Use weak barriers to have more performance boost
|
||||
* 2 : Disable the last write barriers to have even more performance boost
|
||||
* 2 : All 1. Plus disabled the last write barriers
|
||||
|
||||
#### BOX64_DYNAREC_X87DOUBLE *
|
||||
Force the use of Double for x87 emulation
|
||||
|
@ -296,17 +296,17 @@ Define Box64's Dynarec max allowed forward value when building Block.
|
||||
Enable/Disable simulation of Strong Memory model
|
||||
|
||||
* 0 : Don't try anything special (Default.)
|
||||
* 1 : Enable some memory barriers when writting to memory to simulate the Strong Memory Model in a limited way (Default when libmonobdwgc-2.0.so is loaded)
|
||||
* 1 : Enable some memory barriers when writing to memory to simulate the Strong Memory Model in a limited way (Default when libmonobdwgc-2.0.so is loaded)
|
||||
* 2 : All 1. plus memory barriers on SIMD instructions
|
||||
* 3 : All 2. plus more memory barriers on a regular basis
|
||||
|
||||
=item B<BOX64_DYNAREC_WEAKBARRIER>=I<0|1>
|
||||
|
||||
Use weak memory barriers to reduce the performance impact by STRONGMEM
|
||||
Tweaking the memory barriers to reduce the performance impact by STRONGMEM
|
||||
|
||||
* 0 : Use regular safe barrier (Default.)
|
||||
* 1 : Use weak barriers to have more performance boost
|
||||
* 2 : Disable the last write barriers to have even more performance boost
|
||||
* 2 : All 1. Plus disabled the last write barriers
|
||||
|
||||
=item B<BOX64_DYNAREC_X87DOUBLE>=I<0|1>
|
||||
|
||||
|
@ -53,10 +53,14 @@
|
||||
* - SIMD operations (c2)
|
||||
* 4. After every third guest memory store in a SEQ (d)
|
||||
*
|
||||
* STRONGMEM levels:
|
||||
* LEVEL1: Includes a1, b1
|
||||
* LEVEL2: Includes LEVEL1, plus a2, b2, c1, c2
|
||||
* LEVEL3: Includes LEVEL2, plus d
|
||||
* STRONGMEM levels (coarse-grained):
|
||||
* 1: Includes a1, b1, c1
|
||||
* 2: Includes LEVEL1, plus a2, b2, c2
|
||||
* 3: Includes LEVEL2, plus d
|
||||
*
|
||||
* WEAKBARRIER levels (fine-grained):
|
||||
* 1: Use dmb.ishld and dmb.ishst over dmb.ish for more performance
|
||||
* 2. All 1. Plus disabled the last write barriers (c1, c2)
|
||||
*/
|
||||
|
||||
#define STRONGMEM_SIMD_WRITE 2 // The level of SIMD memory writes will be tracked
|
||||
@ -161,21 +165,22 @@
|
||||
} while (0)
|
||||
|
||||
// An opcode will write memory, this will be put before the STORE instruction automatically.
|
||||
#define WILLWRITE() \
|
||||
do { \
|
||||
if (box64_dynarec_strongmem >= dyn->insts[ninst].will_write && dyn->smwrite == 0) { \
|
||||
/* Will write but never written, this is the start of a SEQ, put a barrier. */ \
|
||||
if (box64_dynarec_weakbarrier) \
|
||||
DMB_ISHST(); \
|
||||
else \
|
||||
DMB_ISH(); \
|
||||
} else if (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE && box64_dynarec_weakbarrier <= 1 && dyn->insts[ninst].last_write) { \
|
||||
/* Last write, put a barrier */ \
|
||||
if (box64_dynarec_weakbarrier) \
|
||||
DMB_ISHST(); \
|
||||
else \
|
||||
DMB_ISH(); \
|
||||
} \
|
||||
#define WILLWRITE() \
|
||||
do { \
|
||||
if (box64_dynarec_strongmem >= dyn->insts[ninst].will_write && dyn->smwrite == 0) { \
|
||||
/* Will write but never written, this is the start of a SEQ, put a barrier. */ \
|
||||
if (box64_dynarec_weakbarrier) \
|
||||
DMB_ISHLD(); \
|
||||
else \
|
||||
DMB_ISH(); \
|
||||
} else if (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE && box64_dynarec_weakbarrier != 2 \
|
||||
&& dyn->insts[ninst].last_write) { \
|
||||
/* Last write, put a barrier */ \
|
||||
if (box64_dynarec_weakbarrier) \
|
||||
DMB_ISHST(); \
|
||||
else \
|
||||
DMB_ISH(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Similar to WILLWRITE, but checks lock.
|
||||
@ -195,22 +200,19 @@
|
||||
} while (0)
|
||||
|
||||
// Will be put at the end of the SEQ
|
||||
#define SMEND() \
|
||||
do { \
|
||||
if (box64_dynarec_strongmem) { \
|
||||
/* Check if there is any guest memory write. */ \
|
||||
int i = ninst; \
|
||||
while (i >= 0 && !dyn->insts[i].will_write) \
|
||||
--i; \
|
||||
if (i >= 0) { \
|
||||
/* It's a SEQ, put a barrier here. */ \
|
||||
if (box64_dynarec_weakbarrier) \
|
||||
DMB_ISHST(); \
|
||||
else \
|
||||
DMB_ISH(); \
|
||||
} \
|
||||
} \
|
||||
dyn->smwrite = 0; \
|
||||
#define SMEND() \
|
||||
do { \
|
||||
if (box64_dynarec_strongmem) { \
|
||||
/* It's a SEQ, put a barrier here. */ \
|
||||
if (dyn->smwrite) { \
|
||||
/* Check if the next instruction has a end loop mark */ \
|
||||
if (box64_dynarec_weakbarrier) \
|
||||
DMB_ISHST(); \
|
||||
else \
|
||||
DMB_ISH(); \
|
||||
} \
|
||||
} \
|
||||
dyn->smwrite = 0; \
|
||||
} while (0)
|
||||
|
||||
// The barrier.
|
||||
@ -1283,9 +1285,9 @@
|
||||
#define FTABLE64(A, V)
|
||||
#endif
|
||||
|
||||
#define ARCH_INIT() \
|
||||
dyn->smread = dyn->smwrite = 0; \
|
||||
dyn->doublepush = 0; \
|
||||
#define ARCH_INIT() \
|
||||
SMSTART(); \
|
||||
dyn->doublepush = 0; \
|
||||
dyn->doublepop = 0;
|
||||
#define ARCH_RESET()
|
||||
|
||||
|
@ -106,9 +106,9 @@ typedef struct instruction_arm64_s {
|
||||
uint16_t ymm0_out; // the ymm0 at th end of the opcode
|
||||
uint16_t ymm0_pass2, ymm0_pass3;
|
||||
uint8_t barrier_maybe;
|
||||
uint8_t will_write;
|
||||
uint8_t last_write;
|
||||
uint8_t lock;
|
||||
uint8_t will_write:2; // [strongmem] will write to memory
|
||||
uint8_t last_write:1; // [strongmem] the last write in a SEQ
|
||||
uint8_t lock:1; // [strongmem] lock semantic
|
||||
uint8_t set_nat_flags; // 0 or combinaison of native flags define
|
||||
uint8_t use_nat_flags; // 0 or combinaison of native flags define
|
||||
uint8_t use_nat_flags_before; // 0 or combinaison of native flags define
|
||||
@ -159,7 +159,6 @@ typedef struct dynarec_arm_s {
|
||||
int forward_ninst; // ninst at the forward point
|
||||
uint16_t ymm_zero; // bitmap of ymm to zero at purge
|
||||
uint8_t smwrite; // for strongmem model emulation
|
||||
uint8_t smread;
|
||||
uint8_t doublepush;
|
||||
uint8_t doublepop;
|
||||
uint8_t always_test;
|
||||
|
Loading…
Reference in New Issue
Block a user