78 lines
2 KiB
NASM
78 lines
2 KiB
NASM
;; Vec / Dynamic Array Structure
|
|
extern heap_realloc
|
|
|
|
global vec_init
|
|
global vec_get_nth
|
|
global vec_reserve
|
|
|
|
struc Vec
|
|
.data resq 1 ; pointer to elements
|
|
.size resd 1 ; size in element count
|
|
.cap resd 1 ; cap in element count
|
|
.ele_size resd 1 ; size of each element in bytes
|
|
.ele_align resd 1 ; alignment of each element in bytes
|
|
endstruc
|
|
|
|
;; fn vec_init(vec: *mut Vec, ele_size: usize, ele_align: usize) -> *mut Vec
|
|
vec_init:
|
|
mov qword [rdi + Vec.data], 0
|
|
mov dword [rdi + Vec.size], 0
|
|
mov dword [rdi + Vec.cap], 0
|
|
mov dword [rdi + Vec.ele_size], esi
|
|
mov dword [rdi + Vec.ele_align], edx
|
|
mov rax, rdi
|
|
ret
|
|
|
|
;; fn vec_get_nth(vec: *const Vec, idx: usize) -> *const u8
|
|
vec_get_nth:
|
|
mov rax, rsi
|
|
mov ecx, dword [rdi + Vec.ele_size]
|
|
mul ecx
|
|
add rax, qword [rdi + Vec.data]
|
|
ret
|
|
|
|
;; reserve space for $rsi additional entries in vec $rdi.
|
|
;; fn vec_reserve(vec: *mut Vec, count: usize)
|
|
vec_reserve:
|
|
push rbp
|
|
mov rbp, rsp
|
|
sub rsp, 16
|
|
|
|
mov edx, dword [rdi + Vec.ele_size]
|
|
mov ecx, dword [rdi + Vec.ele_align]
|
|
mov dword [rsp], edx ; obj-size
|
|
mov dword [rsp + 4], ecx ; alignment
|
|
mov qword [rsp + 8], rdi ; table pointer
|
|
|
|
mov eax, dword [rdi + Vec.size]
|
|
add eax, esi
|
|
cmp eax, dword [rdi + Vec.cap]
|
|
jl .done
|
|
|
|
mov eax, esi
|
|
add eax, dword [rdi + Vec.size]
|
|
mov ecx, dword [rdi + Vec.cap]
|
|
mov edx, ecx
|
|
shl edx, 1
|
|
cmp eax, edx
|
|
cmovl eax, edx
|
|
; new cap
|
|
mul dword [rsp] ; obj-size
|
|
|
|
; old cap
|
|
xchg eax, ecx
|
|
mul dword [rsp] ; obj-size
|
|
|
|
mov rdi, qword [rdi + Vec.data] ; old pointer
|
|
mov esi, eax ; old size
|
|
mov edx, ecx ; new size
|
|
mov ecx, dword [rsp + 4] ; alignment
|
|
call heap_realloc
|
|
mov rdi, qword [rsp + 8] ; table pointer
|
|
mov qword [rdi + Vec.data], rax
|
|
|
|
.done:
|
|
add rsp, 16
|
|
pop rbp
|
|
ret
|