// File: sighingnow[P]compile-pascal/pl0_tac_gen.cpp
// Function: pl0_tac_call_proc(pl0_ast_call_proc const*)
void pl0_tac_call_proc(pl0_ast_call_proc const *stmt) {
    cout << __func__;
    std::vector<std::pair<Value *, std::string>> args;
    if (stmt->args) {
        for (auto argexpr: stmt->args->args) {
            args.emplace(args.begin(), pl0_tac_expr(argexpr->arg));
        }
    }
    proc p;
    proctb.find(stmt->id->id, true, p);
    if (p.name.length() == 0) {
        pl0_ast_error(stmt->id->loc, "use of undeclared identifier '" + stmt->id->id + "'");
    }
    std::vector<std::pair<Value *, bool>> pushes; // <Value * val, bool is_ref>
    if (args.size() != p.param_t.size()) {
        pl0_ast_error(stmt->args->loc, string("unmatched number of parameters and arguments."));
    }
    else {
        size_t len = args.size();
        for (size_t i = 0; i < len; ++i) {
            bool is_ref = p.param_t[len-1-i].length() > 4 && p.param_t[len-1-i].substr(0, 4) == "ref_";
            // if (args[i].second != (is_ref ? p.param_t[len-1-i].substr(4): p.param_t[len-1-i])) {
            //     pl0_ast_error(stmt->args->args[i]->loc, string("unmatched type of parameter and argument."));
            // }
            if (is_ref) {
                if (args[i].first->t == Value::TYPE::IMM || (args[i].first->sv.back() != '#' && args[i].first->sv.front() == '~')) {
                    pl0_ast_error(stmt->args->args[i]->loc, string("use constant or expression as reference value."));
                }
                pushes.emplace_back(make_pair(args[i].first, true));
            }
            else {
                pushes.emplace_back(make_pair(args[i].first, false));
            }
        }
    }
    irb.emit("call", new Value(p.name, "string"), pushes);
    irb.emit("label", new Value(irb.makelabel(), "integer"), new Value("allsuffix", "string"));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3c0, %rsp            # imm = 0x3C0
movq %rdi, -0x8(%rbp)
movq 0xa8db2(%rip), %rdi     # 0x15efd8
leaq 0x3ba02(%rip), %rsi     # 0xf1c2f
callq 0x5330
leaq -0x20(%rbp), %rdi
callq 0xbfca0
movq -0x8(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0xb6339
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7db00
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7f5a0
movq %rax, -0x38(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0xbfcc0
testb $0x1, %al
jne 0xb628a
jmp 0xb6337
leaq -0x30(%rbp), %rdi
callq 0x7fe10
movq (%rax), %rax
movq %rax, -0x40(%rbp)
leaq -0x20(%rbp), %rdi
callq 0xbfd40
movq %rax, -0x50(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0xbfd70
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x78(%rbp), %rdi
callq 0xba600
jmp 0xb62c7
movq -0x48(%rbp), %rsi
leaq -0x20(%rbp), %rdi
leaq -0x78(%rbp), %rdx
callq 0xbfd00
movq %rax, -0x330(%rbp)
jmp 0xb62e1
movq -0x330(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0x78(%rbp), %rdi
callq 0xbf290
leaq -0x30(%rbp), %rdi
callq 0xbfdb0
jmp 0xb6274
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6de9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x78(%rbp), %rdi
callq 0xbf290
jmp 0xb6de9
jmp 0xb6339
leaq -0xc8(%rbp), %rdi
callq 0xbfdd0
jmp 0xb6347
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rsi
addq $0x8, %rsi
leaq 0xaa41e(%rip), %rdi     # 0x160778
movl $0x1, %edx
leaq -0xc8(%rbp), %rcx
callq 0xbfe50
jmp 0xb636d
leaq -0xc8(%rbp), %rdi
callq 0x54e0
cmpq $0x0, %rax
jne 0xb6452
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq (%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdx
addq $0x8, %rdx
leaq 0x3ae4a(%rip), %rsi     # 0xf11f2
leaq -0x110(%rbp), %rdi
callq 0x19ef0
jmp 0xb63b6
leaq 0x3ae52(%rip), %rdx     # 0xf120f
leaq -0xf0(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x1a380
jmp 0xb63d2
movq -0xd0(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0xae910
jmp 0xb63e7
leaq -0xf0(%rbp), %rdi
callq 0x5200
leaq -0x110(%rbp), %rdi
callq 0x5200
jmp 0xb6452
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6ddd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6441
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x5200
leaq -0x110(%rbp), %rdi
callq 0x5200
jmp 0xb6ddd
leaq -0x128(%rbp), %rdi
callq 0xc0010
leaq -0x20(%rbp), %rdi
callq 0xc0030
movq %rax, -0x338(%rbp)
leaq -0xc8(%rbp), %rdi
addq $0x20, %rdi
callq 0xa3e70
movq %rax, %rcx
movq -0x338(%rbp), %rax
cmpq %rcx, %rax
je 0xb6541
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq (%rax), %rax
movq %rax, -0x130(%rbp)
leaq -0x151(%rbp), %rdi
movq %rdi, -0x340(%rbp)
callq 0x55d0
movq -0x340(%rbp), %rdx
leaq 0x3ad4d(%rip), %rsi     # 0xf1211
leaq -0x150(%rbp), %rdi
callq 0x19840
jmp 0xb64d2
movq -0x130(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0xae910
jmp 0xb64e7
leaq -0x150(%rbp), %rdi
callq 0x5200
leaq -0x151(%rbp), %rdi
callq 0x53c0
jmp 0xb68df
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6530
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x150(%rbp), %rdi
callq 0x5200
leaq -0x151(%rbp), %rdi
callq 0x53c0
jmp 0xb6dd1
leaq -0x20(%rbp), %rdi
callq 0xc0030
movq %rax, -0x160(%rbp)
movq $0x0, -0x168(%rbp)
movq -0x168(%rbp), %rax
cmpq -0x160(%rbp), %rax
jae 0xb68dd
leaq -0xc8(%rbp), %rdi
addq $0x20, %rdi
movq -0x160(%rbp), %rsi
subq $0x1, %rsi
subq -0x168(%rbp), %rsi
callq 0xc0060
movq %rax, %rdi
callq 0x54e0
movq %rax, %rcx
movb $0x0, -0x191(%rbp)
xorl %eax, %eax
cmpq $0x4, %rcx
movb %al, -0x341(%rbp)
jbe 0xb661c
leaq -0xa8(%rbp), %rdi
movq -0x160(%rbp), %rax
movq -0x168(%rbp), %rsi
notq %rsi
addq %rax, %rsi
callq 0xc0060
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edx
leaq -0x190(%rbp), %rdi
movl $0x4, %ecx
callq 0x5380
jmp 0xb65ec
movb $0x1, -0x191(%rbp)
leaq 0x3ab03(%rip), %rsi     # 0xf10fd
leaq -0x190(%rbp), %rdi
callq 0x2a580
movb %al, -0x342(%rbp)
jmp 0xb660e
movb -0x342(%rbp), %al
movb %al, -0x341(%rbp)
jmp 0xb661c
movb -0x341(%rbp), %al
movb %al, -0x343(%rbp)
testb $0x1, -0x191(%rbp)
jne 0xb6633
jmp 0xb663f
leaq -0x190(%rbp), %rdi
callq 0x5200
movb -0x343(%rbp), %al
andb $0x1, %al
movb %al, -0x169(%rbp)
testb $0x1, -0x169(%rbp)
je 0xb6844
movq -0x168(%rbp), %rsi
leaq -0x20(%rbp), %rdi
callq 0xc0080
movq (%rax), %rax
cmpl $0x0, (%rax)
je 0xb66c2
movq -0x168(%rbp), %rsi
leaq -0x20(%rbp), %rdi
callq 0xc0080
movq (%rax), %rdi
addq $0x8, %rdi
callq 0x5270
movsbl (%rax), %eax
cmpl $0x23, %eax
je 0xb67c1
movq -0x168(%rbp), %rsi
leaq -0x20(%rbp), %rdi
callq 0xc0080
movq (%rax), %rdi
addq $0x8, %rdi
callq 0x50d0
movsbl (%rax), %eax
cmpl $0x7e, %eax
jne 0xb67c1
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
addq $0x8, %rdi
movq -0x168(%rbp), %rsi
callq 0xc00a0
movq (%rax), %rax
movq (%rax), %rax
movq %rax, -0x1a0(%rbp)
leaq -0x1c1(%rbp), %rdi
movq %rdi, -0x350(%rbp)
callq 0x55d0
movq -0x350(%rbp), %rdx
leaq 0x3ab37(%rip), %rsi     # 0xf123f
leaq -0x1c0(%rbp), %rdi
callq 0x19840
jmp 0xb6716
movq -0x1a0(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0xae910
jmp 0xb672b
leaq -0x1c0(%rbp), %rdi
callq 0x5200
leaq -0x1c1(%rbp), %rdi
callq 0x53c0
jmp 0xb67c1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6dd1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
testb $0x1, -0x191(%rbp)
jne 0xb6773
jmp 0xb677f
leaq -0x190(%rbp), %rdi
callq 0x5200
jmp 0xb6dd1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb67b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0x5200
leaq -0x1c1(%rbp), %rdi
callq 0x53c0
jmp 0xb6dd1
movq -0x168(%rbp), %rsi
leaq -0x20(%rbp), %rdi
callq 0xc0080
movq %rax, %rdi
movb $0x1, -0x1d9(%rbp)
leaq -0x1d9(%rbp), %rsi
callq 0xc0140
movb %dl, -0x359(%rbp)
movq %rax, -0x358(%rbp)
jmp 0xb67f6
movb -0x359(%rbp), %al
movq -0x358(%rbp), %rcx
movq %rcx, -0x1f0(%rbp)
movb %al, -0x1e8(%rbp)
movb -0x1e8(%rbp), %al
movb %al, -0x1d0(%rbp)
movq -0x1f0(%rbp), %rax
movq %rax, -0x1d8(%rbp)
leaq -0x128(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0xc00c0
jmp 0xb683f
jmp 0xb68c4
movq -0x168(%rbp), %rsi
leaq -0x20(%rbp), %rdi
callq 0xc0080
movq %rax, %rdi
movb $0x0, -0x201(%rbp)
leaq -0x201(%rbp), %rsi
callq 0xc0140
movb %dl, -0x369(%rbp)
movq %rax, -0x368(%rbp)
jmp 0xb6879
movb -0x369(%rbp), %al
movq -0x368(%rbp), %rcx
movq %rcx, -0x218(%rbp)
movb %al, -0x210(%rbp)
movb -0x210(%rbp), %al
movb %al, -0x1f8(%rbp)
movq -0x218(%rbp), %rax
movq %rax, -0x200(%rbp)
leaq -0x128(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0xc00c0
jmp 0xb68c2
jmp 0xb68c4
jmp 0xb68c6
movq -0x168(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x168(%rbp)
jmp 0xb655c
jmp 0xb68df
leaq -0x239(%rbp), %rdi
movq %rdi, -0x378(%rbp)
callq 0x55d0
movq -0x378(%rbp), %rdx
leaq 0x398ab(%rip), %rsi     # 0xf01ab
leaq -0x238(%rbp), %rdi
callq 0x19840
jmp 0xb690e
movl $0x48, %edi
callq 0x5340
movq %rax, -0x380(%rbp)
jmp 0xb6921
movb $0x1, -0x282(%rbp)
leaq -0x260(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x5150
jmp 0xb693d
leaq -0x281(%rbp), %rdi
movq %rdi, -0x388(%rbp)
callq 0x55d0
movq -0x388(%rbp), %rdx
leaq 0x3b042(%rip), %rsi     # 0xf19a0
leaq -0x280(%rbp), %rdi
callq 0x19840
jmp 0xb696c
movq -0x380(%rbp), %rdi
leaq -0x260(%rbp), %rsi
leaq -0x280(%rbp), %rdx
callq 0xbeae0
jmp 0xb6988
movq -0x380(%rbp), %rdx
movb $0x0, -0x282(%rbp)
leaq 0xa9d33(%rip), %rdi     # 0x1606d0
xorl %eax, %eax
movl %eax, %r8d
leaq -0x238(%rbp), %rsi
leaq -0x128(%rbp), %rcx
callq 0xc0170
jmp 0xb69b7
leaq -0x280(%rbp), %rdi
callq 0x5200
leaq -0x281(%rbp), %rdi
callq 0x53c0
leaq -0x260(%rbp), %rdi
callq 0x5200
leaq -0x238(%rbp), %rdi
callq 0x5200
leaq -0x239(%rbp), %rdi
callq 0x53c0
leaq -0x2a9(%rbp), %rdi
movq %rdi, -0x390(%rbp)
callq 0x55d0
movq -0x390(%rbp), %rdx
leaq 0x3a85a(%rip), %rsi     # 0xf126e
leaq -0x2a8(%rbp), %rdi
callq 0x19840
jmp 0xb6a22
movl $0x48, %edi
callq 0x5340
movq %rax, -0x398(%rbp)
jmp 0xb6a35
movb $0x1, -0x2d2(%rbp)
leaq 0xa9c8d(%rip), %rdi     # 0x1606d0
callq 0xa01e0
movl %eax, -0x39c(%rbp)
jmp 0xb6a50
leaq -0x2d1(%rbp), %rdi
movq %rdi, -0x3a8(%rbp)
callq 0x55d0
movq -0x3a8(%rbp), %rdx
leaq 0x387d6(%rip), %rsi     # 0xef247
leaq -0x2d0(%rbp), %rdi
callq 0x19840
jmp 0xb6a7f
movl -0x39c(%rbp), %esi
movq -0x398(%rbp), %rdi
leaq -0x2d0(%rbp), %rdx
callq 0xbdfe0
jmp 0xb6a9a
movb $0x0, -0x2d2(%rbp)
movl $0x48, %edi
callq 0x5340
movq %rax, -0x3b0(%rbp)
jmp 0xb6ab4
movb $0x1, -0x322(%rbp)
leaq -0x2f9(%rbp), %rdi
movq %rdi, -0x3b8(%rbp)
callq 0x55d0
movq -0x3b8(%rbp), %rdx
leaq 0x3a798(%rip), %rsi     # 0xf1274
leaq -0x2f8(%rbp), %rdi
callq 0x19840
jmp 0xb6aea
leaq -0x321(%rbp), %rdi
movq %rdi, -0x3c0(%rbp)
callq 0x55d0
movq -0x3c0(%rbp), %rdx
leaq 0x3ae95(%rip), %rsi     # 0xf19a0
leaq -0x320(%rbp), %rdi
callq 0x19840
jmp 0xb6b19
movq -0x3b0(%rbp), %rdi
leaq -0x2f8(%rbp), %rsi
leaq -0x320(%rbp), %rdx
callq 0xbeae0
jmp 0xb6b35
movq -0x3b0(%rbp), %rcx
movq -0x398(%rbp), %rdx
movb $0x0, -0x322(%rbp)
leaq 0xa9b7f(%rip), %rdi     # 0x1606d0
xorl %eax, %eax
movl %eax, %r8d
leaq -0x2a8(%rbp), %rsi
callq 0xbdf00
jmp 0xb6b64
leaq -0x320(%rbp), %rdi
callq 0x5200
leaq -0x321(%rbp), %rdi
callq 0x53c0
leaq -0x2f8(%rbp), %rdi
callq 0x5200
leaq -0x2f9(%rbp), %rdi
callq 0x53c0
leaq -0x2d0(%rbp), %rdi
callq 0x5200
leaq -0x2d1(%rbp), %rdi
callq 0x53c0
leaq -0x2a8(%rbp), %rdi
callq 0x5200
leaq -0x2a9(%rbp), %rdi
callq 0x53c0
leaq -0x128(%rbp), %rdi
callq 0xa4700
leaq -0xc8(%rbp), %rdi
callq 0xbef60
leaq -0x20(%rbp), %rdi
callq 0xc0250
addq $0x3c0, %rsp            # imm = 0x3C0
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6c92
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6c86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6c68
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6c50
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x280(%rbp), %rdi
callq 0x5200
leaq -0x281(%rbp), %rdi
callq 0x53c0
leaq -0x260(%rbp), %rdi
callq 0x5200
testb $0x1, -0x282(%rbp)
jne 0xb6c73
jmp 0xb6c84
movq -0x380(%rbp), %rdi
movl $0x48, %esi
callq 0x5350
jmp 0xb6c86
leaq -0x238(%rbp), %rdi
callq 0x5200
leaq -0x239(%rbp), %rdi
callq 0x53c0
jmp 0xb6dd1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6dc5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6db9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6d9b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6d8f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6d83
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6d59
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0xb6d41
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x5200
leaq -0x321(%rbp), %rdi
callq 0x53c0
leaq -0x2f8(%rbp), %rdi
callq 0x5200
leaq -0x2f9(%rbp), %rdi
callq 0x53c0
testb $0x1, -0x322(%rbp)
jne 0xb6d70
jmp 0xb6d81
movq -0x3b0(%rbp), %rdi
movl $0x48, %esi
callq 0x5350
jmp 0xb6d83
leaq -0x2d0(%rbp), %rdi
callq 0x5200
leaq -0x2d1(%rbp), %rdi
callq 0x53c0
testb $0x1, -0x2d2(%rbp)
jne 0xb6da6
jmp 0xb6db7
movq -0x398(%rbp), %rdi
movl $0x48, %esi
callq 0x5350
jmp 0xb6db9
leaq -0x2a8(%rbp), %rdi
callq 0x5200
leaq -0x2a9(%rbp), %rdi
callq 0x53c0
leaq -0x128(%rbp), %rdi
callq 0xa4700
leaq -0xc8(%rbp), %rdi
callq 0xbef60
leaq -0x20(%rbp), %rdi
callq 0xc0250
movq -0x80(%rbp), %rdi
callq 0x55b0
nopl (%rax,%rax)