// File: JameyWoo[P]csmile/assembly.cpp
// Function: genCall(TreeNode*, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>)
void genCall(TreeNode* call, map<string, string> var2stack) {
    // ! 结果在 %eax中
    if (call == NULL) return;
    // debug("call: " + call->child[0]->nodekind);
    // 解析 Call 的参数
    // call->child[0] 是这个函数的名字
    // call->child[1] 如果不为 NULL 的话, 是 Args 类型的
    // 解析args, arg可以是expression, 种类比较多. 考虑是不是要综合一个整体的
    TreeNode* args = call->child[1];
    if (args == NULL) {
        // TODO: call 没有参数的情况
        assout << "\tcall\t" << call->child[0]->name << endl;
        return;
    }
    // debug("args: " + args->child[0]->nodekind);
    // debug("args: " + args->child[0]->sibling->nodekind);

    // 传递参数
    stack<TreeNode*> call_stack;
    TreeNode* arg = args->child[0];
    int cnt       = 0;
    while (arg != NULL) {
        cnt += 1;
        call_stack.push(arg);
        arg = arg->sibling;
    }
    // 调整栈的位置, 防止参数过多
    cnt -= 1;
    assout << "\tsubl\t$" << 4 * cnt << ", %esp" << endl;
    while (not call_stack.empty()) {
        string stack_loc = to_string(4 * cnt) + "(%esp)";
        TreeNode* tmp    = call_stack.top();
        // debug("arg type: " + tmp->nodekind);
        string left = "";
        if (tmp->nodekind == "Const") {
            left += "$" + to_string(tmp->val);
        } else if (tmp->nodekind == "Id") {
            assout << "\tmovl\t" << var2stack[tmp->name] << ", %edx" << endl;
            left += "%edx";
        } else if (tmp->nodekind == "PMOp" || tmp->nodekind == "MDOp") {
            // 一个计算的表达式
            genCalc(tmp, var2stack);
            left += "%edx";
        }
        assout << "\tmovl\t" << left << ", " << stack_loc << endl;
        // TODO: 支持更多的参数类型

        call_stack.pop();
        cnt -= 1;
    }
    // 调用函数
    assout << "\tcall\t" << call->child[0]->name << endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x210, %rsp            # imm = 0x210
movq %rsi, -0x170(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0x18256
jmp 0x18841
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x182a6
leaq 0x16a38(%rip), %rdi     # 0x2eca8
leaq 0x94d3(%rip), %rsi      # 0x2174a
callq 0x3270
movq %rax, %rdi
movq -0x8(%rbp), %rax
movq (%rax), %rsi
addq $0xc0, %rsi
callq 0x3240
movq %rax, %rdi
movq 0x15d14(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x18841
leaq -0x68(%rbp), %rdi
callq 0x1c070
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x70(%rbp)
movl $0x0, -0x74(%rbp)
cmpq $0x0, -0x70(%rbp)
je 0x18301
movl -0x74(%rbp), %eax
incl %eax
movl %eax, -0x74(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x1c0a0
jmp 0x182df
movq -0x70(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x70(%rbp)
jmp 0x182c1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x1884a
movl -0x74(%rbp), %eax
decl %eax
movl %eax, -0x74(%rbp)
leaq 0x16998(%rip), %rdi     # 0x2eca8
leaq 0x943a(%rip), %rsi      # 0x21751
callq 0x3270
movq %rax, -0x178(%rbp)
jmp 0x18325
movq -0x178(%rbp), %rdi
movl -0x74(%rbp), %esi
shll $0x2, %esi
callq 0x3460
movq %rax, -0x180(%rbp)
jmp 0x18340
movq -0x180(%rbp), %rdi
leaq 0x940b(%rip), %rsi      # 0x21759
callq 0x3270
movq %rax, -0x188(%rbp)
jmp 0x1835c
movq -0x188(%rbp), %rdi
movq 0x15c46(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x18371
jmp 0x18373
leaq -0x68(%rbp), %rdi
callq 0x1c0d0
movb %al, -0x189(%rbp)
jmp 0x18384
movb -0x189(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x18395
jmp 0x187e4
movl -0x74(%rbp), %esi
shll $0x2, %esi
leaq -0xc8(%rbp), %rdi
callq 0xf460
jmp 0x183a9
leaq 0x931f(%rip), %rdx      # 0x216cf
leaq -0xa8(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0xf3c0
jmp 0x183c5
leaq -0xc8(%rbp), %rdi
callq 0x34e8
leaq -0x68(%rbp), %rdi
callq 0x1c0f0
movq %rax, -0x198(%rbp)
jmp 0x183e3
movq -0x198(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xd0(%rbp)
leaq -0xf1(%rbp), %rdi
movq %rdi, -0x1a0(%rbp)
callq 0x3480
movq -0x1a0(%rbp), %rdx
leaq 0x9280(%rip), %rsi      # 0x21695
leaq -0xf0(%rbp), %rdi
callq 0x4ef0
jmp 0x18423
leaq -0xf1(%rbp), %rdi
callq 0x32d0
movq -0xd0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x8da8(%rip), %rsi      # 0x211e9
callq 0x5e70
movb %al, -0x1a1(%rbp)
jmp 0x1844e
movb -0x1a1(%rbp), %al
testb $0x1, %al
jne 0x1845d
jmp 0x1856b
movq -0xd0(%rbp), %rax
movl 0xb8(%rax), %esi
leaq -0x138(%rbp), %rdi
callq 0xf460
jmp 0x18478
leaq 0x92d8(%rip), %rsi      # 0x21757
leaq -0x118(%rbp), %rdi
leaq -0x138(%rbp), %rdx
callq 0xf410
jmp 0x18494
leaq -0xf0(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x3380
jmp 0x184a9
leaq -0x118(%rbp), %rdi
callq 0x34e8
leaq -0x138(%rbp), %rdi
callq 0x34e8
jmp 0x18714
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x34e8
jmp 0x1884a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x187d6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xf1(%rbp), %rdi
callq 0x32d0
jmp 0x187d6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x187ca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x1855a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x34e8
leaq -0x138(%rbp), %rdi
callq 0x34e8
jmp 0x187ca
movq -0xd0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x8c2f(%rip), %rsi      # 0x211ac
callq 0x5e70
movb %al, -0x1a2(%rbp)
jmp 0x1858a
movb -0x1a2(%rbp), %al
testb $0x1, %al
jne 0x18599
jmp 0x1863f
leaq 0x16708(%rip), %rdi     # 0x2eca8
leaq 0x90ef(%rip), %rsi      # 0x21696
callq 0x3270
movq %rax, -0x1b0(%rbp)
jmp 0x185b5
movq -0x170(%rbp), %rdi
movq -0xd0(%rbp), %rsi
addq $0xc0, %rsi
callq 0xf2e0
movq %rax, -0x1b8(%rbp)
jmp 0x185d8
movq -0x1b8(%rbp), %rsi
movq -0x1b0(%rbp), %rdi
callq 0x3240
movq %rax, -0x1c0(%rbp)
jmp 0x185f4
movq -0x1c0(%rbp), %rdi
leaq 0x91d6(%rip), %rsi      # 0x217d8
callq 0x3270
movq %rax, -0x1c8(%rbp)
jmp 0x18610
movq -0x1c8(%rbp), %rdi
movq 0x15992(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x18625
leaq 0x91ae(%rip), %rsi      # 0x217da
leaq -0xf0(%rbp), %rdi
callq 0x3260
jmp 0x1863a
jmp 0x18712
movq -0xd0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x8ba3(%rip), %rsi      # 0x211f4
callq 0x5e70
movb %al, -0x1c9(%rbp)
jmp 0x1865e
movb -0x1c9(%rbp), %al
testb $0x1, %al
jne 0x18695
jmp 0x1866a
movq -0xd0(%rbp), %rdi
addq $0x30, %rdi
leaq 0x8b73(%rip), %rsi      # 0x211ef
callq 0x5e70
movb %al, -0x1ca(%rbp)
jmp 0x18689
movb -0x1ca(%rbp), %al
testb $0x1, %al
jne 0x18695
jmp 0x18710
movq -0x170(%rbp), %rsi
movq -0xd0(%rbp), %rax
movq %rax, -0x1d8(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x1c040
jmp 0x186b8
movq -0x1d8(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x1a8a0
jmp 0x186cd
leaq -0x168(%rbp), %rdi
callq 0xee40
leaq 0x90fa(%rip), %rsi      # 0x217da
leaq -0xf0(%rbp), %rdi
callq 0x3260
jmp 0x186ee
jmp 0x18710
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x168(%rbp), %rdi
callq 0xee40
jmp 0x187ca
jmp 0x18712
jmp 0x18714
leaq 0x1658d(%rip), %rdi     # 0x2eca8
leaq 0x8f74(%rip), %rsi      # 0x21696
callq 0x3270
movq %rax, -0x1e0(%rbp)
jmp 0x18730
movq -0x1e0(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x3240
movq %rax, -0x1e8(%rbp)
jmp 0x1874c
movq -0x1e8(%rbp), %rdi
leaq 0x903d(%rip), %rsi      # 0x21797
callq 0x3270
movq %rax, -0x1f0(%rbp)
jmp 0x18768
movq -0x1f0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x3240
movq %rax, -0x1f8(%rbp)
jmp 0x18784
movq -0x1f8(%rbp), %rdi
movq 0x1581e(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x18799
leaq -0x68(%rbp), %rdi
callq 0x1c110
jmp 0x187a4
movl -0x74(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x74(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x34e8
leaq -0xa8(%rbp), %rdi
callq 0x34e8
jmp 0x18373
leaq -0xf0(%rbp), %rdi
callq 0x34e8
leaq -0xa8(%rbp), %rdi
callq 0x34e8
jmp 0x1884a
leaq 0x164bd(%rip), %rdi     # 0x2eca8
leaq 0x8f58(%rip), %rsi      # 0x2174a
callq 0x3270
movq %rax, -0x200(%rbp)
jmp 0x18800
movq -0x200(%rbp), %rdi
movq -0x8(%rbp), %rax
movq (%rax), %rsi
addq $0xc0, %rsi
callq 0x3240
movq %rax, -0x208(%rbp)
jmp 0x18823
movq -0x208(%rbp), %rdi
movq 0x1577f(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x18838
leaq -0x68(%rbp), %rdi
callq 0x1c130
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
leaq -0x68(%rbp), %rdi
callq 0x1c130
movq -0x80(%rbp), %rdi
callq 0x3470
nopl (%rax)