:: commit 9da61456d9afce1615703148cd0b112b0fccf59a

Mintsuki <mintsuki@protonmail.com> — 2026-04-25 15:32

parents: beea0dc6fb

lib/mem: Bring back assembly versions of x86-64/IA-32 memory routines

This is an attempt to mitigate certain performance regressions. See #557.
diff --git a/common/lib/mem.asm_x86_64 b/common/lib/mem.asm_x86_64
new file mode 100644
index 00000000..f082324f
--- /dev/null
+++ b/common/lib/mem.asm_x86_64
@@ -0,0 +1,57 @@
+section .text
+
+global memcpy
+memcpy:
+    mov rcx, rdx
+    mov rax, rdi
+    rep movsb
+    ret
+
+global memset
+memset:
+    push rdi
+    mov rax, rsi
+    mov rcx, rdx
+    rep stosb
+    pop rax
+    ret
+
+global memmove
+memmove:
+    mov rcx, rdx
+    mov rax, rdi
+
+    cmp rdi, rsi
+    ja .copy_backwards
+
+    rep movsb
+    jmp .done
+
+  .copy_backwards:
+    lea rdi, [rdi+rcx-1]
+    lea rsi, [rsi+rcx-1]
+    std
+    rep movsb
+    cld
+
+  .done:
+    ret
+
+global memcmp
+memcmp:
+    mov rcx, rdx
+    repe cmpsb
+    je .equal
+
+    mov al, byte [rdi-1]
+    sub al, byte [rsi-1]
+    movsx rax, al
+    jmp .done
+
+  .equal:
+    xor eax, eax
+
+  .done:
+    ret
+
+section .note.GNU-stack noalloc noexec nowrite progbits
diff --git a/common/lib/mem.s2.asm_ia32 b/common/lib/mem.s2.asm_ia32
new file mode 100644
index 00000000..a23f685d
--- /dev/null
+++ b/common/lib/mem.s2.asm_ia32
@@ -0,0 +1,77 @@
+section .text
+
+global memcpy
+memcpy:
+    push esi
+    push edi
+    mov eax, dword [esp+12]
+    mov edi, eax
+    mov esi, dword [esp+16]
+    mov ecx, dword [esp+20]
+    rep movsb
+    pop edi
+    pop esi
+    ret
+
+global memset
+memset:
+    push edi
+    mov edx, dword [esp+8]
+    mov edi, edx
+    mov eax, dword [esp+12]
+    mov ecx, dword [esp+16]
+    rep stosb
+    mov eax, edx
+    pop edi
+    ret
+
+global memmove
+memmove:
+    push esi
+    push edi
+    mov eax, dword [esp+12]
+    mov edi, eax
+    mov esi, dword [esp+16]
+    mov ecx, dword [esp+20]
+
+    cmp edi, esi
+    ja .copy_backwards
+
+    rep movsb
+    jmp .done
+
+  .copy_backwards:
+    lea edi, [edi+ecx-1]
+    lea esi, [esi+ecx-1]
+    std
+    rep movsb
+    cld
+
+  .done:
+    pop edi
+    pop esi
+    ret
+
+global memcmp
+memcmp:
+    push esi
+    push edi
+    mov edi, dword [esp+12]
+    mov esi, dword [esp+16]
+    mov ecx, dword [esp+20]
+    repe cmpsb
+    je .equal
+    mov al, byte [edi-1]
+    sub al, byte [esi-1]
+    movsx eax, al
+    jmp .done
+
+  .equal:
+    xor eax, eax
+
+  .done:
+    pop edi
+    pop esi
+    ret
+
+section .note.GNU-stack noalloc noexec nowrite progbits
diff --git a/common/lib/memory.s2.c b/common/lib/memory.s2.c
index a5353b2b..c51bc4c7 100644
--- a/common/lib/memory.s2.c
+++ b/common/lib/memory.s2.c
@@ -1,3 +1,5 @@
+#if !defined (__x86_64__) && !defined (__i386__)
+
 #include <stdint.h>
 #include <stddef.h>
 
@@ -51,3 +53,5 @@ int memcmp(const void *s1, const void *s2, size_t n) {
 
     return 0;
 }
+
+#endif
tab: 248 wrap: offon