about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-03-31 10:29:57 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-03-31 10:29:57 +0200
commit8561a4a8331cf7918b261712383003699de0ace8 (patch)
tree4b577a5cd003f17cd1338fea5be8c53f26343a8a /src
parentc40f9651bc51c0f3446484233d6ce63d05ec4b7b (diff)
downloadbox64-8561a4a8331cf7918b261712383003699de0ace8.tar.gz
box64-8561a4a8331cf7918b261712383003699de0ace8.zip
[ARM64] Use crc32 hardware support (if available) for dynablock signature
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/arm64_lock.S22
-rw-r--r--src/dynarec/dynablock.c4
-rw-r--r--src/dynarec/dynarec_arch.h2
3 files changed, 28 insertions, 0 deletions
diff --git a/src/dynarec/arm64/arm64_lock.S b/src/dynarec/arm64/arm64_lock.S
index 2203648b..74855129 100644
--- a/src/dynarec/arm64/arm64_lock.S
+++ b/src/dynarec/arm64/arm64_lock.S
@@ -34,6 +34,7 @@
 .global arm64_lock_get_b
 .global arm64_lock_get_d
 .global arm64_lock_get_dd
+.global arm64_crc
 
 arm64_lock_read_b:
     dmb     ish
@@ -395,3 +396,24 @@ arm64_lock_get_d:
 arm64_lock_get_dd:
     ldaxr   x0, [x0]
     ret
+
+arm64_crc:
+    //x0 is address, w1 is len
+    mov     x2, x0  // address is x2 now
+    mov     w0, wzr // crc is w0
+1:
+    cmp     w1, #8
+    blo     2f
+    ldr     x3, [x2], #8
+    crc32x  w0, w0, x3
+    subs    w1, w1, #8
+    bne     1b
+2:
+    cbz     w1, 4f
+3:
+    ldrb    w3, [x2], #1
+    crc32b  w0, w0, w3
+    subs    w1, w1, #1
+    bne     3b
+4:
+    ret
\ No newline at end of file
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 7a7e4033..004d7a2b 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -22,6 +22,7 @@
 #include "signals.h"
 
 #include "dynarec_native.h"
+#include "dynarec_arch.h"
 #include "native_lock.h"
 
 #include "custommem.h"
@@ -31,6 +32,9 @@
 uint32_t X31_hash_code(void* addr, int len)
 {
     if(!len) return 0;
+    #ifdef ARCH_CRC
+    ARCH_CRC(addr, len);
+    #endif
     uint8_t* p = (uint8_t*)addr;
     int32_t h = *p;
     for (--len, ++p; len; --len, ++p) h = (h << 5) - h + (int32_t)*p;
diff --git a/src/dynarec/dynarec_arch.h b/src/dynarec/dynarec_arch.h
index f02a1bca..eaf64fd8 100644
--- a/src/dynarec/dynarec_arch.h
+++ b/src/dynarec/dynarec_arch.h
@@ -30,6 +30,8 @@
 #define ARCH_ADJUST(A, B, C, D) adjust_arch(A, B, C, D)

 #define STOP_NATIVE_FLAGS(A, B)   A->insts[B].nat_flags_op = NAT_FLAG_OP_UNUSABLE

 #define ARCH_UNALIGNED(A, B) arch_unaligned(A, B)

+extern uint32_t arm64_crc(void* p, uint32_t len);

+#define ARCH_CRC(A, B)  if(arm64_crc32) return arm64_crc(A, B)

 #elif defined(LA64)

 

 #define instruction_native_t        instruction_la64_t