// File: /workspace/github_c_makefile_star2_O0/heltilda[P]cicada/lnklst.c
// Function: copyElements
ccInt copyElements(linkedlist *sourceList, ccInt sourceBegin, linkedlist *destList, ccInt destBegin, ccInt numberToCopy)
{
    ccInt firstCopied, lastCopied, sourceBottom, destBottom, elementSize;
    sublistHeader *currentSourceSublist, *currentDestSublist;
    
    
        // First, make sure the user is within range.
    
    if ((sourceList->memory == NULL) || (destList->memory == NULL))  return init_err;
    if (sourceList->elementSize != destList->elementSize)  return mismatched_indices_err;
    if (numberToCopy == 0)  return passed;            // put before el-exists-check, since if NTC == 0 we often can't pass a valid element
    if ((!elementExists(sourceList, sourceBegin)) || (!elementExists(destList, destBegin)))  return out_of_range_err;
    if ((!elementExists(sourceList, sourceBegin + numberToCopy - 1)) || (!elementExists(destList, destBegin+numberToCopy-1)))
        return out_of_range_err;
    
    elementSize = sourceList->elementSize;
    
    
        // Now start copying the lists.  If we can do it from lowest to highest without overwriting, that's easiest (first clause of 'if' statement).
        // Either way, we iteratively hop down sublists: updating them, restricting the size of the copied memory block, and copying the memory.
    
    if ((sourceBegin > destBegin) || (sourceBegin+numberToCopy <= destBegin) || (sourceList != destList))
    {
        currentSourceSublist = findSublist(sourceList, sourceBegin, &sourceBottom);
        currentDestSublist = findSublist(destList, destBegin, &destBottom);
        firstCopied = 1;
        lastCopied = numberToCopy - 1;
        while (lastCopied < numberToCopy)
        {
            if (currentSourceSublist->numElements+sourceBottom-1 < sourceBegin+firstCopied-1)   {    //update sublists
                sourceBottom = sourceBottom + currentSourceSublist->numElements;
                currentSourceSublist = currentSourceSublist->nextSublist;       }
            
            if (currentDestSublist->numElements+destBottom-1 < destBegin+firstCopied-1)   {
                destBottom = destBottom + currentDestSublist->numElements;
                currentDestSublist = currentDestSublist->nextSublist;     }
            
            lastCopied = numberToCopy;
            if (sourceBottom+currentSourceSublist->numElements < sourceBegin+lastCopied)      // restrict copy length
                lastCopied = sourceBottom + currentSourceSublist->numElements - sourceBegin;
            if (destBottom+currentDestSublist->numElements < destBegin+lastCopied)
                lastCopied = destBottom + currentDestSublist->numElements - destBegin;

            memmove((void *) (((char *) currentDestSublist) + (firstCopied+destBegin-destBottom-1)*elementSize + sublistHeaderSize),
                    (void *) (((char *) currentSourceSublist) + (firstCopied+sourceBegin-sourceBottom-1)*elementSize + sublistHeaderSize),
                    elementSize*(lastCopied-firstCopied+1));
            
            firstCopied = lastCopied+1;
    }   }
    
    else if (sourceBegin < destBegin)       // No, copy from the top down; otherwise we will overwrite something.
    {
        currentSourceSublist = findSublist(sourceList, sourceBegin+numberToCopy-1, &sourceBottom);
        currentDestSublist = findSublist(destList, destBegin+numberToCopy-1, &destBottom);
        firstCopied = numberToCopy+1;
        lastCopied = numberToCopy;
        
        while(firstCopied > 1)
        {
            firstCopied = 1;          // how much to copy?
            if (sourceBottom > firstCopied+sourceBegin-1)
                firstCopied = sourceBottom - sourceBegin + 1;
            if (destBottom > firstCopied+destBegin-1)
                firstCopied = destBottom - destBegin + 1;
            
                        // here we copy first, then scale the lists
            memmove((void *) ((char *) currentDestSublist + (firstCopied+destBegin-destBottom-1)*elementSize + sublistHeaderSize),
                    (void *) ((char *) currentSourceSublist + (firstCopied+sourceBegin-sourceBottom-1)*elementSize + sublistHeaderSize),
                    elementSize*(lastCopied-firstCopied+1));
            
            lastCopied = firstCopied-1;
            if (firstCopied == sourceBottom-sourceBegin+1)
                currentSourceSublist = findSublist(sourceList, sourceBegin+lastCopied-1, &sourceBottom);
            if (firstCopied == destBottom-destBegin+1)
                currentDestSublist = findSublist(destList, destBegin+lastCopied-1, &destBottom);
    }   }
    
    return passed;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movl %r8d, -0x28(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x8ac0
movq -0x20(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x8acc
movl $0x3, -0x4(%rbp)
jmp 0x8e37
movq -0x10(%rbp), %rax
movl 0x10(%rax), %eax
movq -0x20(%rbp), %rcx
cmpl 0x10(%rcx), %eax
je 0x8ae8
movl $0x4, -0x4(%rbp)
jmp 0x8e37
cmpl $0x0, -0x28(%rbp)
jne 0x8afa
movl $0x0, -0x4(%rbp)
jmp 0x8e37
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x8830
cmpl $0x0, %eax
je 0x8b1c
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x8830
cmpl $0x0, %eax
jne 0x8b28
movl $0x2, -0x4(%rbp)
jmp 0x8e37
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
addl -0x28(%rbp), %esi
subl $0x1, %esi
callq 0x8830
cmpl $0x0, %eax
je 0x8b56
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
addl -0x28(%rbp), %esi
subl $0x1, %esi
callq 0x8830
cmpl $0x0, %eax
jne 0x8b62
movl $0x2, -0x4(%rbp)
jmp 0x8e37
movq -0x10(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x3c(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x24(%rbp), %eax
jg 0x8b8d
movl -0x14(%rbp), %eax
addl -0x28(%rbp), %eax
cmpl -0x24(%rbp), %eax
jle 0x8b8d
movq -0x10(%rbp), %rax
cmpq -0x20(%rbp), %rax
je 0x8ce1
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
leaq -0x34(%rbp), %rdx
callq 0x83f0
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
leaq -0x38(%rbp), %rdx
callq 0x83f0
movq %rax, -0x50(%rbp)
movl $0x1, -0x2c(%rbp)
movl -0x28(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x28(%rbp), %eax
jge 0x8cdc
movq -0x48(%rbp), %rax
movl (%rax), %eax
addl -0x34(%rbp), %eax
subl $0x1, %eax
movl -0x14(%rbp), %ecx
addl -0x2c(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x8c02
movl -0x34(%rbp), %eax
movq -0x48(%rbp), %rcx
addl (%rcx), %eax
movl %eax, -0x34(%rbp)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x50(%rbp), %rax
movl (%rax), %eax
addl -0x38(%rbp), %eax
subl $0x1, %eax
movl -0x24(%rbp), %ecx
addl -0x2c(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x8c33
movl -0x38(%rbp), %eax
movq -0x50(%rbp), %rcx
addl (%rcx), %eax
movl %eax, -0x38(%rbp)
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x34(%rbp), %eax
movq -0x48(%rbp), %rcx
addl (%rcx), %eax
movl -0x14(%rbp), %ecx
addl -0x30(%rbp), %ecx
cmpl %ecx, %eax
jge 0x8c5b
movl -0x34(%rbp), %eax
movq -0x48(%rbp), %rcx
addl (%rcx), %eax
subl -0x14(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x38(%rbp), %eax
movq -0x50(%rbp), %rcx
addl (%rcx), %eax
movl -0x24(%rbp), %ecx
addl -0x30(%rbp), %ecx
cmpl %ecx, %eax
jge 0x8c7d
movl -0x38(%rbp), %eax
movq -0x50(%rbp), %rcx
addl (%rcx), %eax
subl -0x24(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x50(%rbp), %rdi
movl -0x2c(%rbp), %eax
addl -0x24(%rbp), %eax
subl -0x38(%rbp), %eax
subl $0x1, %eax
imull -0x3c(%rbp), %eax
cltq
addq %rax, %rdi
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
movl -0x2c(%rbp), %eax
addl -0x14(%rbp), %eax
subl -0x34(%rbp), %eax
subl $0x1, %eax
imull -0x3c(%rbp), %eax
cltq
addq %rax, %rsi
addq $0x18, %rsi
movl -0x3c(%rbp), %eax
movl -0x30(%rbp), %ecx
subl -0x2c(%rbp), %ecx
addl $0x1, %ecx
imull %ecx, %eax
movslq %eax, %rdx
callq 0x8200
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x8bc5
jmp 0x8e30
movl -0x14(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x8e2e
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
addl -0x28(%rbp), %esi
subl $0x1, %esi
leaq -0x34(%rbp), %rdx
callq 0x83f0
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
addl -0x28(%rbp), %esi
subl $0x1, %esi
leaq -0x38(%rbp), %rdx
callq 0x83f0
movq %rax, -0x50(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x30(%rbp)
cmpl $0x1, -0x2c(%rbp)
jle 0x8e2c
movl $0x1, -0x2c(%rbp)
movl -0x34(%rbp), %eax
movl -0x2c(%rbp), %ecx
addl -0x14(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jle 0x8d5d
movl -0x34(%rbp), %eax
subl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movl -0x38(%rbp), %eax
movl -0x2c(%rbp), %ecx
addl -0x24(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jle 0x8d79
movl -0x38(%rbp), %eax
subl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movq -0x50(%rbp), %rdi
movl -0x2c(%rbp), %eax
addl -0x24(%rbp), %eax
subl -0x38(%rbp), %eax
subl $0x1, %eax
imull -0x3c(%rbp), %eax
cltq
addq %rax, %rdi
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
movl -0x2c(%rbp), %eax
addl -0x14(%rbp), %eax
subl -0x34(%rbp), %eax
subl $0x1, %eax
imull -0x3c(%rbp), %eax
cltq
addq %rax, %rsi
addq $0x18, %rsi
movl -0x3c(%rbp), %eax
movl -0x30(%rbp), %ecx
subl -0x2c(%rbp), %ecx
addl $0x1, %ecx
imull %ecx, %eax
movslq %eax, %rdx
callq 0x8200
movl -0x2c(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
movl -0x2c(%rbp), %eax
movl -0x34(%rbp), %ecx
subl -0x14(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jne 0x8dfd
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
addl -0x30(%rbp), %esi
subl $0x1, %esi
leaq -0x34(%rbp), %rdx
callq 0x83f0
movq %rax, -0x48(%rbp)
movl -0x2c(%rbp), %eax
movl -0x38(%rbp), %ecx
subl -0x24(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jne 0x8e27
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
addl -0x30(%rbp), %esi
subl $0x1, %esi
leaq -0x38(%rbp), %rdx
callq 0x83f0
movq %rax, -0x50(%rbp)
jmp 0x8d30
jmp 0x8e2e
jmp 0x8e30
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq