60 lines
1.3 KiB
ArmAsm
60 lines
1.3 KiB
ArmAsm
global ft_list_sort
|
|
|
|
ft_list_sort:
|
|
push r12 ; callee saved registers
|
|
push r13
|
|
push r14
|
|
push r15
|
|
cmp qword [rdi], 0
|
|
je .done
|
|
mov r12, 0 ; r12 "prev" = NULL
|
|
mov r13, [rdi] ; r13 "curr" = *begin_list
|
|
mov r14, rdi ; r14 "begin_list"
|
|
mov r15, rsi ; r15 cmp function (avoids pop push in .loop)
|
|
|
|
.loop:
|
|
cmp qword [r13 + 8], 0 ; if curr->next is null then exit
|
|
je .done
|
|
mov rdi, [r13] ; first arg is curr->data
|
|
mov rsi, [r13 + 8] ; rsi = curr->next;
|
|
mov rsi, [rsi] ; rsi = rsi->data;
|
|
call r15
|
|
cmp eax, 0
|
|
jle .next; if in order continue...
|
|
cmp r13, [r14]
|
|
je .is_first_elem
|
|
mov rdx, [r13 + 8]
|
|
mov [r12 + 8], rdx ; prev->next = curr->next
|
|
mov rcx, [r13 + 8]
|
|
mov rdx, [rcx + 8] ; curr->next = curr->next->next
|
|
mov [r13 + 8], rdx
|
|
mov rcx, [r12 + 8]
|
|
mov [rcx + 8], r13 ; prev->next->next = curr
|
|
mov r12, 0 ; reset prev
|
|
mov r13, [r14] ; reset curr
|
|
jmp .loop
|
|
|
|
.is_first_elem:
|
|
mov rdx, [r13 + 8]
|
|
mov [r14], rdx ; *begin_list = curr->next
|
|
mov rdx, [r13 + 8]
|
|
mov rcx, [rdx + 8]
|
|
mov [r13 + 8], rcx ; curr->next = curr->next->next
|
|
mov rdx, [r14]
|
|
mov [rdx + 8], r13 ; *begin_list->next = curr
|
|
mov r12, 0 ; reset prev
|
|
mov r13, [r14] ; reset curr
|
|
jmp .loop
|
|
|
|
.next:
|
|
mov r12, r13 ; prev = curr;
|
|
mov r13, [r13 + 8] ; curr = curr->next;
|
|
jmp .loop
|
|
|
|
.done:
|
|
pop r15 ; restore stack and return
|
|
pop r14
|
|
pop r13
|
|
pop r12
|
|
ret
|