## Fukncija implemetira quick sort po algoritmu
##	quick_sort(int *a, int l, int r){
##		int i, j, pivot, temp;
##		if(l>=r) return;
##
##		pivot = a[r];
##		i = l;
##		j = r;
##
##   	while(i<j){
##			while(i < j && a[i]<pivot) i++;
##			while(i < j && a[j]>=pivot) j--;
##			temp = a[i];
##			a[i] = a[j];
##			a[j] = temp;
##		}
##		a[r] = a[i];
##		a[i] = pivot;
##
##		quick_sort(a, l, i-1);
##		quick_sort(a, i+1, r);
##	}


.intel_syntax noprefix

.text
.global quick_sort

########################################
# void quick_sort(int *a, int l, int r)
#
# rdi - int *a
# esi - int l
# edx - int r
########################################

quick_sort:
    enter 0, 0

    cmp	    esi, edx                # Poredimo da li je l<r
    jge	    end_quick_sort          # Ako je l>=r prelazimo na kraj

    mov	    r12d, [rdi+rdx*4]       # U r12 smestamo pivot, a[r]

    mov	    r13d, esi               # i=l
    mov	    r14d, edx               # j=r

partition:
    cmp	    r13d, r14d              # while (i<j)
    jge	    end_partition           # ako je i>=j kraj particionisanja

left_loop:                          # while(i<j && a[i]<pivot) i++
    cmp	    r13d, r14d              # while (i<j)
    jge	    end_left_loop
    mov	    eax, [rdi+r13*4]
    sub	    eax, r12d
    cmp	    eax, 0                  # poredimo pivot sa tekucim u levom delu
    jge	    end_left_loop           # ako smo pronasli veceg izlazimo iz petlje
    inc	    r13                     # ako nismo, radimo i++
    jmp	    left_loop
end_left_loop:

right_loop:                         # while(i<j && a[j]>=pivot) j--;
    cmp	    r13d, r14d              # while (i<j)
    jge	    end_right_loop
    mov	    eax, [rdi+r14*4]
    sub	    eax, r12d
    cmp	    eax, 0                  # poredimo pivot sa tekucim u desnom delu
    jl	    end_right_loop          # ako smo nasli manjeg izlazimo iz petlje
    dec	    r14d                    # ako nismo, radimo j--
    jmp	    right_loop
end_right_loop:

    mov	    eax, [rdi + r13*4]      # zamenjujemo mesta elementima na pozicijama
    mov	    r15d, [rdi + r14*4]     # i i j
    mov	    [rdi + r13*4], r15d
    mov	    [rdi + r14*4], eax

    jmp	    partition               # vracamo se na particionisanje
end_partition:

    mov	    eax, [rdi + r13*4]      # a[r] = a[i]
    mov	    [rdi + rdx*4], eax
    mov	    [rdi + r13*4], r12d     # a[i] = pivot

                                    # Sortiramo rekurzivno levu i desnu particiju.

quick_sort_left:                    # quick_sort(array,l,i-1)
    push    rdx
    push	r13
    mov	    edx, r13d
    dec	    edx
    call    quick_sort
    pop	    r13
    pop	    rdx

quick_sort_right:                   # quick_sort(array,i+1,r)
    mov	    esi, r13d
    inc	    esi
    call    quick_sort

end_quick_sort:
    xor	    rax, rax
    leave
    ret

