// File: /workspace/github_c_makefile_star2_O0/seojangho[P]clee/simclist.c
// Function: list_sort_quicksort
static void list_sort_quicksort(list_t *restrict l, int versus, 
        unsigned int first, struct list_entry_s *fel,
        unsigned int last, struct list_entry_s *lel) {
    unsigned int pivotid;
    unsigned int i;
    register struct list_entry_s *pivot;
    struct list_entry_s *left, *right;
    void *tmpdata;
#ifdef SIMCLIST_WITH_THREADS
    pthread_t tid;
    int traised;
#endif


    if (last <= first)      /* <= 1-element lists are always sorted */
        return;
    
    if (last - first+1 <= SIMCLIST_MINQUICKSORTELS) {
        list_sort_selectionsort(l, versus, first, fel, last, lel);
        return;
    }
    
    /* base of iteration: one element list */
    if (! (last > first)) return;

    pivotid = (get_random() % (last - first + 1));
    /* pivotid = (last - first + 1) / 2; */

    /* find pivot */
    if (pivotid < (last - first + 1)/2) {
        for (i = 0, pivot = fel; i < pivotid; pivot = pivot->next, i++);
    } else {
        for (i = last - first, pivot = lel; i > pivotid; pivot = pivot->prev, i--);
    }

    /* smaller PIVOT bigger */
    left = fel;
    right = lel;
    /* iterate     --- left ---> PIV <--- right --- */
    while (left != pivot && right != pivot) {
        for (; left != pivot && (l->attrs.comparator(left->data, pivot->data) * -versus <= 0); left = left->next);
        /* left points to a smaller element, or to pivot */
        for (; right != pivot && (l->attrs.comparator(right->data, pivot->data) * -versus >= 0); right = right->prev);
        /* right points to a bigger element, or to pivot */
        if (left != pivot && right != pivot) {
            /* swap, then move iterators */
            tmpdata = left->data;
            left->data = right->data;
            right->data = tmpdata;

            left = left->next;
            right = right->prev;
        }
    }

    /* now either left points to pivot (end run), or right */
    if (right == pivot) {    /* left part longer */
        while (left != pivot) {
            if (l->attrs.comparator(left->data, pivot->data) * -versus > 0) {
                tmpdata = left->data;
                left->data = pivot->prev->data;
                pivot->prev->data = pivot->data;
                pivot->data = tmpdata;
                pivot = pivot->prev;
                pivotid--;
                if (pivot == left) break;
            } else {
                left = left->next;
            }
        }
    } else {                /* right part longer */
        while (right != pivot) {
            if (l->attrs.comparator(right->data, pivot->data) * -versus < 0) {
                /* move current right before pivot */
                tmpdata = right->data;
                right->data = pivot->next->data;
                pivot->next->data = pivot->data;
                pivot->data = tmpdata;
                pivot = pivot->next;
                pivotid++;
                if (pivot == right) break;
            } else {
                right = right->prev;
            }
        }
    }

    /* sort sublists A and B :       |---A---| pivot |---B---| */

#ifdef SIMCLIST_WITH_THREADS
    traised = 0;
    if (pivotid > 0) {
        /* prepare wrapped args, then start thread */
        if (l->threadcount < SIMCLIST_MAXTHREADS-1) {
            struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *)malloc(sizeof(struct list_sort_wrappedparams));
            l->threadcount++;
            traised = 1;
            wp->l = l;
            wp->versus = versus;
            wp->first = first;
            wp->fel = fel;
            wp->last = first+pivotid-1;
            wp->lel = pivot->prev;
            if (pthread_create(&tid, NULL, list_sort_quicksort_threadwrapper, wp) != 0) {
                free(wp);
                traised = 0;
                list_sort_quicksort(l, versus, first, fel, first+pivotid-1, pivot->prev);
            }
        } else {
            list_sort_quicksort(l, versus, first, fel, first+pivotid-1, pivot->prev);
        }
    }
    if (first + pivotid < last) list_sort_quicksort(l, versus, first+pivotid+1, pivot->next, last, lel);
    if (traised) {
        pthread_join(tid, (void **)NULL);
        l->threadcount--;
    }
