// File: /workspace/github_c_makefile_star2_O2/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 $0x98, %rsp
movq %r8, %rbx
movl 0xc(%rdi), %r8d
cmpl 0xc(%rsi), %r8d
jne 0xc4a0
movq %rcx, %rax
movq %rsi, %r12
movq %rdi, %r13
movq (%rdi), %rcx
movq 0x10(%rcx), %rsi
movq (%r12), %rcx
movq 0x10(%rcx), %r15
movq %rsi, 0x8(%rsp)
movl 0xc0(%rsi), %ecx
movl 0xc0(%r15), %ebp
cmpl $0x5, %ecx
movq %r15, 0x40(%rsp)
jl 0xc462
cmpl $0x4, %ebp
jg 0xc1fa
leaq 0x18585(%rip), %rax     # 0x24760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
pushq $0x11
popq %rdi
movq %rcx, %rbx
movq %rdx, %r14
callq 0xc7c2
movq %r14, %rdx
movq %rbx, %rcx
leaq 0x1855f(%rip), %rax     # 0x24760
cmpl $0x0, 0x18(%rax)
jne 0xc64e
movq %rdx, 0x88(%rsp)
movq %rcx, 0x90(%rsp)
movl %ebp, 0x4c(%rsp)
leaq 0x34(%rsp), %rdx
andl $0x0, (%rdx)
leaq 0x1c(%rsp), %rbx
andl $0x0, (%rbx)
leaq 0x28(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0xcac8
leaq 0x20(%rsp), %rsi
movq %r15, %rdi
movq %rbx, %rdx
callq 0xcac8
leaq 0x1850b(%rip), %rdx     # 0x24760
movl $0x0, 0x18(%rsp)
leaq 0x70(%rsp), %rbp
movl $0x0, 0x14(%rsp)
movq %r13, 0x38(%rsp)
movl 0x34(%rsp), %eax
movq 0x8(%rsp), %rcx
cmpl 0x10(%rcx), %eax
jg 0xc621
movq 0x10(%r13), %rax
movq %rax, 0x60(%rsp)
movups (%r13), %xmm0
movaps %xmm0, 0x50(%rsp)
movq 0x10(%r12), %rax
movq %rax, 0x80(%rsp)
movups (%r12), %xmm0
movaps %xmm0, 0x70(%rsp)
movl 0x1c(%rsp), %eax
cmpl 0x10(%r15), %eax
jle 0xc2d6
leaq 0x184a4(%rip), %rax     # 0x24760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
pushq $0x11
popq %rdi
callq 0xc7c2
leaq 0x1848a(%rip), %rdx     # 0x24760
cmpl $0x0, 0x18(%rdx)
jne 0xc64e
movq 0x90(%rsp), %rax
cmpl 0x4c(%rsp), %eax
jne 0xc31f
movq 0x8(%rsp), %rax
movl 0xc4(%rax), %eax
movq 0x28(%rsp), %r14
movq 0x20(%rsp), %rbx
movq 0x40(%rsp), %rcx
cmpl 0xc4(%rcx), %eax
jne 0xc329
movl 0xc(%r14), %r15d
movl 0xc(%rbx), %r13d
leaq 0x50(%rsp), %rdi
jmp 0xc35f
movq 0x28(%rsp), %r14
movq 0x20(%rsp), %rbx
movl 0xc(%r14), %ecx
movl 0xc(%rbx), %eax
testl %ecx, %ecx
je 0xc349
pushq $0x1
popq %r13
movl %r13d, %r15d
testl %eax, %eax
leaq 0x50(%rsp), %rdi
jne 0xc35f
jmp 0xc63b
xorl %r15d, %r15d
movl $0x0, %r13d
cmpl %eax, %ecx
leaq 0x50(%rsp), %rdi
jne 0xc63b
movl 0x44(%r14), %eax
testb $0x2, %al
jne 0xc51d
testb $0x4, 0x44(%rbx)
jne 0xc51d
orl $0x2, %eax
movl %eax, 0x44(%r14)
orb $0x4, 0x44(%rbx)
movq %r14, %rsi
movl 0x14(%rsp), %edx
movl %r15d, %ecx
callq 0xcb03
movq %rbp, %rdi
movq %rbx, %rsi
movl 0x18(%rsp), %edx
movl %r13d, %ecx
callq 0xcb03
leaq 0x183b8(%rip), %rdx     # 0x24760
cmpl $0x0, 0x18(%rdx)
je 0xc3b9
andb $-0x3, 0x44(%r14)
andb $-0x5, 0x44(%rbx)
jmp 0xc3df
leaq 0x50(%rsp), %rdi
movq %rbp, %rsi
callq *0x88(%rsp)
leaq 0x18391(%rip), %rdx     # 0x24760
movl 0x18(%rdx), %eax
andl $-0x3, 0x44(%r14)
andb $-0x5, 0x44(%rbx)
testl %eax, %eax
je 0xc3f3
movq 0x70(%rsp), %rax
orq 0x50(%rsp), %rax
jne 0xc64e
andl $0x0, 0x18(%rdx)
movl 0x14(%rsp), %eax
addl %r15d, %eax
movl %eax, 0x14(%rsp)
cmpl 0xc(%r14), %eax
jl 0xc427
movq 0x8(%rsp), %rdi
leaq 0x28(%rsp), %rsi
leaq 0x34(%rsp), %rdx
callq 0xcac8
leaq 0x18341(%rip), %rdx     # 0x24760
movl $0x0, 0x14(%rsp)
addl 0x18(%rsp), %r13d
cmpl 0xc(%rbx), %r13d
movq 0x40(%rsp), %r15
jl 0xc453
movq %r15, %rdi
leaq 0x20(%rsp), %rsi
leaq 0x1c(%rsp), %rdx
callq 0xcac8
leaq 0x18310(%rip), %rdx     # 0x24760
xorl %r13d, %r13d
movl %r13d, 0x18(%rsp)
movq 0x38(%rsp), %r13
jmp 0xc26f
cmpl $0x4, %ecx
je 0xc49b
cmpl %ebp, %ecx
jne 0xc49b
movq 0x8(%rsp), %rdi
addq $0x10, %rdi
movl 0x8(%r13), %esi
incl %esi
addq $0x10, %r15
movl 0x8(%r12), %ecx
incl %ecx
movq %r15, %rdx
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmpq *%rax
cmpl $0x5, %ebp
jl 0xc4cb
leaq 0x182b9(%rip), %rax     # 0x24760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
pushq $0x11
popq %rdi
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xc7c2
cmpl $0x4, %ecx
jne 0xc524
cmpl $0x4, %ebp
jne 0xc4a0
addq $0x10, 0x8(%rsp)
addq $0x10, %r15
pushq $0x1
popq %rbp
cmpl %r8d, %ebp
jg 0xc64e
movl 0x8(%r13), %esi
addl %ebp, %esi
movq 0x8(%rsp), %rdi
callq 0x9088
movq (%rax), %r14
movl 0x8(%r12), %esi
addl %ebp, %esi
movq %r15, %rdi
callq 0x9088
movq %r14, %rdi
movq %rax, %rsi
callq *%rbx
incl %ebp
movl 0xc(%r13), %r8d
jmp 0xc4e2
pushq $0x2f
jmp 0xc63d
cmpl $0x4, %ebp
je 0xc4a0
movq %r13, 0x38(%rsp)
leal (%rcx,%rcx,4), %eax
addl %ebp, %eax
cltq
movq (%r9,%rax,8), %r14
movq 0x8(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x50(%rsp)
movq 0x18(%r15), %rax
movq %rax, 0x70(%rsp)
andl $0x0, 0x28(%rsp)
andl $0x0, 0x20(%rsp)
testl %r8d, %r8d
jle 0xc64e
movq 0x8(%rsp), %rdi
addq $0x10, %rdi
movq 0x40(%rsp), %r15
addq $0x10, %r15
movq 0x38(%rsp), %rax
movl 0x8(%rax), %ecx
leaq 0x50(%rsp), %rsi
leaq 0x28(%rsp), %rdx
movq %rdi, 0x8(%rsp)
callq 0x90c5
movq %rax, %rbx
movl 0x8(%r12), %ecx
leaq 0x70(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %r15, %r13
movq %r15, %rdi
callq 0x90c5
movq %rbx, %rdi
movq %rax, %rsi
callq *%r14
leaq 0x1819e(%rip), %r15     # 0x24760
cmpl $0x0, 0x18(%r15)
jne 0xc64e
pushq $0x1
popq %r12
movl %r12d, %ebx
incl %ebx
movq 0x38(%rsp), %rax
cmpl 0xc(%rax), %ebx
jg 0xc64e
movq 0x8(%rsp), %rdi
leaq 0x50(%rsp), %rsi
leaq 0x28(%rsp), %rdx
movl %r12d, %ecx
callq 0x90c5
movq %rax, %rbp
movq %r13, %rdi
leaq 0x70(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movl %r12d, %ecx
callq 0x90c5
movq %rbp, %rdi
movq %rax, %rsi
callq *%r14
cmpl $0x0, 0x18(%r15)
je 0xc5d4
jmp 0xc64e
movl 0x1c(%rsp), %eax
cmpl 0x10(%r15), %eax
jg 0xc64e
movq 0xb8(%rdx), %rsi
addq $-0x4, %rsi
pushq $0x11
popq %rdi
jmp 0xc649
pushq $0x11
popq %rdi
movq 0xb8(%rdx), %rsi
addq $-0x4, %rsi
callq 0xc7c2
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq