// File: fondoger[P]C0-Compiler/src/mips.cpp
// Function: gen_RARRAY_WARRAY(_FourTuple const&)
static void gen_RARRAY_WARRAY(const FourTuple &ft) 
{
    // format:
    //      * WARRAY, arr, idx, value
    //      * RARRAY, arr, idx, target
    assert(ft.op == RARRAY || ft.op == WARRAY);
    TabEntry entry;
    
    bool flag = tabFind(ft.a, entry);
    assert(flag == true);
    assert(entry.itype == IT_ARRAY);

    // Step 1: load index(offset) to register $v0
    int idx_val;
    if (isConstValue(ft.b, idx_val)) {
        // for const values, we calculate it's actual
        // offset without a multiplication
        loadToReg("$v0", std::to_string(idx_val * 4));
    } else {
        loadToReg("$v0", ft.b);
        // might use shift operate to improve performance
        MIPS(T << "mul" << HT << "$v0, $v0, 4");
    }

    // Step 2-1: handle global arrays
    if (entry.scope == GLOBAL) {
        if (ft.op == RARRAY) {
            MIPS(T << "lw" << HT << "$v1, " << ft.a << "($v0)");
            MIPS(T << "sw" << HT << "$v1, " << getVariableAddr(ft.res));
        } else {
            loadToReg("$v1", ft.res);
            MIPS(T << "sw" << HT << "$v1, " << ft.a << "($v0)");
        }
        return;
    } 

    assert(entry.scope == LOCAL);
    // Step 2-2: handle local arrays
    // calculate array element's memory address
    MIPS(T << "addu" << HT << "$v0, $v0, $sp");
    if (ft.op == RARRAY) {
        MIPS(T << "lw" << HT << "$v1, " << entry.addr << "($v0)");
        MIPS(T << "sw" << HT << "$v1, " << getVariableAddr(ft.res));
    } else {
        loadToReg("$v1", ft.res);
        MIPS(T << "sw" << HT << "$v1, " << entry.addr << "($v0)");
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rcx
movb $0x1, %al
cmpl $0xe, (%rcx)
movb %al, -0x132(%rbp)
je 0x2a940
movq -0x8(%rbp), %rax
cmpl $0xd, (%rax)
sete %al
movb %al, -0x132(%rbp)
movb -0x132(%rbp), %al
testb $0x1, %al
jne 0x2a94c
jmp 0x2a94e
jmp 0x2a96d
leaq 0xb848(%rip), %rdi      # 0x3619d
leaq 0xb634(%rip), %rsi      # 0x35f90
movl $0x19b, %edx            # imm = 0x19B
leaq 0xb858(%rip), %rcx      # 0x361c0
callq 0x3230
movq -0x8(%rbp), %rdi
addq $0x8, %rdi
leaq -0x1c(%rbp), %rsi
callq 0x2f100
andb $0x1, %al
movb %al, -0x1d(%rbp)
movb -0x1d(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x2a992
jmp 0x2a9b1
leaq 0xb75e(%rip), %rdi      # 0x360f7
leaq 0xb5f0(%rip), %rsi      # 0x35f90
movl $0x19f, %edx            # imm = 0x19F
leaq 0xb814(%rip), %rcx      # 0x361c0
callq 0x3230
cmpl $0x3, -0x18(%rbp)
jne 0x2a9b9
jmp 0x2a9d8
leaq 0xb82a(%rip), %rdi      # 0x361ea
leaq 0xb5c9(%rip), %rsi      # 0x35f90
movl $0x1a0, %edx            # imm = 0x1A0
leaq 0xb7ed(%rip), %rcx      # 0x361c0
callq 0x3230
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
leaq -0x24(%rbp), %rsi
callq 0x27780
testb $0x1, %al
jne 0x2a9f2
jmp 0x2aaa3
leaq -0x49(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x3570
movq -0x140(%rbp), %rdx
leaq 0xb6df(%rip), %rsi      # 0x360ef
leaq -0x48(%rbp), %rdi
callq 0x3440
jmp 0x2aa1b
movl -0x24(%rbp), %esi
shll $0x2, %esi
leaq -0x80(%rbp), %rdi
callq 0x22950
jmp 0x2aa2c
leaq -0x48(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x2cf90
jmp 0x2aa3b
leaq -0x80(%rbp), %rdi
callq 0x35e8
leaq -0x48(%rbp), %rdi
callq 0x35e8
leaq -0x49(%rbp), %rdi
callq 0x3370
jmp 0x2ab76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x2aa95
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x2aa8c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x35e8
leaq -0x48(%rbp), %rdi
callq 0x35e8
leaq -0x49(%rbp), %rdi
callq 0x3370
jmp 0x2b013
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x148(%rbp)
callq 0x3570
movq -0x148(%rbp), %rdx
leaq 0xb62b(%rip), %rsi      # 0x360ef
leaq -0xa0(%rbp), %rdi
callq 0x3440
jmp 0x2aad2
movq -0x8(%rbp), %rsi
addq $0x28, %rsi
leaq -0xa0(%rbp), %rdi
callq 0x2cf90
jmp 0x2aae8
leaq -0xa0(%rbp), %rdi
callq 0x35e8
leaq -0xa1(%rbp), %rdi
callq 0x3370
leaq 0x1fb29(%rip), %rdi     # 0x4a630
addq $0x10, %rdi
leaq 0xb566(%rip), %rsi      # 0x36078
callq 0x3300
movq %rax, %rdi
leaq 0xb4d3(%rip), %rsi      # 0x35ff4
callq 0x3300
movq %rax, %rdi
leaq 0xb6d2(%rip), %rsi      # 0x36202
callq 0x3300
movq %rax, %rdi
callq 0x29270
jmp 0x2ab76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x2ab65
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x35e8
leaq -0xa1(%rbp), %rdi
callq 0x3370
jmp 0x2b013
cmpl $0x0, -0x1c(%rbp)
jne 0x2ad9c
movq -0x8(%rbp), %rax
cmpl $0xe, (%rax)
jne 0x2aca5
leaq 0x1faac(%rip), %rdi     # 0x4a640
movq %rdi, -0x178(%rbp)
leaq 0xb410(%rip), %rsi      # 0x35fb2
callq 0x3300
movq %rax, %rdi
leaq 0xb443(%rip), %rsi      # 0x35ff4
movq %rsi, -0x170(%rbp)
callq 0x3300
movq %rax, %rdi
leaq 0xb647(%rip), %rsi      # 0x3620e
movq %rsi, -0x168(%rbp)
callq 0x3300
movq %rax, %rdi
movq -0x8(%rbp), %rsi
addq $0x8, %rsi
callq 0x32c0
movq %rax, %rdi
leaq 0xb627(%rip), %rsi      # 0x36214
callq 0x3300
movq %rax, %rdi
callq 0x29270
movq -0x178(%rbp), %rdi
leaq 0xb3ad(%rip), %rsi      # 0x35fb5
callq 0x3300
movq -0x170(%rbp), %rsi
movq %rax, %rdi
callq 0x3300
movq -0x168(%rbp), %rsi
movq %rax, %rdi
callq 0x3300
movq %rax, -0x160(%rbp)
movq -0x8(%rbp), %rsi
addq $0x48, %rsi
leaq -0xc8(%rbp), %rdi
movq %rdi, -0x158(%rbp)
callq 0x2d120
movq -0x160(%rbp), %rdi
movq -0x158(%rbp), %rsi
callq 0x32c0
movq %rax, -0x150(%rbp)
jmp 0x2ac69
movq -0x150(%rbp), %rdi
callq 0x29270
jmp 0x2ac77
leaq -0xc8(%rbp), %rdi
callq 0x35e8
jmp 0x2ad97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x35e8
jmp 0x2b013
leaq -0xe9(%rbp), %rdi
movq %rdi, -0x180(%rbp)
callq 0x3570
movq -0x180(%rbp), %rdx
leaq 0xb42d(%rip), %rsi      # 0x360f3
leaq -0xe8(%rbp), %rdi
callq 0x3440
jmp 0x2acd4
movq -0x8(%rbp), %rsi
addq $0x48, %rsi
leaq -0xe8(%rbp), %rdi
callq 0x2cf90
jmp 0x2acea
leaq -0xe8(%rbp), %rdi
callq 0x35e8
leaq -0xe9(%rbp), %rdi
callq 0x3370
leaq 0x1f927(%rip), %rdi     # 0x4a630
addq $0x10, %rdi
leaq 0xb2a1(%rip), %rsi      # 0x35fb5
callq 0x3300
movq %rax, %rdi
leaq 0xb2d1(%rip), %rsi      # 0x35ff4
callq 0x3300
movq %rax, %rdi
leaq 0xb4dc(%rip), %rsi      # 0x3620e
callq 0x3300
movq %rax, %rdi
movq -0x8(%rbp), %rsi
addq $0x8, %rsi
callq 0x32c0
movq %rax, %rdi
leaq 0xb4c3(%rip), %rsi      # 0x36214
callq 0x3300
movq %rax, %rdi
callq 0x29270
jmp 0x2ad97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x2ad86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x35e8
leaq -0xe9(%rbp), %rdi
callq 0x3370
jmp 0x2b013
jmp 0x2b00a
cmpl $0x1, -0x1c(%rbp)
jne 0x2ada4
jmp 0x2adc3
leaq 0xb46f(%rip), %rdi      # 0x3621a
leaq 0xb1de(%rip), %rsi      # 0x35f90
movl $0x1ba, %edx            # imm = 0x1BA
leaq 0xb402(%rip), %rcx      # 0x361c0
callq 0x3230
leaq 0x1f866(%rip), %rdi     # 0x4a630
addq $0x10, %rdi
leaq 0xb299(%rip), %rsi      # 0x3606e
callq 0x3300
movq %rax, %rdi
leaq 0xb210(%rip), %rsi      # 0x35ff4
callq 0x3300
movq %rax, %rdi
leaq 0xb43c(%rip), %rsi      # 0x3622f
callq 0x3300
movq %rax, %rdi
callq 0x29270
movq -0x8(%rbp), %rax
cmpl $0xe, (%rax)
jne 0x2af20
leaq 0x1f82c(%rip), %rdi     # 0x4a640
movq %rdi, -0x1b0(%rbp)
leaq 0xb190(%rip), %rsi      # 0x35fb2
callq 0x3300
movq %rax, %rdi
leaq 0xb1c3(%rip), %rsi      # 0x35ff4
movq %rsi, -0x1a8(%rbp)
callq 0x3300
movq %rax, %rdi
leaq 0xb3c7(%rip), %rsi      # 0x3620e
movq %rsi, -0x1a0(%rbp)
callq 0x3300
movq %rax, %rdi
movl -0xc(%rbp), %esi
callq 0x3550
movq %rax, %rdi
leaq 0xb3ac(%rip), %rsi      # 0x36214
callq 0x3300
movq %rax, %rdi
callq 0x29270
movq -0x1b0(%rbp), %rdi
leaq 0xb132(%rip), %rsi      # 0x35fb5
callq 0x3300
movq -0x1a8(%rbp), %rsi
movq %rax, %rdi
callq 0x3300
movq -0x1a0(%rbp), %rsi
movq %rax, %rdi
callq 0x3300
movq %rax, -0x198(%rbp)
movq -0x8(%rbp), %rsi
addq $0x48, %rsi
leaq -0x110(%rbp), %rdi
movq %rdi, -0x190(%rbp)
callq 0x2d120
movq -0x198(%rbp), %rdi
movq -0x190(%rbp), %rsi
callq 0x32c0
movq %rax, -0x188(%rbp)
jmp 0x2aee4
movq -0x188(%rbp), %rdi
callq 0x29270
jmp 0x2aef2
leaq -0x110(%rbp), %rdi
callq 0x35e8
jmp 0x2b00a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x35e8
jmp 0x2b013
leaq -0x131(%rbp), %rdi
movq %rdi, -0x1b8(%rbp)
callq 0x3570
movq -0x1b8(%rbp), %rdx
leaq 0xb1b2(%rip), %rsi      # 0x360f3
leaq -0x130(%rbp), %rdi
callq 0x3440
jmp 0x2af4f
movq -0x8(%rbp), %rsi
addq $0x48, %rsi
leaq -0x130(%rbp), %rdi
callq 0x2cf90
jmp 0x2af65
leaq -0x130(%rbp), %rdi
callq 0x35e8
leaq -0x131(%rbp), %rdi
callq 0x3370
leaq 0x1f6ac(%rip), %rdi     # 0x4a630
addq $0x10, %rdi
leaq 0xb026(%rip), %rsi      # 0x35fb5
callq 0x3300
movq %rax, %rdi
leaq 0xb056(%rip), %rsi      # 0x35ff4
callq 0x3300
movq %rax, %rdi
leaq 0xb261(%rip), %rsi      # 0x3620e
callq 0x3300
movq %rax, %rdi
movl -0xc(%rbp), %esi
callq 0x3550
movq %rax, %rdi
leaq 0xb24d(%rip), %rsi      # 0x36214
callq 0x3300
movq %rax, %rdi
callq 0x29270
jmp 0x2b00a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x2affc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x130(%rbp), %rdi
callq 0x35e8
leaq -0x131(%rbp), %rdi
callq 0x3370
jmp 0x2b013
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x3560
nopl (%rax)