Files
lity3d/Engine/ASM/string_ops.asm
T
shuiyu1123 0669d102ce feat: major engine overhaul - scene demo with lighting, sphere, ground
- Scene Demo: cube + sphere + ground plane with proper lighting
- Audio: XAudio2 dynamic loading + WAV playback
- Physics: expanded collision system
- Renderer: improved pipeline with materials
- UI: extended widget system
- VisualScript: enhanced serializer + block interactions
- ASM: optimized math/memory/profiling routines
- Window: mouse input + scroll support
2026-07-12 08:21:07 +08:00

305 lines
7.2 KiB
NASM

; ============================================================================
; string_ops.asm - 快速字符串/内存操作 (x86-64 MASM)
; 使用 SSE4.1 加速 memcpy/memset/strlen
; ============================================================================
include asm_macros.inc
.CODE
; ============================================================================
; 内存操作
; ============================================================================
; void fast_memcpy(void* dst, const void* src, uint64_t count)
; RCX = dst, RDX = src, R8 = count
fast_memcpy PROC
mov rax, rcx ; rax = dst
mov r9, r8 ; r9 = count
; 小于 16 字节: 逐字节复制
cmp r9, 16
jb memcpy_small
; 16-32 字节: 两次 128-bit 加载
cmp r9, 32
jb memcpy_16_32
; 32-64 字节: 四次 128-bit 加载
cmp r9, 64
jb memcpy_32_64
; >= 64 字节: SSE 批量复制
; 确保 16 字节对齐
mov r10, rcx
and r10, 0Fh ; 检查 dst 对齐
jnz memcpy_unaligned
memcpy_aligned_loop:
cmp r9, 64
jb memcpy_tail
; 每次复制 64 字节 (4x128-bit)
movaps xmm0, xmmword ptr [rdx]
movaps xmm1, xmmword ptr [rdx + 16]
movaps xmm2, xmmword ptr [rdx + 32]
movaps xmm3, xmmword ptr [rdx + 48]
movaps xmmword ptr [rcx], xmm0
movaps xmmword ptr [rcx + 16], xmm1
movaps xmmword ptr [rcx + 32], xmm2
movaps xmmword ptr [rcx + 48], xmm3
add rcx, 64
add rdx, 64
sub r9, 64
jmp memcpy_aligned_loop
memcpy_tail:
; 处理剩余 0-63 字节
test r9, 32
jz memcpy_tail_16
movaps xmm0, xmmword ptr [rdx]
movaps xmm1, xmmword ptr [rdx + 16]
movaps xmmword ptr [rcx], xmm0
movaps xmmword ptr [rcx + 16], xmm1
add rcx, 32
add rdx, 32
sub r9, 32
memcpy_tail_16:
test r9, 16
jz memcpy_tail_8
movaps xmm0, xmmword ptr [rdx]
movaps xmmword ptr [rcx], xmm0
memcpy_tail_8:
test r9, 8
jz memcpy_tail_4
mov r10, qword ptr [rdx]
mov qword ptr [rcx], r10
memcpy_tail_4:
test r9, 4
jz memcpy_tail_2
mov r10d, dword ptr [rdx]
mov dword ptr [rcx], r10d
memcpy_tail_2:
test r9, 2
jz memcpy_tail_1
mov r10w, word ptr [rdx]
mov word ptr [rcx], r10w
memcpy_tail_1:
test r9, 1
jz memcpy_done
mov r10b, byte ptr [rdx]
mov byte ptr [rcx], r10b
jmp memcpy_done
memcpy_unaligned:
; 非对齐时使用 movups
movups xmm0, xmmword ptr [rdx]
movups xmmword ptr [rcx], xmm0
add rcx, 16
add rdx, 16
sub r9, 16
jmp memcpy_aligned_loop
memcpy_32_64:
mov r10, qword ptr [rdx]
mov qword ptr [rcx], r10
mov r10, qword ptr [rdx + 8]
mov qword ptr [rcx + 8], r10
mov r10, qword ptr [rdx + 16]
mov qword ptr [rcx + 16], r10
mov r10, qword ptr [rdx + 24]
mov qword ptr [rcx + 24], r10
sub r9, 32
add rdx, 32
add rcx, 32
jmp memcpy_small
memcpy_16_32:
mov r10, qword ptr [rdx]
mov qword ptr [rcx], r10
mov r10, qword ptr [rdx + 8]
mov qword ptr [rcx + 8], r10
test r9, 8
jz memcpy_16_32_done
mov r10, qword ptr [rdx + 16]
mov qword ptr [rcx + 16], r10
memcpy_16_32_done:
jmp memcpy_done
memcpy_small:
test r9, r9
jz memcpy_done
mov r10, r9
and r10, 7 ; r10 = count % 8
shr r9, 3 ; r9 = count / 8
; 复制完整 8 字节
memcpy_small_loop:
test r9, r9
jz memcpy_small_tail
mov r11, qword ptr [rdx]
mov qword ptr [rcx], r11
add rdx, 8
add rcx, 8
dec r9
jmp memcpy_small_loop
memcpy_small_tail:
; 复制剩余字节
test r10, r10
jz memcpy_done
mov r11b, byte ptr [rdx]
mov byte ptr [rcx], r11b
inc rdx
inc rcx
dec r10
jmp memcpy_small_tail
memcpy_done:
mov rax, rax ; 返回 dst
ret
fast_memcpy ENDP
; void fast_memset(void* dst, int value, uint64_t count)
; RCX = dst, EDX = value, R8 = count
fast_memset PROC
mov rax, rcx
mov r9, r8
; 将 value 扩展到所有字节
movsx rdx, dl ; 符号扩展
mov rcx, rdx
shl rcx, 8
or rdx, rcx
mov rcx, rdx
shl rcx, 16
or rdx, rcx ; rdx = value 重复4次
mov rcx, rdx
shl rcx, 32
or rdx, rcx ; rdx = value 重复8次
; 复制到 XMM 寄存器
vmovq xmm0, rdx
vinsertf128 ymm0, ymm0, xmm0, 1 ; 256-bit 广播
; >= 32 字节: AVX 批量
cmp r9, 32
jb memset_small
memset_avx_loop:
cmp r9, 32
jb memset_tail
vmovdqu ymmword ptr [rax], ymm0
add rax, 32
sub r9, 32
jmp memset_avx_loop
memset_tail:
; 处理剩余 0-31 字节
test r9, 16
jz memset_tail_8
movups xmmword ptr [rax], xmm0
add rax, 16
sub r9, 16
memset_tail_8:
test r9, 8
jz memset_tail_4
mov qword ptr [rax], rdx
add rax, 8
memset_tail_4:
test r9, 4
jz memset_tail_2
mov dword ptr [rax], edx
add rax, 4
memset_tail_2:
test r9, 2
jz memset_tail_1
mov word ptr [rax], dx
add rax, 2
memset_tail_1:
test r9, 1
jz memset_done
mov byte ptr [rax], dl
jmp memset_done
memset_small:
test r9, r9
jz memset_done
mov byte ptr [rax], dl
inc rax
dec r9
jmp memset_small
memset_done:
vzeroupper
ret
fast_memset ENDP
; ============================================================================
; 字符串操作
; ============================================================================
; uint64_t fast_strlen(const char* str) -> RAX
; 使用 SSE4.2 PCMPESTRI 搜索 null terminator
fast_strlen PROC
mov rdx, rcx ; rdx = original str
pxor xmm0, xmm0 ; 搜索 0
strlen_sse_loop:
mov rax, rcx ; rax = 当前 16 字节块起始
movdqu xmm1, xmmword ptr [rcx]
pcmpestri xmm0, xmm1, 00001000b ; 搜索 0, CF=1 表示找到, ECX=偏移
jc strlen_found
add rcx, 16
jmp strlen_sse_loop
strlen_found:
; rax = 块起始, rcx (ecx) = 块内偏移
add rax, rcx
sub rax, rdx
ret
fast_strlen ENDP
; int fast_strcmp(const char* a, const char* b) -> EAX
; 返回: 0=相等, <0=a<b, >0=a>b
fast_strcmp PROC
xor rax, rax
strcmp_loop:
movzx r8d, byte ptr [rcx + rax]
movzx r9d, byte ptr [rdx + rax]
cmp r8b, r9b
jne strcmp_diff
test r8b, r8b
jz strcmp_equal
inc rax
jmp strcmp_loop
strcmp_diff:
mov eax, r8d
sub eax, r9d
ret
strcmp_equal:
xor eax, eax
ret
fast_strcmp ENDP
END