Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ft_list_sort #9

Merged
merged 5 commits into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ LIST_ASM_SRC = \
ft_list_push_front.s \
ft_list_remove_if.s \
ft_list_size.s \
ft_list_sort.s \
ft_read.s \
ft_strcmp.s \
ft_strcpy.s \
Expand All @@ -23,13 +24,15 @@ LIST_TEST_SRC = \
ft_list_push_front.c \
ft_list_remove_if.c \
ft_list_size.c \
ft_list_sort.c \
ft_read.c \
ft_strcmp.c \
ft_strcpy.c \
ft_strdup.c \
ft_strlen.c \
ft_write.c \
main.c
main.c \
utils.c

# ------------ DIRECTORIES ------------ #

Expand Down
1 change: 1 addition & 0 deletions include/libasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ t_list *ft_create_elem(void *data);
void ft_list_push_front(t_list **begin_list, void *data);
int ft_list_size(t_list *begin_list);
void ft_list_remove_if(t_list **begin_list, void *data_ref, int (*cmp)(), void (*free_fct)(void *));
void ft_list_sort(t_list **begin_list, int (*cmp)());

#endif
241 changes: 241 additions & 0 deletions src/ft_list_sort.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
bits 64

%include "ft_list.s"

section .note.GNU-stack

section .text
global ft_list_sort

;typedef struct s_list
;{
; void *data;
; struct s_list *next;
;} t_list;

; void ft_list_sort(t_list **head, int (*cmp)()) {
; if (head == NULL || *head == NULL || (*head)->next == NULL) {
; return;
; }
;
; t_list *middle = get_middle(*head);
; t_list *next_to_middle = middle->next;
; middle->next = NULL;
;
; ft_list_sort(head, cmp);
; return;
; ft_list_sort(&next_to_middle, cmp);
;
; *head = sorted_merge(*head, next_to_middle, cmp);
; }

; t_list* sorted_merge(t_list *left, t_list *right, int (*cmp)(void*, void*)) {
; if (left == NULL) {
; return right;
; }
; if (right == NULL) {
; return left;
; }
;
; t_list *result = NULL;
;
; if (cmp(left->data, right->data) <= 0) {
; result = left;
; result->next = sorted_merge(left->next, right, cmp);
; } else {
; result = right;
; result->next = sorted_merge(left, right->next, cmp);
; }
;
; return result;
; }

; t_list* get_middle(t_list *head) {
; if (head == NULL) {
; return head;
; }
;
; t_list *slow = head;
; t_list *fast = head;
;
; while (fast->next != NULL && fast->next->next != NULL) {
; slow = slow->next;
; fast = fast->next->next;
; }
;
; printf("get_middle result: %p\n", slow);
; return slow;
; }

;void ft_list_sort(t_list **begin_list, int (*cmp)());
ft_list_sort:
test rdi, rdi
jz ft_list_sort_end
mov r8, [rdi]
test r8, r8
jz ft_list_sort_end
mov r8, [r8 + LIST_NEXT_OFFSET]
test r8, r8
jz ft_list_sort_end
sub rsp, 16
push rdi
push rsi
mov rdi, [rdi]
call get_middle
pop rsi
pop rdi
; middle
mov [rsp + 0], rax
; next_to_middle
mov rax, [rax + LIST_NEXT_OFFSET]
mov [rsp + 8], rax
; middle->next = 0
mov rax, [rsp + 0]
mov qword [rax + LIST_NEXT_OFFSET], 0


push rdi
push rsi
call ft_list_sort
pop rsi
pop rdi

mov r8, rsp
add r8, 8
push rdi
push rsi
mov rdi, r8
call ft_list_sort
; right
pop rsi
pop rdi

mov r8, [rsp + 8]
push rdi
push rsi
mov rdi, [rdi]
mov rdx, rsi
mov rsi, r8
call sorted_merge
pop rsi
pop rdi
mov [rdi], rax
add rsp, 16
ret

ft_list_sort_end:
ret


;t_list* sorted_merge(t_list *left, t_list *right, int (*cmp)(void*, void*))
sorted_merge:
test rdi, rdi
jz sorted_merge_ret_right
test rsi, rsi
jz sorted_merge_ret_left
; result
sub rsp, 8
mov qword [rsp + 0], 0
push rdi
push rsi
push rdx
mov rdi, [rdi + LIST_DATA_OFFSET]
mov rsi, [rsi + LIST_DATA_OFFSET]
call rdx
pop rdx
pop rsi
pop rdi
; cmp only int32_t
cmp eax, 0
jle sorted_merge_below_or_equal
jmp sorted_merge_greater

sorted_merge_ret_left:
mov rax, rdi
ret

sorted_merge_ret_right:
mov rax, rsi
ret

sorted_merge_below_or_equal:
mov [rsp + 0], rdi
push rdi
push rsi
push rdx
mov rdi, [rdi + LIST_NEXT_OFFSET]
call sorted_merge
pop rdx
pop rsi
pop rdi
mov r8, [rsp + 0]
mov [r8 + LIST_NEXT_OFFSET], rax
jmp sorted_merge_end

sorted_merge_greater:
mov [rsp + 0], rsi
push rdi
push rsi
push rdx
mov rsi, [rsi + LIST_NEXT_OFFSET]
call sorted_merge
pop rdx
pop rsi
pop rdi
mov r8, [rsp + 0]
mov [r8 + LIST_NEXT_OFFSET], rax
jmp sorted_merge_end

sorted_merge_end:
mov rax, [rsp + 0]
add rsp, 8
ret

;t_list* get_middle(t_list *head)
get_middle:
test rdi, rdi
jz get_middle_ret_head
jnz get_middle_loop

get_middle_loop:
sub rsp, 16
; slow
mov [rsp + 0], rdi
; fast
mov [rsp + 8], rdi
jmp get_middle_loop_condition

get_middle_loop_condition:
mov r8, [rsp + 8]
mov r8, [r8 + LIST_NEXT_OFFSET]
test r8, r8
jnz get_middle_loop_condition2
jmp get_middle_ret_slow

get_middle_loop_condition2:
mov r8, [r8 + LIST_NEXT_OFFSET]
test r8, r8
jnz get_middle_loop_routine
jmp get_middle_ret_slow

get_middle_loop_routine:
mov r8, [rsp + 0]
mov r8, [r8 + LIST_NEXT_OFFSET]
mov [rsp + 0], r8
mov r8, [rsp + 8]
mov r8, [r8 + LIST_NEXT_OFFSET]
mov r8, [r8 + LIST_NEXT_OFFSET]
mov [rsp + 8], r8
jmp get_middle_loop_condition

get_middle_ret_head:
mov rax, rdi
ret

get_middle_ret_slow:
mov rax, [rsp + 0]
add rsp, 16
ret

end:
ret
8 changes: 1 addition & 7 deletions test/ft_list_remove_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "libasm.h"
#include "utest.h"
#include "utils.h"

UTEST(ft_list_remove_if, null_list_ptr) {
t_list **list_ptr = NULL;
Expand All @@ -29,13 +30,6 @@ UTEST(ft_list_remove_if, null_list) {
ASSERT_EQ(errno, 0);
}

static int my_strcmp(const void *s1, const void *s2) {
if (s1 == NULL || s2 == NULL) {
return 1;
}
return strcmp(s1, s2);
}

UTEST(ft_list_remove_if, null_data_ref) {
t_list *list = NULL;
char *data = strdup("Hello, World!");
Expand Down
Loading