diff --git a/lang/src/vec.asm b/lang/src/vec.asm index ead1ec8..3c2d246 100644 --- a/lang/src/vec.asm +++ b/lang/src/vec.asm @@ -19,6 +19,8 @@ global vec_remove global vec_get global vec_drop global vec_find +global vec_insert +global vec_binary_search_by global vec_tests @@ -454,3 +456,104 @@ vec_find: ret .panic: call panic +;; rdi: pointer to Vec struct +;; rsi : index +;; rdx: pointer to data to insert +;; fn vec_insert(vec: *mut Vec, index: usize, data: *const T, size: usize) +vec_insert: + push rbp + mov rbp, rsp + sub rsp, 32 + mov [rsp], rdi ; save vec + mov [rsp + 8], rsi ; save index + mov [rsp + 16], rdx ; save data ptr + + mov rsi, rdx + mov rdx, rcx + call vec_push + mov rdi, [rsp] + mov rsi, [rdi + 8] + sub rsi, 1 + mov rdx, [rsp + 8] + call vec_swap + add rsp, 32 + pop rbp + ret + + +;; rdi: pointer to Vec struct +;; rsi: pointer to key +;; rdx: compare function fn(ctx: *const (), a: *const T, b: *const T) -> i32 +;; rcx: compare_fn context +;;fn vec_binary_search_by(vec: *mut Vec, key: *const T, compare: fn(ctx: *const (), a: *const T, b: *const T) -> i32, ctx: *const ()) -> isize +vec_binary_search_by: + push rbp + mov rbp, rsp + sub rsp, 0x40 + mov [rsp], rdi ; save vec + mov [rsp + 0x8], rsi ; save key + mov [rsp + 0x10], rdx ; save compare fn + mov [rsp + 0x18], rcx ; save compare fn context + + mov rax, [rdi + 8] ; len + mov qword [rsp + 0x20], 0 ; low + mov [rsp + 0x28], rax ; mid + mov [rsp + 0x30], rax ; high + mov rax, [rdi + 24] ; item_size + mov [rsp + 0x38], rax ; item_size + +.loop: + mov rax, [rsp + 0x20] ; low + mov rcx, [rsp + 0x30] ; high + cmp rax, rcx + jge .not_found + ; mid = (low + high) / 2 + sub rcx, rax + shr rcx, 1 + add rax, rcx + mov [rsp + 0x28], rax ; mid + + mov rcx, [rsp] ; vec + mov rcx, [rcx] ; vec.data + mov rdx, [rsp + 0x38] ; item_size + mul rdx ; mid * item_size + add rax, rcx ; vec.data + mid * item_size + mov rdi, [rsp + 0x18] ; compare ctx + mov rsi, rax + mov rdx, [rsp + 0x8] ; key + mov rax, [rsp + 0x10] ; compare fn + call rax + cmp eax, 0 + je .found + jl .less + ; greater + mov rax, [rsp + 0x28] ; mid + inc rax + mov [rsp + 0x20], rax ; low = mid + 1 + jmp .loop +.less: + mov rax, [rsp + 0x28] ; mid + dec rax + mov [rsp + 0x30], rax ; high = mid - 1 + jmp .loop +.found: + mov rax, [rsp + 0x28] + jmp .epilogue +.not_found: + mov rax, [rsp + 0x20] + not rax + +.epilogue: + add rsp, 0x40 + pop rbp + ret + + + + + + + + + +