// File: /workspace/github_c_makefile_star2_O1/heltilda[P]cicada/intrpt.c
// Function: doCopyCompare
void doCopyCompare(view *sourceView, view *destView,
        void(*ccComposite)(view *, view *),
        void(*ccData)(linkedlist *, ccInt, linkedlist *, ccInt, ccInt),
        void(*ccString)(window *, member *),
        void(**ccJumpTable)(void *, void *))
{
    variable *sourceVar = sourceView->windowPtr->variable_ptr, *destVar = destView->windowPtr->variable_ptr;
    member *loopSourceMember, *loopDestMember;
    ccInt sourceType = sourceVar->type, destType = destVar->type;
    ccInt sourceMemberNumber, destMemberNumber, indexCounter;
    ccInt sourceOffset, destOffset, sourceWidth, destWidth;
    
    
        // explore composite variables by individually stepping into their members
    
    if (sourceView->width != destView->width)  {  setError(type_mismatch_err, pcCodePtr-1);  return;  }
    
    if (sourceType >= composite_type)  {
        if (destType < composite_type)  setError(type_mismatch_err, pcCodePtr-1);
        if (errCode != passed)  return;
        
        sourceMemberNumber = 0;
        destMemberNumber = 0;
        findNextVisibleMember(sourceVar, &loopSourceMember, &sourceMemberNumber);
        findNextVisibleMember(destVar, &loopDestMember, &destMemberNumber);
        sourceOffset = destOffset = 0;
        
        while (sourceMemberNumber <= sourceVar->mem.members.elementNum)     {
            
            view nextSourceView = *sourceView, nextDestView = *destView;
            
            if (destMemberNumber > destVar->mem.members.elementNum)  setError(type_mismatch_err, pcCodePtr-1);
            if (errCode != passed)  return;
            
            if ((sourceType == destType) && (sourceVar->eventualType == destVar->eventualType))  {
                sourceWidth = loopSourceMember->indices;
                destWidth = loopDestMember->indices;        }
            else  {
                sourceWidth = destWidth = 1;
                if ((loopSourceMember->indices == 0) || (loopDestMember->indices == 0))  {
                    sourceWidth = destWidth = 0;
                    if (loopSourceMember->indices != loopDestMember->indices)  {
                        setError(type_mismatch_err, pcCodePtr-1);
                        return;
            }   }   }
            
            if (isBusy(loopSourceMember, busy_source_copy_flag))  {  setError(self_reference_err, pcCodePtr-1);  return;  }
            if (isBusy(loopDestMember, busy_dest_copy_flag))  {  setError(self_reference_err, pcCodePtr-1);  return;  }
            setBusy(loopSourceMember, busy_source_copy_flag);
            setBusy(loopDestMember, busy_dest_copy_flag);
            
            stepView(&nextSourceView, loopSourceMember, sourceOffset, sourceWidth);
            stepView(&nextDestView, loopDestMember, destOffset, destWidth);
            
            if (errCode == passed)
                ccComposite(&nextSourceView, &nextDestView);
            
            clearBusy(loopSourceMember, busy_source_copy_flag);
            clearBusy(loopDestMember, busy_dest_copy_flag);
            
            if (errCode != passed)  {
                if ((nextSourceView.windowPtr == NULL) && (nextDestView.windowPtr == NULL))  errCode = passed;
                else  return;     }
            
            if (sourceOffset+sourceWidth >= loopSourceMember->indices)  {
                findNextVisibleMember(sourceVar, &loopSourceMember, &sourceMemberNumber);
                sourceOffset = 0;        }
            else  sourceOffset += sourceWidth;
            
            if (destOffset+destWidth >= loopDestMember->indices)  {
                findNextVisibleMember(destVar, &loopDestMember, &destMemberNumber);
                destOffset = 0;          }
            else  destOffset += destWidth;      }
        
        if (destMemberNumber <= destVar->mem.members.elementNum)  setError(type_mismatch_err, pcCodePtr-1);    }
    
    
        // if it's a primitive variable then we handle that here
    
    else    {
    
            // the easiest option is to copy/compare the entire array (if it is one) at once, using linked list routines
        
        if ((sourceType == destType) && (sourceType != string_type))    {
            
            ccData(&(sourceVar->mem.data), sourceView->offset + 1, &(destVar->mem.data), destView->offset + 1, sourceView->width);   }
        
        else if (destType >= composite_type)  setError(type_mismatch_err, pcCodePtr-1);
        
        else   {
        
                // strings are special and we have to copy/compare each one individually
            
            if (sourceType == string_type)  {
                if (destType != string_type)  setError(type_mismatch_err, pcCodePtr-1);
                else for (indexCounter = 1; indexCounter <= sourceView->width; indexCounter++)  {
                    ccString(LL_member(sourceVar, sourceView->offset + indexCounter)->memberWindow,
                            LL_member(destVar, destView->offset + indexCounter));
            }   }
            
            
                // finally, if we have mismatched but compatible types (think composite variables having ints versus doubles),
                // then we have to step through them member by member
            
            else   {
                if (destType == string_type)  setError(type_mismatch_err, pcCodePtr-1);
                else {
                    void(*ccFunction)(void *, void *) = ccJumpTable[5*sourceVar->type + destVar->type];
                    linkedlist *sourceLL = &(sourceVar->mem.data), *destLL = &(destVar->mem.data);
                    sublistHeader *sourceLLsublist = sourceLL->memory, *destLLsublist = destLL->memory;
                    ccInt sourceSublistLocalIndex = 0, destSublistLocalIndex = 0;
                    
                    if (sourceView->width > 0)  {       // skipElements() will crash if sourceLL or destLL has 0 elements
                        ccFunction( skipElements(sourceLL, &sourceLLsublist, &sourceSublistLocalIndex, sourceView->offset),
                                    skipElements(destLL, &destLLsublist, &destSublistLocalIndex, destView->offset));
                        if (errCode == passed)  {
                        for (indexCounter = 2; indexCounter <= sourceView->width; indexCounter++)  {
                            ccFunction( skipElements(sourceLL, &sourceLLsublist, &sourceSublistLocalIndex, 1),
                                        skipElements(destLL, &destLLsublist, &destSublistLocalIndex, 1)  );
                            if (errCode != passed)  break;
        }   }   }   }   }}
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %r8, %r13
movl 0xc(%rdi), %r8d
cmpl 0xc(%rsi), %r8d
jne 0xcaf3
movq %rcx, %rax
movq %rsi, %r12
movq %rdi, %r15
movq %rdx, 0x98(%rsp)
movq (%rdi), %rcx
movq 0x10(%rcx), %rbx
movq (%rsi), %rcx
movq 0x10(%rcx), %rcx
movl 0xc0(%rbx), %edx
movq %rcx, 0x8(%rsp)
movl 0xc0(%rcx), %r14d
cmpl $0x5, %edx
jl 0xcaaf
movq %rdx, 0xa0(%rsp)
cmpl $0x4, %r14d
jg 0xca8b
leaq 0x18cf6(%rip), %r8      # 0x25760
movq 0xb8(%r8), %rdi
addq $-0x4, %rdi
leaq 0x18(%r8), %rdx
leaq 0x1c(%r8), %rcx
addq $0x28, %r8
movl $0x11, %esi
callq 0xf1d9
leaq 0x18cce(%rip), %r13     # 0x25760
cmpl $0x0, 0x18(%r13)
je 0xcb2c
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x4, %edx
je 0xcae9
cmpl %r14d, %edx
jne 0xcae9
addq $0x10, %rbx
movl 0x8(%r15), %esi
incl %esi
movq 0x8(%rsp), %rdx
addq $0x10, %rdx
movl 0x8(%r12), %ecx
incl %ecx
movq %rbx, %rdi
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmpq *%rax
cmpl $0x5, %r14d
jl 0xce4e
leaq 0x18c66(%rip), %r8      # 0x25760
movq 0xb8(%r8), %rdi
addq $-0x4, %rdi
leaq 0x18(%r8), %rdx
leaq 0x1c(%r8), %rcx
addq $0x28, %r8
movl $0x11, %esi
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xf1d9
xorl %eax, %eax
leaq 0x58(%rsp), %rdx
movl %eax, (%rdx)
leaq 0x3c(%rsp), %rbp
movl $0x0, 0x18(%rsp)
movl %eax, (%rbp)
leaq 0x30(%rsp), %rsi
movq %rbx, %rdi
callq 0xd4ea
leaq 0x20(%rsp), %rsi
movq 0x8(%rsp), %rdi
movq %rbp, %rdx
callq 0xd4ea
leaq 0x18(%r13), %rax
movq %rax, 0x50(%rsp)
leaq 0x1c(%r13), %rax
movq %rax, 0x48(%rsp)
leaq 0x28(%r13), %rax
movq %rax, 0x40(%rsp)
movl $0x0, 0x14(%rsp)
movq %rbx, 0x28(%rsp)
movl %r14d, 0x1c(%rsp)
movl 0x58(%rsp), %eax
cmpl 0x10(%rbx), %eax
jg 0xcec4
movq 0x10(%r15), %rax
movq %rax, 0x90(%rsp)
movups (%r15), %xmm0
movaps %xmm0, 0x80(%rsp)
movq 0x10(%r12), %rax
movq %rax, 0x70(%rsp)
movups (%r12), %xmm0
movaps %xmm0, 0x60(%rsp)
movl 0x3c(%rsp), %eax
movq 0x8(%rsp), %rcx
cmpl 0x10(%rcx), %eax
jle 0xcbfc
movq 0xb8(%r13), %rdi
addq $-0x4, %rdi
movl $0x11, %esi
movq 0x50(%rsp), %rdx
movq 0x48(%rsp), %rcx
movq 0x40(%rsp), %r8
callq 0xf1d9
cmpl $0x0, 0x18(%r13)
je 0xcc0a
xorl %ebp, %ebp
jmp 0xce2b
cmpl %r14d, 0xa0(%rsp)
jne 0xcc3a
movl 0xc4(%rbx), %eax
movq 0x8(%rsp), %rcx
cmpl 0xc4(%rcx), %eax
jne 0xcc3a
movq 0x30(%rsp), %rax
movl 0xc(%rax), %ebp
movq 0x20(%rsp), %rax
movl 0xc(%rax), %r13d
jmp 0xcc72
movq 0x30(%rsp), %rax
movl 0xc(%rax), %eax
testl %eax, %eax
je 0xcc5c
movq 0x20(%rsp), %rcx
movl $0x1, %ebp
cmpl $0x0, 0xc(%rcx)
movl $0x1, %r13d
jne 0xcc72
movq 0x20(%rsp), %rcx
xorl %ebp, %ebp
movl $0x0, %r13d
cmpl 0xc(%rcx), %eax
jne 0xcdc4
movq 0x30(%rsp), %r14
movl 0x44(%r14), %eax
testb $0x2, %al
jne 0xcd95
movq 0x20(%rsp), %rbx
testb $0x4, 0x44(%rbx)
jne 0xcdf4
orl $0x2, %eax
movl %eax, 0x44(%r14)
orb $0x4, 0x44(%rbx)
leaq 0x80(%rsp), %rdi
movq %r14, %rsi
movl 0x14(%rsp), %edx
movl %ebp, %ecx
callq 0xd531
leaq 0x60(%rsp), %rdi
movq %rbx, %rsi
movl 0x18(%rsp), %edx
movl %r13d, 0x5c(%rsp)
movl %r13d, %ecx
callq 0xd531
leaq 0x18a8d(%rip), %r13     # 0x25760
cmpl $0x0, 0x18(%r13)
jne 0xccee
leaq 0x80(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq *0x98(%rsp)
andb $-0x3, 0x44(%r14)
andb $-0x5, 0x44(%rbx)
cmpl $0x0, 0x18(%r13)
movl 0x5c(%rsp), %r13d
je 0xcd24
movq 0x60(%rsp), %rax
orq 0x80(%rsp), %rax
jne 0xce39
leaq 0x18a43(%rip), %rax     # 0x25760
movl $0x0, 0x18(%rax)
movl 0x14(%rsp), %eax
addl %ebp, %eax
movl %eax, 0x14(%rsp)
cmpl 0xc(%r14), %eax
jl 0xcd50
movq 0x28(%rsp), %rdi
leaq 0x30(%rsp), %rsi
leaq 0x58(%rsp), %rdx
callq 0xd4ea
movl $0x0, 0x14(%rsp)
movl 0x18(%rsp), %eax
addl %r13d, %eax
movb $0x1, %bpl
movl %eax, 0x18(%rsp)
cmpl 0xc(%rbx), %eax
movl 0x1c(%rsp), %r14d
leaq 0x189f3(%rip), %r13     # 0x25760
jl 0xcd8b
movq 0x8(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0x3c(%rsp), %rdx
callq 0xd4ea
movl $0x0, 0x18(%rsp)
movq 0x28(%rsp), %rbx
jmp 0xce2b
leaq 0x189c4(%rip), %r13     # 0x25760
movq 0xb8(%r13), %rdi
addq $-0x4, %rdi
movl $0x2f, %esi
movq 0x50(%rsp), %rdx
movq 0x48(%rsp), %rcx
movq 0x40(%rsp), %r8
callq 0xf1d9
xorl %ebp, %ebp
jmp 0xce26
leaq 0x18995(%rip), %r13     # 0x25760
movq 0xb8(%r13), %rdi
addq $-0x4, %rdi
movl $0x11, %esi
movq 0x50(%rsp), %rdx
movq 0x48(%rsp), %rcx
movq 0x40(%rsp), %r8
callq 0xf1d9
jmp 0xcc03
leaq 0x18965(%rip), %r13     # 0x25760
movq 0xb8(%r13), %rdi
addq $-0x4, %rdi
movl $0x2f, %esi
movq 0x50(%rsp), %rdx
movq 0x48(%rsp), %rcx
movq 0x40(%rsp), %r8
callq 0xf1d9
xorl %ebp, %ebp
movq 0x28(%rsp), %rbx
movl 0x1c(%rsp), %r14d
testb %bpl, %bpl
jne 0xcb91
jmp 0xca9d
xorl %ebp, %ebp
movq 0x28(%rsp), %rbx
movl 0x1c(%rsp), %r14d
leaq 0x18914(%rip), %r13     # 0x25760
jmp 0xce2b
movq %rdx, %rax
cmpl $0x4, %eax
jne 0xceff
cmpl $0x4, %r14d
jne 0xcaf3
cmpl $0x0, 0xc(%r15)
jle 0xca9d
addq $0x10, %rbx
addq $0x10, 0x8(%rsp)
movl $0x1, %r14d
movl 0x8(%r15), %esi
addl %r14d, %esi
movq %rbx, %rdi
callq 0x911c
movq %rbx, %rbp
movq (%rax), %rbx
movl 0x8(%r12), %esi
addl %r14d, %esi
movq 0x8(%rsp), %rdi
callq 0x911c
movq %rbx, %rdi
movq %rbp, %rbx
movq %rax, %rsi
callq *%r13
leal 0x1(%r14), %eax
cmpl 0xc(%r15), %r14d
movl %eax, %r14d
jl 0xce7f
jmp 0xca9d
movl 0x3c(%rsp), %eax
movq 0x8(%rsp), %rcx
cmpl 0x10(%rcx), %eax
jg 0xca9d
movq 0xb8(%r13), %rdi
addq $-0x4, %rdi
movl $0x11, %esi
movq 0x50(%rsp), %rdx
movq 0x48(%rsp), %rcx
movq 0x40(%rsp), %r8
callq 0xf1d9
jmp 0xca9d
cmpl $0x4, %r14d
je 0xcaf3
leal (%rax,%rax,4), %eax
addl %r14d, %eax
cltq
movq (%r9,%rax,8), %r14
movq 0x18(%rbx), %rax
movq %rax, 0x80(%rsp)
movq 0x8(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x60(%rsp)
xorl %eax, %eax
movl %eax, 0x30(%rsp)
movl %eax, 0x20(%rsp)
testl %r8d, %r8d
jle 0xca9d
movq %rbx, %rdi
addq $0x10, %rdi
movq 0x8(%rsp), %rbp
addq $0x10, %rbp
movl 0x8(%r15), %ecx
leaq 0x80(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq %rdi, 0x28(%rsp)
callq 0x9150
movq %rax, %rbx
movl 0x8(%r12), %ecx
leaq 0x60(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %rbp, %r13
movq %rbp, %rdi
callq 0x9150
movq %rbx, %rdi
movq %rax, %rsi
callq *%r14
leaq 0x187c6(%rip), %rbx     # 0x25760
cmpl $0x0, 0x18(%rbx)
jne 0xca9d
cmpl $0x2, 0xc(%r15)
jl 0xca9d
movl $0x1, %r12d
movq 0x28(%rsp), %rdi
leaq 0x80(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movl $0x1, %ecx
callq 0x9150
movq %rax, %rbp
movq %r13, %rdi
leaq 0x60(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movl $0x1, %ecx
callq 0x9150
movq %rbp, %rdi
movq %rax, %rsi
callq *%r14
cmpl $0x0, 0x18(%rbx)
jne 0xca9d
incl %r12d
cmpl 0xc(%r15), %r12d
jl 0xcfb5
jmp 0xca9d