// File: /workspace/github_c_makefile_star2_O0/vtereshkov[P]umka-lang/src/umka_expr.c
// Function: doDynArrayToDynArrayConv
static void doDynArrayToDynArrayConv(Compiler *comp, const Type *dest, const Type **src, Const *constant)
{
    if (constant)
        comp->error.handler(comp->error.context, "Conversion from dynamic array is not allowed in constant expressions");

    // Get source array length: length = len(srcArray)
    int lenOffset = identAllocStack(&comp->idents, &comp->types, &comp->blocks, comp->intType);

    genDup(&comp->gen);
    genCallBuiltin(&comp->gen, (*src)->kind, BUILTIN_LEN);
    genPushLocalPtr(&comp->gen, lenOffset);
    genSwapAssign(&comp->gen, TYPE_INT, 0);

    // Allocate destination array: destArray = make(dest, length)
    const Ident *destArray = identAllocTempVar(&comp->idents, &comp->types, &comp->modules, &comp->blocks, dest, false);
    doZeroVar(comp, destArray);

    genPushLocal(&comp->gen, TYPE_INT, lenOffset);
    doPushVarPtr(comp, destArray);
    genCallTypedBuiltin(&comp->gen, dest, BUILTIN_MAKE);
    genPop(&comp->gen);

    // Loop initialization: index = length - 1
    int indexOffset = identAllocStack(&comp->idents, &comp->types, &comp->blocks, comp->intType);

    genPushLocal(&comp->gen, TYPE_INT, lenOffset);
    genPushIntConst(&comp->gen, 1);
    genBinary(&comp->gen, TOK_MINUS, TYPE_INT, 0);
    genPushLocalPtr(&comp->gen, indexOffset);
    genSwapAssign(&comp->gen, TYPE_INT, 0);

    // Loop condition: index >= 0
    genWhileCondProlog(&comp->gen);

    genPushLocal(&comp->gen, TYPE_INT, indexOffset);
    genPushIntConst(&comp->gen, 0);
    genBinary(&comp->gen, TOK_GREATEREQ, TYPE_INT, 0);

    genWhileCondEpilog(&comp->gen);

    // Additional scope embracing temporary variables declaration
    blocksEnter(&comp->blocks);

    // Loop body: destArray[index] = destItemType(srcArray[index]); index--
    genDup(&comp->gen);
    genPushLocal(&comp->gen, TYPE_INT, indexOffset);
    genGetDynArrayPtr(&comp->gen);
    genDeref(&comp->gen, (*src)->base->kind);

    const Type *castType = (*src)->base;
    doExplicitTypeConv(comp, dest->base, &castType, constant);

    if (!typeEquivalent(dest->base, castType))
    {
        char srcBuf[DEFAULT_STR_LEN + 1], destBuf[DEFAULT_STR_LEN + 1];
        comp->error.handler(comp->error.context, "Cannot cast %s to %s", typeSpelling((*src)->base, srcBuf), typeSpelling(dest->base, destBuf));
    }

    doPushVarPtr(comp, destArray);
    genDeref(&comp->gen, dest->kind);
    genPushLocal(&comp->gen, TYPE_INT, indexOffset);
    genGetDynArrayPtr(&comp->gen);
    genSwapChangeRefCntAssign(&comp->gen, dest->base);

    genPushLocalPtr(&comp->gen, indexOffset);
    genUnary(&comp->gen, TOK_MINUSMINUS, TYPE_INT);

    // Additional scope embracing temporary variables declaration
    doGarbageCollection(comp);
    identWarnIfUnusedAll(&comp->idents, blocksCurrent(&comp->blocks));
    blocksLeave(&comp->blocks);

    genWhileEpilog(&comp->gen);

    // Remove srcArray and push destArray
    genPop(&comp->gen);
    doPushVarPtr(comp, destArray);
    genDeref(&comp->gen, dest->kind);

    *src = dest;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x260, %rsp            # imm = 0x260
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0xdd53
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rdi
leaq 0x1cae91(%rip), %rsi    # 0x1d8be0
movb $0x0, %al
callq *%rcx
movq -0x8(%rbp), %rdi
addq $0x4e38, %rdi           # imm = 0x4E38
movq -0x8(%rbp), %rsi
addq $0x4e18, %rsi           # imm = 0x4E18
movq -0x8(%rbp), %rdx
addq $0x4220, %rdx           # imm = 0x4220
movq -0x8(%rbp), %rax
movq 0x5240(%rax), %rcx
callq 0x1a320
movl %eax, -0x24(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16eb0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x18(%rbp), %rax
movq (%rax), %rax
movl (%rax), %esi
movl $0x22, %edx
callq 0x18040
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x24(%rbp), %esi
callq 0x169a0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x7, %esi
xorl %edx, %edx
callq 0x17120
movq -0x8(%rbp), %rdi
addq $0x4e38, %rdi           # imm = 0x4E38
movq -0x8(%rbp), %rsi
addq $0x4e18, %rsi           # imm = 0x4E18
movq -0x8(%rbp), %rdx
addq $0x100, %rdx            # imm = 0x100
movq -0x8(%rbp), %rcx
addq $0x4220, %rcx           # imm = 0x4220
movq -0x10(%rbp), %r8
xorl %r9d, %r9d
callq 0x1a540
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x1d5e0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x24(%rbp), %edx
movl $0x7, %esi
callq 0x16b10
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0xd010
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x10(%rbp), %rsi
movl $0x16, %edx
callq 0x182e0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16d30
movq -0x8(%rbp), %rdi
addq $0x4e38, %rdi           # imm = 0x4E38
movq -0x8(%rbp), %rsi
addq $0x4e18, %rsi           # imm = 0x4E18
movq -0x8(%rbp), %rdx
addq $0x4220, %rdx           # imm = 0x4220
movq -0x8(%rbp), %rax
movq 0x5240(%rax), %rcx
callq 0x1a320
movl %eax, -0x34(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x24(%rbp), %edx
movl $0x7, %esi
callq 0x16b10
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x1, %esi
callq 0x16850
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x17, %esi
movl $0x7, %edx
xorl %ecx, %ecx
callq 0x17790
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x34(%rbp), %esi
callq 0x169a0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x7, %esi
xorl %edx, %edx
callq 0x17120
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x188a0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x34(%rbp), %edx
movl $0x7, %esi
callq 0x16b10
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
xorl %eax, %eax
movl %eax, %esi
callq 0x16850
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x36, %esi
movl $0x7, %edx
xorl %ecx, %ecx
callq 0x17790
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x188c0
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x5e60
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16eb0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x34(%rbp), %edx
movl $0x7, %esi
callq 0x16b10
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x17b00
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movl (%rax), %esi
callq 0x16fa0
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x20(%rbp), %rcx
leaq -0x40(%rbp), %rdx
callq 0xd730
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x40(%rbp), %rsi
callq 0x22250
testb $0x1, %al
jne 0xe0a1
movq -0x8(%rbp), %rax
movq 0x50f8(%rax), %rax
movq %rax, -0x248(%rbp)
movq -0x8(%rbp), %rax
movq 0x5118(%rax), %rax
movq %rax, -0x258(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rdi
leaq -0x140(%rbp), %rsi
callq 0x22070
movq %rax, -0x250(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq -0x240(%rbp), %rsi
callq 0x22070
movq -0x258(%rbp), %rdi
movq -0x250(%rbp), %rdx
movq -0x248(%rbp), %r8
movq %rax, %rcx
leaq 0x1cab89(%rip), %rsi    # 0x1d8c25
movb $0x0, %al
callq *%r8
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0xd010
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x10(%rbp), %rax
movl (%rax), %esi
callq 0x16fa0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x34(%rbp), %edx
movl $0x7, %esi
callq 0x16b10
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x17b00
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x17500
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl -0x34(%rbp), %esi
callq 0x169a0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movl $0x2d, %esi
movl $0x7, %edx
callq 0x17620
movq -0x8(%rbp), %rdi
callq 0x1d3a0
movq -0x8(%rbp), %rax
addq $0x4e38, %rax           # imm = 0x4E38
movq %rax, -0x260(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x6020
movq -0x260(%rbp), %rdi
movl %eax, %esi
callq 0x1a7e0
movq -0x8(%rbp), %rdi
addq $0x4220, %rdi           # imm = 0x4220
callq 0x5fa0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x188e0
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
callq 0x16d30
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0xd010
movq -0x8(%rbp), %rdi
addq $0x4e70, %rdi           # imm = 0x4E70
movq -0x10(%rbp), %rax
movl (%rax), %esi
callq 0x16fa0
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
addq $0x260, %rsp            # imm = 0x260
popq %rbp
retq