// File: /workspace/github_c_makefile_star2_O2/vtereshkov[P]umka-lang/src/umka_expr.c
// Function: doImplicitTypeConvEx
static void doImplicitTypeConvEx(Compiler *comp, const Type *dest, const Type **src, Const *constant, bool lhs, bool rhs)
{
    // lhs/rhs can only be set to true for operands of binary operators

    // Signed to 64-bit unsigned integer or vice versa (64-bit overflow check only, not applied to operands of binary operators)
    if (!lhs && !rhs && ((dest->kind == TYPE_UINT && typeKindSigned((*src)->kind)) || (typeKindSigned(dest->kind) && (*src)->kind == TYPE_UINT)))
    {
        doOrdinalToOrdinalOrRealToRealConv(comp, dest, src, constant);
    }

    // Integer to real
    else if (typeReal(dest) && typeInteger(*src))
    {
        doIntToRealConv(comp, dest, src, constant, lhs);
    }

    // Character to string
    else if (dest->kind == TYPE_STR && (*src)->kind == TYPE_CHAR)
    {
        doCharToStrConv(comp, dest, src, constant, lhs);
    }

    // Dynamic array to string
    else if (dest->kind == TYPE_STR && (*src)->kind == TYPE_DYNARRAY && (*src)->base->kind == TYPE_CHAR)
    {
        doDynArrayToStrConv(comp, dest, src, constant, lhs);
    }

    // String to dynamic array (not applied to operands of binary operators)
    else if (!lhs && !rhs && dest->kind == TYPE_DYNARRAY && dest->base->kind == TYPE_CHAR && (*src)->kind == TYPE_STR)
    {
        doStrToDynArrayConv(comp, dest, src, constant);
    }

    // Dynamic array to array
    else if (dest->kind == TYPE_ARRAY && (*src)->kind == TYPE_DYNARRAY && typeEquivalent(dest->base, (*src)->base))
    {
        doDynArrayToArrayConv(comp, dest, src, constant, lhs);
    }

    // Array to dynamic array (not applied to operands of binary operators)
    else if (!lhs && !rhs && dest->kind == TYPE_DYNARRAY && (*src)->kind == TYPE_ARRAY && typeEquivalent(dest->base, (*src)->base))
    {
        doArrayToDynArrayConv(comp, dest, src, constant);
    }

    // Concrete to interface or interface to interface
    else if (dest->kind == TYPE_INTERFACE)
    {
        if ((*src)->kind == TYPE_INTERFACE)
        {
            // Interface to interface
            if (!typeEquivalent(dest, *src))
                doInterfaceToInterfaceConv(comp, dest, src, constant);
        }
        else if ((*src)->kind == TYPE_PTR)
        {
            // Pointer to interface
            if ((*src)->base->kind == TYPE_PTR)
                comp->error.handler(comp->error.context, "Pointer base type cannot be a pointer");

            doPtrToInterfaceConv(comp, dest, src, constant);
        }
        else if ((*src)->kind != TYPE_VOID)
        {
            // Value to interface
            doValueToInterfaceConv(comp, dest, src, constant);
        }
    }

    // Pointer to pointer
    else if (dest->kind == TYPE_PTR && (*src)->kind == TYPE_PTR && typeImplicitlyConvertibleBaseTypes(dest->base, (*src)->base))
    {
        *src = dest;
    }

    // Pointer to weak pointer (not applied to operands of binary operators)
    else if (!lhs && !rhs && dest->kind == TYPE_WEAKPTR && (*src)->kind == TYPE_PTR && (typeEquivalent(dest->base, (*src)->base) || (*src)->base->kind == TYPE_NULL))
    {
        doPtrToWeakPtrConv(comp, dest, src, constant);
    }

    // Weak pointer to pointer
    else if (dest->kind == TYPE_PTR && (*src)->kind == TYPE_WEAKPTR && (typeEquivalent(dest->base, (*src)->base) || dest->base->kind == TYPE_NULL))
    {
        doWeakPtrToPtrConv(comp, dest, src, constant, lhs);
    }

    // Function to closure
    else if (dest->kind == TYPE_CLOSURE && (*src)->kind == TYPE_FN && typeEquivalent(dest->field[0]->type, *src))
    {
        doFnToClosureConv(comp, dest, src, constant);
    }

    // Expression list to expression list (not applied to operands of binary operators)
    else if (!lhs && !rhs && typeExprListStruct(dest) && typeExprListStruct(*src) && !typeEquivalent(dest, *src) && dest->numItems == (*src)->numItems)
    {
        doExprListToExprListConv(comp, dest, src, constant);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
movl %r9d, %r13d
movl %r8d, %ebp
movq %rcx, %r12
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %r14
orl %r8d, %r13d
movl (%rsi), %eax
je 0x8deb
movl %eax, %ecx
andl $-0x2, %ecx
cmpl $0xe, %ecx
jne 0x8e02
movq (%r15), %rdx
movl (%rdx), %ecx
leal -0x4(%rcx), %esi
cmpl $0x7, %esi
ja 0x901b
cmpb $0x0, 0x16(%rdx)
jne 0x901b
movzbl %bpl, %r8d
orl $0x6, %r8d
testq %r12, %r12
je 0x8fa6
addq $0x4e68, %r14           # imm = 0x4E68
movq %r14, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x6aed
jmp 0x976d
cmpl $0xb, %eax
jne 0x8e5a
movq (%r15), %rax
movl (%rax), %eax
andl $-0x4, %eax
cmpl $0x4, %eax
je 0x8e74
jmp 0x94f3
cmpl $0x14, %eax
jne 0x8e96
movq (%r15), %rsi
movl (%rsi), %ecx
pushq $0x14
popq %rax
cmpl $0x13, %ecx
je 0x8f73
cmpl $0xd, %ecx
jne 0x901b
testq %r12, %r12
je 0x8fbf
addq $0xf0, %r14
cmpq $0x0, (%r12)
je 0x9006
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x41e7
movb (%r12), %cl
movb %cl, (%rax)
movb $0x0, 0x1(%rax)
jmp 0x9010
movl %eax, %ecx
andl $-0x4, %ecx
cmpl $0x4, %ecx
jne 0x8d9c
movq (%r15), %rcx
cmpl $0xb, (%rcx)
jne 0x8d9c
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
movq %r12, %rcx
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9cfb
cmpl $0x13, %eax
setne %cl
orb %r13b, %cl
je 0x8f38
cmpl $0x12, %eax
jne 0x901b
movq (%r15), %rax
cmpl $0x13, (%rax)
jne 0x9001
movq 0x8(%rbx), %rdi
movq 0x8(%rax), %rsi
callq 0x15262
testb %al, %al
je 0x9019
testq %r12, %r12
je 0x8eeb
movq 0x5118(%r14), %rdi
leaq 0x61947(%rip), %rsi     # 0x6a829
xorl %eax, %eax
callq *0x50f8(%r14)
testb %bpl, %bpl
je 0x8efc
leaq 0x4e70(%r14), %rdi
callq 0xeddd
leaq 0x4e38(%r14), %rdi
leaq 0x4e18(%r14), %rsi
leaq 0x4220(%r14), %rdx
movq %rbx, %rcx
callq 0x10996
leaq 0x4e70(%r14), %r12
movq %r12, %rdi
movl %eax, %esi
callq 0xeb38
pushq $0x19
popq %rdx
movq %r12, %rdi
movq %rbx, %rsi
jmp 0x8fe0
movq 0x8(%rbx), %rax
cmpl $0xd, (%rax)
jne 0x9026
movq (%r15), %rax
cmpl $0x14, (%rax)
jne 0x9026
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
movq %r12, %rcx
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9eb9
movq 0x8(%rsi), %rcx
cmpl $0xd, (%rcx)
jne 0x901b
movzbl %bpl, %r8d
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
movq %r12, %rcx
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9e3f
addq $0x4e70, %r14           # imm = 0x4E70
movq %r14, %rdi
movl %ecx, %esi
movl %r8d, %edx
callq 0xf72f
jmp 0x976d
testb %bpl, %bpl
je 0x8fd3
leaq 0x4e70(%r14), %rdi
callq 0xeddd
movq (%r15), %rsi
leaq 0x4e70(%r14), %r12
pushq $0x1a
popq %rdx
movq %r12, %rdi
callq 0xf8f6
movq %r14, %rdi
movq %rbx, %rsi
callq 0x8cb9
testb %bpl, %bpl
je 0x976d
movq %r12, %rdi
jmp 0x93a8
pushq $0x12
popq %rax
jmp 0x901b
movq %r14, %rdi
xorl %esi, %esi
callq 0x41e7
movq %rax, (%r12)
jmp 0x976d
movl (%rbx), %eax
cmpl $0x13, %eax
setne %cl
orb %r13b, %cl
jne 0x9098
movq (%r15), %rax
cmpl $0x12, (%rax)
jne 0x94ea
movq 0x8(%rbx), %rdi
movq 0x8(%rax), %rsi
callq 0x15262
testb %al, %al
je 0x9096
testq %r12, %r12
je 0x9673
addq $0xf0, %r14
movq (%r15), %rax
movslq 0x10(%rax), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x4213
movq %rbx, %r14
movq %r15, %rbx
movq %rax, %r15
movq 0x10(%rax), %rdi
movq (%r12), %rsi
movq (%rbx), %rax
movslq 0x10(%rax), %rdx
imulq 0x8(%r15), %rdx
callq 0x3260
movq %r15, (%r12)
movq %rbx, %r15
movq %r14, %rbx
jmp 0x976d
movl (%rbx), %eax
cmpl $0x10, %eax
je 0x9314
cmpl $0x17, %eax
jne 0x93b2
movq (%r15), %rdx
movl (%rdx), %eax
cmpl $0x2, %eax
je 0x9770
cmpl $0x10, %eax
je 0x96d0
cmpl $0x17, %eax
jne 0x96f2
movq %rbx, %rdi
movq %rdx, %rsi
callq 0x15262
testb %al, %al
jne 0x9770
testq %r12, %r12
je 0x90f9
movq 0x5118(%r14), %rdi
leaq 0x61774(%rip), %rsi     # 0x6a864
xorl %eax, %eax
callq *0x50f8(%r14)
leaq 0x4e38(%r14), %rdi
leaq 0x4e18(%r14), %r13
leaq 0x4220(%r14), %rdx
movq %r13, %rsi
movq %rbx, %rcx
callq 0x10996
movl %eax, %r12d
movq %r14, 0x20(%rsp)
addq $0x4e70, %r14           # imm = 0x4E70
movq %r14, %rdi
callq 0xedd1
pushq $0x10
popq %rbp
movq %r14, %rdi
movl %ebp, %esi
callq 0xee17
movq %r14, %rdi
movl %r12d, %esi
callq 0xeb38
movq %r14, %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0xeee9
leaq 0x5d27b(%rip), %rdx     # 0x663d6
movq %r13, %rdi
movq %rbx, %rsi
xorl %ecx, %ecx
callq 0x159b0
movq %rax, %r13
movq %r14, %rdi
callq 0xedd1
movl 0x110(%r13), %esi
movq %r14, %rdi
callq 0xf4db
movq %r14, %rdi
movl %ebp, %esi
callq 0xee17
movl %r12d, 0x8(%rsp)
addl 0x110(%r13), %r12d
movq %r14, %rdi
movl %r12d, %esi
callq 0xeb38
movq %r14, 0x28(%rsp)
movq %r14, %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0xeee9
pushq $0x2
popq %r14
movslq 0x10(%rbx), %rax
cmpq %rax, %r14
jge 0x9754
movq 0x28(%rbx), %rax
movq (%rax,%r14,8), %rbp
movq (%r15), %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x1590a
movq %rax, %r13
testq %rax, %rax
jne 0x9240
movq 0x20(%rsp), %rax
movq 0x50f8(%rax), %rcx
movq %rcx, 0x18(%rsp)
movq 0x5118(%rax), %rax
movq %rax, 0x10(%rsp)
movq (%r15), %rdi
leaq 0x30(%rsp), %rsi
callq 0x15180
movq %rbx, %r12
movq %rax, %rbx
movq %r12, %rdi
leaq 0x130(%rsp), %rsi
callq 0x15180
movq 0x10(%rsp), %rdi
leaq 0x61675(%rip), %rsi     # 0x6a8a3
movq %rbx, %rdx
movq %r12, %rbx
movq %rax, %rcx
movq %rbp, %r8
xorl %eax, %eax
callq *0x18(%rsp)
movq 0x28(%rbx), %rax
movq (%rax,%r14,8), %rax
movq 0x108(%rax), %rdi
movq 0x108(%r13), %rsi
callq 0x155ab
testb %al, %al
jne 0x92bd
movq 0x20(%rsp), %rax
movq 0x50f8(%rax), %rcx
movq %rcx, 0x18(%rsp)
movq 0x5118(%rax), %rax
movq %rax, 0x10(%rsp)
movq (%r15), %rdi
leaq 0x30(%rsp), %rsi
callq 0x15180
movq %r15, %r12
movq %rax, %r15
movq %rbx, %rdi
leaq 0x130(%rsp), %rsi
callq 0x15180
movq 0x10(%rsp), %rdi
leaq 0x6162e(%rip), %rsi     # 0x6a8d9
movq %r15, %rdx
movq %r12, %r15
movq %rax, %rcx
movq %rbp, %r8
xorl %eax, %eax
callq *0x18(%rsp)
movq 0x28(%rsp), %r12
movq %r12, %rdi
callq 0xedd1
movl 0x110(%r13), %esi
movq %r12, %rdi
callq 0xf4db
movq %r12, %rdi
pushq $0x1a
popq %rbp
movl %ebp, %esi
callq 0xee17
movq 0x28(%rbx), %rax
movq (%rax,%r14,8), %rax
movl 0x110(%rax), %esi
addl 0x8(%rsp), %esi
movq %r12, %rdi
callq 0xeb38
movq %r12, %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0xeee9
incq %r14
jmp 0x91b8
movq (%r15), %rax
cmpl $0x10, (%rax)
jne 0x9336
movq 0x8(%rbx), %rcx
cmpl $0x2, (%rcx)
je 0x976d
movq 0x8(%rax), %rax
cmpl $0x3, (%rax)
je 0x976d
movq (%r15), %rax
cmpl $0x11, (%rax)
jne 0x94ea
movq 0x8(%rbx), %rdi
movq 0x8(%rax), %rsi
callq 0x15262
testb %al, %al
jne 0x9360
movq 0x8(%rbx), %rax
cmpl $0x3, (%rax)
jne 0x9782
testq %r12, %r12
je 0x937c
movq 0x5118(%r14), %rdi
leaq 0x615e6(%rip), %rsi     # 0x6a959
xorl %eax, %eax
callq *0x50f8(%r14)
testb %bpl, %bpl
je 0x938d
leaq 0x4e70(%r14), %rdi
callq 0xeddd
addq $0x4e70, %r14           # imm = 0x4E70
movq %r14, %rdi
callq 0xf5a3
testb %bpl, %bpl
je 0x976d
movq %r14, %rdi
callq 0xeddd
jmp 0x976d
cmpl $0x11, %eax
setne %cl
orb %r13b, %cl
je 0x9491
cmpl $0x18, %eax
jne 0x94ea
movq (%r15), %rsi
cmpl $0x1a, (%rsi)
jne 0x94ea
movq 0x28(%rbx), %rax
movq (%rax), %rax
movq 0x108(%rax), %rdi
callq 0x15262
testb %al, %al
je 0x94ea
movq %r14, %r13
movq %rbx, %r14
testq %r12, %r12
je 0x9413
movq 0x5118(%r13), %rdi
leaq 0x61593(%rip), %rsi     # 0x6a99d
xorl %eax, %eax
callq *0x50f8(%r13)
leaq 0x4e38(%r13), %rdi
leaq 0x4e18(%r13), %rbx
leaq 0x4220(%r13), %rdx
movq %rbx, %rsi
movq %r14, %rcx
callq 0x10996
movl %eax, %ebp
addq $0x4e70, %r13           # imm = 0x4E70
movq %r13, %rdi
movl %eax, %esi
callq 0xeb38
movq %rbx, %rdi
movq %r14, %rsi
callq 0x15124
movq %r13, %rdi
movl %eax, %esi
callq 0xede9
movq 0x28(%r14), %rax
movq (%rax), %rax
movl 0x110(%rax), %esi
addl %ebp, %esi
movq %r13, %rdi
callq 0xeb38
pushq $0x1a
popq %rsi
movq %r13, %rdi
xorl %edx, %edx
callq 0xeee9
movq %r13, %rdi
movl %ebp, %esi
callq 0xeb38
movq %r14, (%r15)
jmp 0x9770
movq (%r15), %rax
cmpl $0x10, (%rax)
jne 0x94ea
movq 0x8(%rbx), %rdi
movq 0x8(%rax), %rsi
callq 0x15262
testb %al, %al
jne 0x94ba
movq (%r15), %rax
movq 0x8(%rax), %rax
cmpl $0x3, (%rax)
jne 0x9789
testq %r12, %r12
je 0x94d6
movq 0x5118(%r14), %rdi
leaq 0x6144a(%rip), %rsi     # 0x6a917
xorl %eax, %eax
callq *0x50f8(%r14)
addq $0x4e70, %r14           # imm = 0x4E70
movq %r14, %rdi
callq 0xf597
jmp 0x976d
testb %r13b, %r13b
jne 0x9770
cmpl $0x16, (%rbx)
jne 0x9770
cmpb $0x1, 0x14(%rbx)
jne 0x9770
cmpl $0x0, 0x10(%rbx)
jle 0x9770
movq (%r15), %rsi
cmpl $0x16, (%rsi)
jne 0x9770
cmpb $0x1, 0x14(%rsi)
jne 0x9770
cmpl $0x0, 0x10(%rsi)
jle 0x9770
movq %rbx, %rdi
callq 0x15262
testb %al, %al
jne 0x9770
movl 0x10(%rbx), %eax
movq (%r15), %rcx
cmpl 0x10(%rcx), %eax
jne 0x9770
movq %r14, %rbp
movq %rbx, %r14
testq %r12, %r12
je 0x9570
movq 0x5118(%rbp), %rdi
leaq 0x61472(%rip), %rsi     # 0x6a9da
xorl %eax, %eax
callq *0x50f8(%rbp)
leaq 0x4e38(%rbp), %rdi
leaq 0x4e18(%rbp), %rsi
leaq 0x100(%rbp), %rdx
leaq 0x4220(%rbp), %rcx
xorl %ebx, %ebx
movq %r14, %r8
xorl %r9d, %r9d
callq 0x10abb
movq %rbp, %rdi
movq %rax, 0x8(%rsp)
movq %rax, %rsi
callq 0x124c6
movq %rbp, %r13
addq $0x4e70, %rbp           # imm = 0x4E70
movslq 0x10(%r14), %rax
cmpq %rax, %rbx
jge 0x9799
movq %rbp, %rdi
callq 0xedd1
movq (%r15), %rax
movq 0x28(%rax), %rax
movq (%rax,%rbx,8), %rax
movl 0x110(%rax), %esi
movq %rbp, %rdi
callq 0xf4db
movq (%r15), %rax
movq 0x28(%rax), %rax
movq (%rax,%rbx,8), %rax
movq 0x108(%rax), %rax
movl (%rax), %esi
movq %rbp, %rdi
callq 0xee17
movq (%r15), %rax
movq 0x28(%rax), %rax
movq (%rax,%rbx,8), %rax
movq 0x108(%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x28(%r14), %rax
movq (%rax,%rbx,8), %rax
movq 0x108(%rax), %rsi
movq %r13, %rdi
leaq 0x30(%rsp), %rdx
movq %r12, %rcx
callq 0x97b3
movq 0x28(%r14), %rax
movq (%rax,%rbx,8), %rax
movl 0x110(%rax), %esi
movq 0x8(%rsp), %rax
addl 0x120(%rax), %esi
movq %rbp, %rdi
callq 0xeb38
movq 0x28(%r14), %rax
movq (%rax,%rbx,8), %rax
movq 0x108(%rax), %rsi
movq %rbp, %rdi
callq 0xf122
incq %rbx
jmp 0x95b3
leaq 0x4e38(%r14), %rdi
leaq 0x4e18(%r14), %rsi
leaq 0x4220(%r14), %rdx
movq %rbx, %rcx
callq 0x10996
movl %eax, %ebp
leaq 0x4e70(%r14), %r12
movq (%r15), %rax
movslq 0x10(%rax), %rsi
movq %r12, %rdi
callq 0xea9e
movq %r12, %rdi
movl %ebp, %esi
callq 0xeb38
pushq $0x17
popq %rdx
movq %r12, %rdi
movq %rbx, %rsi
callq 0xf8f6
movq %r14, %rdi
movq %rbx, %rsi
callq 0x8cb9
jmp 0x976d
movq 0x8(%rdx), %rax
cmpl $0x10, (%rax)
jne 0x9732
movq 0x5118(%r14), %rdi
leaq 0x6111c(%rip), %rsi     # 0x6a803
xorl %eax, %eax
callq *0x50f8(%r14)
jmp 0x9732
testq %r12, %r12
je 0x9711
movq 0x5118(%r14), %rdi
leaq 0x6115f(%rip), %rsi     # 0x6a864
xorl %eax, %eax
callq *0x50f8(%r14)
movq (%r15), %rdx
leaq 0x4e18(%r14), %rdi
leaq 0x4220(%r14), %rsi
callq 0x15100
movq %rax, (%r15)
movq %r14, %rdi
movq %rax, %rsi
callq 0xddbc
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
movq %r12, %rcx
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xdadd
movq 0x28(%rsp), %r14
movq %r14, %rdi
callq 0xed28
movq %r14, %rdi
movl 0x8(%rsp), %esi
callq 0xeb38
movq %rbx, (%r15)
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl (%rbx), %eax
jmp 0x93c1
movl (%rbx), %eax
cmpl $0x10, %eax
je 0x9336
jmp 0x93c1
movq %rbp, %rdi
callq 0xed28
movq %r13, %rdi
movq 0x8(%rsp), %rsi
callq 0x8c92
jmp 0x9489