about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-11-21 01:59:20 +0800
committerGitHub <noreply@github.com>2024-11-20 18:59:20 +0100
commit9757d1b67aa51f6e7d4a5f535953a708ce6711bc (patch)
tree0c4b761b31afaf1accf8b3131b13f6b38e1ecdba /src
parent5422b108af4213228ad7a41e3e4353fb3115b324 (diff)
downloadbox64-9757d1b67aa51f6e7d4a5f535953a708ce6711bc.tar.gz
box64-9757d1b67aa51f6e7d4a5f535953a708ce6711bc.zip
[ARM64_DYNAREC] More optimizations on strongmem emulation (#2051)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h78
-rw-r--r--src/dynarec/arm64/dynarec_arm64_private.h7
2 files changed, 43 insertions, 42 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index aa06379f..1979c90e 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -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()
 
diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h
index 295574b8..297d9895 100644
--- a/src/dynarec/arm64/dynarec_arm64_private.h
+++ b/src/dynarec/arm64/dynarec_arm64_private.h
@@ -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;