about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-11-20 02:59:43 +0800
committerGitHub <noreply@github.com>2024-11-19 19:59:43 +0100
commit81e4e26dc51b85720fbc3ba2ffe68030e5d227fa (patch)
treecc6b62f68664f88fafccad7517a463ea55b56735
parent4f6a66f9c60f20c97059215d076effc3c9fafd7f (diff)
downloadbox64-81e4e26dc51b85720fbc3ba2ffe68030e5d227fa.tar.gz
box64-81e4e26dc51b85720fbc3ba2ffe68030e5d227fa.zip
[ARM64_DYNAREC] Re-enable weakbarrier for dmb.ishst (#2048)
-rw-r--r--docs/USAGE.md11
-rw-r--r--docs/box64.pod12
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h17
3 files changed, 31 insertions, 9 deletions
diff --git a/docs/USAGE.md b/docs/USAGE.md
index 379d82dd..eb94ff18 100644
--- a/docs/USAGE.md
+++ b/docs/USAGE.md
@@ -169,9 +169,14 @@ 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 Barrier when writting to memory (on some MOV opcode) to simulate Strong Memory Model while trying to limit performance impact (Default when libmonobdwgc-2.0.so is loaded)

-* 2 : All 1. plus a memory barrier on every write to memory using MOV

-* 3 : All 2. plus Memory Barrier when reading from memory and on some SSE/SSE2 opcodes too

+* 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)

+* 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

+* 0 : Use regular safe barrier (Default.)

+* 1 : Use weak barriers to have more performance boost

 

 #### BOX64_DYNAREC_X87DOUBLE *

 Force the use of Double for x87 emulation

diff --git a/docs/box64.pod b/docs/box64.pod
index 478e602f..d0d192c0 100644
--- a/docs/box64.pod
+++ b/docs/box64.pod
@@ -296,8 +296,16 @@ 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 Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model while trying to limit performance impact (Default when libmonobdwgc-2.0.so is loaded)
-    * 2 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model
+    * 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)
+    * 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
+
+    * 0 : Use regular safe barrier (Default.)
+    * 1 : Use weak barriers to have more performance boost
 
 =item B<BOX64_DYNAREC_X87DOUBLE>=I<0|1>
 
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index e76aac02..15a2d423 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -60,7 +60,7 @@
  */
 
 #define STRONGMEM_SIMD_WRITE 2 // The level of SIMD memory writes will be tracked
-#define STRONGMEM_LAST_WRITE 2 // The level of a barrier before the last guest memory store will be put
+#define STRONGMEM_LAST_WRITE 1 // The level of a barrier before the last guest memory store will be put
 #define STRONGMEM_SEQ_WRITE  3 // The level of a barrier at every third memory store will be  put
 
 #if STEP == 1
@@ -165,10 +165,16 @@
     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. */            \
-            DMB_ISH();                                                                                \
+            if (box64_dynarec_weakbarrier)                                                            \
+                DMB_ISHST();                                                                          \
+            else                                                                                      \
+                DMB_ISH();                                                                            \
         } else if (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE && dyn->insts[ninst].last_write) { \
             /* Last write, put a barrier */                                                           \
-            DMB_ISH();                                                                                \
+            if (box64_dynarec_weakbarrier)                                                            \
+                DMB_ISHST();                                                                          \
+            else                                                                                      \
+                DMB_ISH();                                                                            \
         }                                                                                             \
     } while (0)
 
@@ -198,7 +204,10 @@
                 --i;                                        \
             if (i >= 0) {                                   \
                 /* It's a SEQ, put a barrier here. */       \
-                DMB_ISH();                                  \
+                if (box64_dynarec_weakbarrier)              \
+                    DMB_ISHST();                            \
+                else                                        \
+                    DMB_ISH();                              \
             }                                               \
         }                                                   \
         dyn->smwrite = 0;                                   \