#else
    if (pivotid > 0) list_sort_quicksort(l, versus, first, fel, first+pivotid-1, pivot->prev);
    if (first + pivotid < last) list_sort_quicksort(l, versus, first+pivotid+1, pivot->next, last, lel);
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movl %r8d, -0x1c(%rbp)
movq %r9, -0x28(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x10(%rbp), %eax
ja 0x583b
jmp 0x5bef
movl -0x1c(%rbp), %eax
subl -0x10(%rbp), %eax
addl $0x1, %eax
cmpl $0x18, %eax
ja 0x5869
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movq -0x18(%rbp), %rcx
movl -0x1c(%rbp), %r8d
movq -0x28(%rbp), %r9
callq 0x73d0
jmp 0x5bef
movl -0x1c(%rbp), %eax
cmpl -0x10(%rbp), %eax
ja 0x5876
jmp 0x5bef
callq 0x3220
movl -0x1c(%rbp), %ecx
subl -0x10(%rbp), %ecx
addl $0x1, %ecx
xorl %edx, %edx
divl %ecx
movl %edx, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movl -0x1c(%rbp), %ecx
subl -0x10(%rbp), %ecx
addl $0x1, %ecx
shrl %ecx
cmpl %ecx, %eax
jae 0x58cf
movl $0x0, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jae 0x58cd
jmp 0x58b6
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x58ac
jmp 0x5903
movl -0x1c(%rbp), %eax
subl -0x10(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x38(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jbe 0x5901
jmp 0x58ea
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
movl -0x30(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x58e0
jmp 0x5903
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rcx
xorl %eax, %eax
cmpq -0x38(%rbp), %rcx
movb %al, -0x51(%rbp)
je 0x5930
movq -0x48(%rbp), %rax
cmpq -0x38(%rbp), %rax
setne %al
movb %al, -0x51(%rbp)
movb -0x51(%rbp), %al
testb $0x1, %al
jne 0x593c
jmp 0x5a37
jmp 0x593e
movq -0x40(%rbp), %rcx
xorl %eax, %eax
cmpq -0x38(%rbp), %rcx
movb %al, -0x52(%rbp)
je 0x5976
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x40(%rbp), %rcx
movq (%rcx), %rdi
movq -0x38(%rbp), %rcx
movq (%rcx), %rsi
callq *%rax
xorl %ecx, %ecx
subl -0xc(%rbp), %ecx
imull %ecx, %eax
cmpl $0x0, %eax
setle %al
movb %al, -0x52(%rbp)
movb -0x52(%rbp), %al
testb $0x1, %al
jne 0x597f
jmp 0x598f
jmp 0x5981
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x593e
jmp 0x5991
movq -0x48(%rbp), %rcx
xorl %eax, %eax
cmpq -0x38(%rbp), %rcx
movb %al, -0x53(%rbp)
je 0x59c9
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x48(%rbp), %rcx
movq (%rcx), %rdi
movq -0x38(%rbp), %rcx
movq (%rcx), %rsi
callq *%rax
xorl %ecx, %ecx
subl -0xc(%rbp), %ecx
imull %ecx, %eax
cmpl $0x0, %eax
setge %al
movb %al, -0x53(%rbp)
movb -0x53(%rbp), %al
testb $0x1, %al
jne 0x59d2
jmp 0x59e2
jmp 0x59d4
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x5991
movq -0x40(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x5a32
movq -0x48(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x5a32
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rax
movq (%rax), %rcx
movq -0x40(%rbp), %rax
movq %rcx, (%rax)
movq -0x50(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, (%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x5913
movq -0x48(%rbp), %rax
cmpq -0x38(%rbp), %rax
jne 0x5aed
jmp 0x5a47
movq -0x40(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x5ae8
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x40(%rbp), %rcx
movq (%rcx), %rdi
movq -0x38(%rbp), %rcx
movq (%rcx), %rsi
callq *%rax
xorl %ecx, %ecx
subl -0xc(%rbp), %ecx
imull %ecx, %eax
cmpl $0x0, %eax
jle 0x5ad7
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rcx
movq -0x40(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq (%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rcx, (%rax)
movq -0x50(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
movl -0x2c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x2c(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x40(%rbp), %rax
jne 0x5ad5
jmp 0x5ae8
jmp 0x5ae3
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x5a47
jmp 0x5b92
jmp 0x5aef
movq -0x48(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x5b90
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x48(%rbp), %rcx
movq (%rcx), %rdi
movq -0x38(%rbp), %rcx
movq (%rcx), %rsi
callq *%rax
xorl %ecx, %ecx
subl -0xc(%rbp), %ecx
imull %ecx, %eax
cmpl $0x0, %eax
jge 0x5b7f
movq -0x48(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rcx
movq -0x48(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq (%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq %rcx, (%rax)
movq -0x50(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x48(%rbp), %rax
jne 0x5b7d
jmp 0x5b90
jmp 0x5b8b
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x5aef
jmp 0x5b92
cmpl $0x0, -0x2c(%rbp)
jbe 0x5bbf
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movq -0x18(%rbp), %rcx
movl -0x10(%rbp), %r8d
addl -0x2c(%rbp), %r8d
subl $0x1, %r8d
movq -0x38(%rbp), %rax
movq 0x10(%rax), %r9
callq 0x5810
movl -0x10(%rbp), %eax
addl -0x2c(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jae 0x5bef
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
addl -0x2c(%rbp), %edx
addl $0x1, %edx
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rcx
movl -0x1c(%rbp), %r8d
movq -0x28(%rbp), %r9
callq 0x5810
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)