// File: kelwinfc[P]ci4721-Fernandez-Gyomrey/src/AST/to_tac.cpp
// Function: AST_array_access::gen_tac_arr(Tac*, int*, opd**, int*)
opd *AST_array_access::gen_tac_arr(Tac* t, int *sta_base, opd **ind_addr, int *arr_base){
    opd *din_base = value->gen_tac_arr(t, sta_base, ind_addr, arr_base);

    if (0 == *ind_addr) {
        // no se hace backpatck porque sabemos que es un entero
        *ind_addr = index->to_tac(t);
        if (O_TEMP != (*ind_addr)->type) {
            opd *o = new opd();
            t->append_quad(inst::CP, o, *ind_addr, 0, "el índice más izquierdo de un arreglo es entero, se copia a temporal para poder operar sobre él");
            *ind_addr = o;
        }
    } else {
        // (i1 x n2) + i2 >>= i1 (parte de la suma)
        t->append_quad(inst::ADD, *ind_addr, *ind_addr, index->to_tac(t), "parte dinámica del acceso a arreglo. sumar al acumulador el índice dinámico");
    }

    if (typeid(*types.types[ type ]) == typeid(array_descriptor)){
        array_descriptor* ad = (array_descriptor*)types.types[ type ];

        // (i1 x n2) + i2 (parte del producto)
        t->append_quad(inst::MUL, *ind_addr, *ind_addr, new opd(ad->num_elements), "como aún nos encontramos en un arreglo, multiplicar el índice dinámico por el tamaño del siguiente índice a la derecha");

        // (l1 x n2) + l2
        *arr_base = *arr_base * ad->num_elements + ad->lower_index;
    }

    return din_base;
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x150(%rsp)
movq %rsi, 0x148(%rsp)
movq %rdx, 0x140(%rsp)
movq %rcx, 0x138(%rsp)
movq %r8, 0x130(%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x48(%rax), %rdi
movq 0x148(%rsp), %rsi
movq 0x140(%rsp), %rdx
movq 0x138(%rsp), %rcx
movq 0x130(%rsp), %r8
movq (%rdi), %rax
callq *0x40(%rax)
movq %rax, 0x128(%rsp)
movq 0x138(%rsp), %rcx
xorl %eax, %eax
cmpq (%rcx), %rax
jne 0x16ef9
movq 0x88(%rsp), %rax
movq 0x50(%rax), %rdi
movq 0x148(%rsp), %rsi
movq (%rdi), %rax
callq *0x18(%rax)
movq %rax, %rcx
movq 0x138(%rsp), %rax
movq %rcx, (%rax)
movq 0x138(%rsp), %rax
movq (%rax), %rax
movsbl 0x10(%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
je 0x16ef4
movl $0x18, %edi
callq 0x6390
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x80(%rsp)
callq 0x37ff0
jmp 0x16dc7
movq 0x80(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x120(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x138(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x70(%rsp)
leaq 0xef(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x66c0
movq 0x78(%rsp), %rdx
leaq 0x3c7ee(%rip), %rsi     # 0x5360d
leaq 0xf0(%rsp), %rdi
callq 0x7500
jmp 0x16e2e
movq 0x70(%rsp), %rcx
movq 0x68(%rsp), %rdx
movq 0x60(%rsp), %rdi
xorl %esi, %esi
movl %esi, %r8d
leaq 0xf0(%rsp), %r9
callq 0x4de80
jmp 0x16e51
leaq 0xf0(%rsp), %rdi
callq 0x6778
leaq 0xef(%rsp), %rdi
callq 0x6400
movq 0x120(%rsp), %rcx
movq 0x138(%rsp), %rax
movq %rcx, (%rax)
jmp 0x16ef4
movq 0x80(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
movl $0x18, %esi
callq 0x63a0
jmp 0x171c3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x16ee2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x6778
leaq 0xef(%rsp), %rdi
callq 0x6400
jmp 0x171c3
jmp 0x16fef
movq 0x88(%rsp), %rax
movq 0x148(%rsp), %rsi
movq %rsi, 0x38(%rsp)
movq 0x138(%rsp), %rcx
movq (%rcx), %rcx
movq %rcx, 0x40(%rsp)
movq %rcx, 0x48(%rsp)
movq 0x50(%rax), %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
movq %rax, 0x50(%rsp)
leaq 0xc7(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x66c0
movq 0x58(%rsp), %rdx
leaq 0x3c71d(%rip), %rsi     # 0x53670
leaq 0xc8(%rsp), %rdi
callq 0x7500
jmp 0x16f62
movq 0x50(%rsp), %r8
movq 0x40(%rsp), %rcx
movq 0x48(%rsp), %rdx
movq 0x38(%rsp), %rdi
movl $0x11, %esi
leaq 0xc8(%rsp), %r9
callq 0x4de80
jmp 0x16f8a
leaq 0xc8(%rsp), %rdi
callq 0x6778
leaq 0xc7(%rsp), %rdi
callq 0x6400
jmp 0x16fef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x16fdd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x6778
leaq 0xc7(%rsp), %rdi
callq 0x6400
jmp 0x171c3
movq 0x88(%rsp), %rax
movslq 0x10(%rax), %rsi
leaq 0x574de(%rip), %rdi     # 0x6e4e0
callq 0x1fc90
movq (%rax), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
jne 0x1701a
callq 0x6420
movq 0x30(%rsp), %rax
movq (%rax), %rax
movq -0x8(%rax), %rdi
leaq 0x55e93(%rip), %rsi     # 0x6cec0
callq 0x20340
testb $0x1, %al
jne 0x1703b
jmp 0x171b3
movq 0x88(%rsp), %rax
movslq 0x10(%rax), %rsi
leaq 0x57492(%rip), %rdi     # 0x6e4e0
callq 0x1fc90
movq (%rax), %rax
movq %rax, 0xb8(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x138(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movl $0x18, %edi
callq 0x6390
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x28(%rsp)
movq 0xb8(%rsp), %rax
movl 0x38(%rax), %esi
movl $0x2, %edx
callq 0x38010
jmp 0x170ac
leaq 0x97(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x66c0
movq 0x8(%rsp), %rdx
leaq 0x3c5f5(%rip), %rsi     # 0x536bf
leaq 0x98(%rsp), %rdi
callq 0x7500
jmp 0x170d9
movq 0x28(%rsp), %r8
movq 0x18(%rsp), %rcx
movq 0x20(%rsp), %rdx
movq 0x10(%rsp), %rdi
movl $0x13, %esi
leaq 0x98(%rsp), %r9
callq 0x4de80
jmp 0x17101
leaq 0x98(%rsp), %rdi
callq 0x6778
leaq 0x97(%rsp), %rdi
callq 0x6400
movq 0x130(%rsp), %rax
movl (%rax), %ecx
movq 0xb8(%rsp), %rax
imull 0x38(%rax), %ecx
movq 0xb8(%rsp), %rax
addl 0x30(%rax), %ecx
movq 0x130(%rsp), %rax
movl %ecx, (%rax)
jmp 0x171b3
movq 0x28(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
movl $0x18, %esi
callq 0x63a0
jmp 0x171c3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x171a4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x6778
leaq 0x97(%rsp), %rdi
callq 0x6400
jmp 0x171c3
movq 0x128(%rsp), %rax
addq $0x158, %rsp            # imm = 0x158
retq
movq 0x118(%rsp), %rdi
callq 0x66b0