// File: /workspace/github_c_makefile_star2_O3/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, %rbx
movl 0xc(%rdi), %r8d
cmpl 0xc(%rsi), %r8d
jne 0xc9ef
movq %rcx, %rax
movq %rsi, %r12
movq %rdi, %r15
movq (%rdi), %rcx
movq 0x10(%rcx), %rdi
movq (%rsi), %rcx
movq 0x10(%rcx), %rbp
movl 0xc0(%rdi), %ecx
movl 0xc0(%rbp), %r14d
cmpl $0x5, %ecx
movq %rdi, 0x8(%rsp)
jl 0xc9b4
movq %rdx, 0x98(%rsp)
movq %rcx, 0xa0(%rsp)
cmpl $0x4, %r14d
jg 0xc91f
leaq 0x18e62(%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 0xef9a
leaq 0x18e3a(%rip), %rax     # 0x25760
cmpl $0x0, 0x18(%rax)
movq 0x8(%rsp), %r13
jne 0xcdf8
movl %r14d, 0x2c(%rsp)
xorl %eax, %eax
leaq 0x28(%rsp), %rbx
movl %eax, (%rbx)
leaq 0x14(%rsp), %r14
movl $0x0, 0x4(%rsp)
movl %eax, (%r14)
leaq 0x20(%rsp), %rsi
movq %r13, %rdi
movq %rbx, %rdx
callq 0xd2e4
leaq 0x18(%rsp), %rsi
movq %rbp, %rdi
movq %r14, %rdx
callq 0xd2e4
leaq 0x18de6(%rip), %r8      # 0x25760
movl (%rbx), %eax
cmpl 0x10(%r13), %eax
jle 0xca8e
movl 0x14(%rsp), %eax
cmpl 0x10(%rbp), %eax
jg 0xcdf8
movq 0xb8(%r8), %rdi
addq $-0x4, %rdi
leaq 0x18(%r8), %rdx
leaq 0x1c(%r8), %rcx
addq $0x28, %r8
movl $0x11, %esi
jmp 0xcdf3
cmpl $0x4, %ecx
je 0xc9e9
cmpl %r14d, %ecx
jne 0xc9e9
addq $0x10, %rdi
movl 0x8(%r15), %esi
incl %esi
addq $0x10, %rbp
movl 0x8(%r12), %ecx
incl %ecx
movq %rbp, %rdx
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmpq *%rax
cmpl $0x5, %r14d
jl 0xca28
leaq 0x18d6a(%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 0xef9a
cmpl $0x4, %ecx
jne 0xccda
cmpl $0x4, %r14d
jne 0xc9ef
testl %r8d, %r8d
jle 0xcdf8
addq $0x10, 0x8(%rsp)
addq $0x10, %rbp
movl $0x1, %r13d
movl 0x8(%r15), %esi
addl %r13d, %esi
movq 0x8(%rsp), %rdi
callq 0x91d8
movq (%rax), %r14
movl 0x8(%r12), %esi
addl %r13d, %esi
movq %rbp, %rdi
callq 0x91d8
movq %r14, %rdi
movq %rax, %rsi
callq *%rbx
leal 0x1(%r13), %eax
cmpl 0xc(%r15), %r13d
movl %eax, %r13d
jl 0xca50
jmp 0xcdf8
leaq 0x18(%r8), %rax
movq %rax, 0x40(%rsp)
leaq 0x1c(%r8), %rax
movq %rax, 0x38(%rsp)
leaq 0x28(%r8), %rax
movq %rax, 0x30(%rsp)
movl $0x0, 0x10(%rsp)
movq %rbp, 0x58(%rsp)
movq %r15, 0x50(%rsp)
movq %r12, 0x48(%rsp)
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 0x14(%rsp), %eax
cmpl 0x10(%rbp), %eax
jle 0xcb20
movq 0xb8(%r8), %rdi
addq $-0x4, %rdi
movl $0x11, %esi
movq 0x40(%rsp), %rdx
movq 0x38(%rsp), %rcx
movq 0x30(%rsp), %r8
callq 0xef9a
leaq 0x18c40(%rip), %r8      # 0x25760
cmpl $0x0, 0x18(%r8)
jne 0xcdf8
movq 0xa0(%rsp), %rax
cmpl 0x2c(%rsp), %eax
jne 0xcb65
movq 0x8(%rsp), %rax
movl 0xc4(%rax), %eax
movq 0x20(%rsp), %r13
movq 0x18(%rsp), %r14
movq 0x58(%rsp), %rcx
cmpl 0xc4(%rcx), %eax
jne 0xcb6f
movl 0xc(%r13), %ebp
movl 0xc(%r14), %ebx
jmp 0xcb9d
movq 0x20(%rsp), %r13
movq 0x18(%rsp), %r14
movl 0xc(%r13), %ecx
movl 0xc(%r14), %eax
testl %ecx, %ecx
je 0xcb8e
movl $0x1, %ebp
movl $0x1, %ebx
testl %eax, %eax
jne 0xcb9d
jmp 0xcdd4
xorl %ebp, %ebp
movl $0x0, %ebx
cmpl %eax, %ecx
jne 0xcdd4
movl 0x44(%r13), %eax
movl $0x2f, %esi
testb $0x2, %al
jne 0xcdd9
testb $0x4, 0x44(%r14)
jne 0xcdd9
orl $0x2, %eax
movl %eax, 0x44(%r13)
orb $0x4, 0x44(%r14)
leaq 0x80(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
movl 0x4(%rsp), %edx
movl %ebp, %ecx
callq 0xd32b
leaq 0x60(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
movl 0x10(%rsp), %edx
movl %ebx, %ecx
callq 0xd32b
leaq 0x18b65(%rip), %r8      # 0x25760
cmpl $0x0, 0x18(%r8)
je 0xcc18
andb $-0x3, 0x44(%r13)
andb $-0x5, 0x44(%r14)
movq 0x50(%rsp), %r15
movq 0x48(%rsp), %r12
jmp 0xcc48
movq %r15, %rdi
movq %r12, %rsi
callq *0x98(%rsp)
leaq 0x18b34(%rip), %r8      # 0x25760
movl 0x18(%r8), %eax
andl $-0x3, 0x44(%r13)
andb $-0x5, 0x44(%r14)
testl %eax, %eax
movq 0x50(%rsp), %r15
movq 0x48(%rsp), %r12
je 0xcc63
movq 0x60(%rsp), %rax
orq 0x80(%rsp), %rax
jne 0xcdf8
movl $0x0, 0x18(%r8)
movl 0x4(%rsp), %eax
addl %ebp, %eax
movl %eax, 0x4(%rsp)
cmpl 0xc(%r13), %eax
movq 0x8(%rsp), %r13
jl 0xcc99
movq %r13, %rdi
leaq 0x20(%rsp), %rsi
leaq 0x28(%rsp), %rdx
callq 0xd2e4
leaq 0x18acf(%rip), %r8      # 0x25760
movl $0x0, 0x4(%rsp)
addl 0x10(%rsp), %ebx
cmpl 0xc(%r14), %ebx
movq 0x58(%rsp), %rbp
jl 0xccc3
movq %rbp, %rdi
leaq 0x18(%rsp), %rsi
leaq 0x14(%rsp), %rdx
callq 0xd2e4
leaq 0x18a9f(%rip), %r8      # 0x25760
xorl %ebx, %ebx
movl 0x28(%rsp), %eax
movl %ebx, 0x10(%rsp)
cmpl 0x10(%r13), %eax
jle 0xcac0
jmp 0xc986
cmpl $0x4, %r14d
je 0xc9ef
leal (%rcx,%rcx,4), %eax
addl %r14d, %eax
cltq
movq (%r9,%rax,8), %r14
movq 0x18(%rdi), %rax
movq %rax, 0x80(%rsp)
movq 0x18(%rbp), %rax
movq %rax, 0x60(%rsp)
xorl %eax, %eax
movl %eax, 0x20(%rsp)
movl %eax, 0x18(%rsp)
testl %r8d, %r8d
jle 0xcdf8
movq 0x8(%rsp), %rdi
addq $0x10, %rdi
addq $0x10, %rbp
movl 0x8(%r15), %ecx
leaq 0x80(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %rdi, 0x8(%rsp)
callq 0x920c
movq %rax, %rbx
movl 0x8(%r12), %ecx
leaq 0x60(%rsp), %rsi
leaq 0x18(%rsp), %rdx
movq %rbp, %r13
movq %rbp, %rdi
callq 0x920c
movq %rbx, %rdi
movq %rax, %rsi
callq *%r14
leaq 0x189f3(%rip), %rbx     # 0x25760
cmpl $0x0, 0x18(%rbx)
jne 0xcdf8
cmpl $0x2, 0xc(%r15)
jl 0xcdf8
movl $0x1, %r12d
movq 0x8(%rsp), %rdi
leaq 0x80(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movl $0x1, %ecx
callq 0x920c
movq %rax, %rbp
movq %r13, %rdi
leaq 0x60(%rsp), %rsi
leaq 0x18(%rsp), %rdx
movl $0x1, %ecx
callq 0x920c
movq %rbp, %rdi
movq %rax, %rsi
callq *%r14
cmpl $0x0, 0x18(%rbx)
jne 0xcdf8
incl %r12d
cmpl 0xc(%r15), %r12d
jl 0xcd84
jmp 0xcdf8
movl $0x11, %esi
movq 0xb8(%r8), %rdi
addq $-0x4, %rdi
movq 0x40(%rsp), %rdx
movq 0x38(%rsp), %rcx
movq 0x30(%rsp), %r8
callq 0xef9a
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq