// File: /workspace/github_c_makefile_star2_O3/sisshiki1969[P]monocc/src/codegen.c
// Function: gen_call
void gen_call(Node *node) {
  // function call
  // kind: ND_CALL
  // lhs: callee (ND_IDENT)
  // nodes: vector of arguments
  // token: Token *token
  // type: return type of callee
  // TODO: Currently, only ND_IDENT is allowed as a callee.
  int len = vec_len(node->nodes);
  Node **args = node->nodes->data;
  for (int i = len - 1; i >= 0; i--) {
    gen(args[i]);
  }
  for (int i = 0; i < len; i++) {
    fprintf(output, "\tpop  %s\n", registers[0][i]);
  }
  Token *name;
  if (node->lhs->kind == ND_IDENT) {
    name = node->lhs->token;
    if (cmp_token_str(name, "__builtin_va_start")) {
      builtin_va_start(node);
      return;
    }
  } else {
    error_at_node(node->lhs, "Currently, callee must be function designator.");
  }

  char *label1 = new_label();
  char *label2 = new_label();
  fprintf(output, "\tmov  rax, rsp\n");
  fprintf(output, "\tand  rax, 15\n");
  fprintf(output, "\tjnz  %s\n", label1);
  fprintf(output, "\tmov  rax, 0\n");
  fprintf(output, "\tcall %.*s\n", name->len, name->str);
  emit_jmp(label2);

  emit_label(label1);
  fprintf(output, "\tsub  rsp, 8\n");
  fprintf(output, "\tmov  rax, 0\n");
  fprintf(output, "\tcall %.*s\n", name->len, name->str);
  fprintf(output, "\tadd  rsp, 8\n");

  emit_label(label2);
  fprintf(output, "\tpush rax\n");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x48(%rdi), %rdi
callq 0x3f3a
testl %eax, %eax
jle 0x2d9b
movl %eax, %ebp
movq 0x48(%rbx), %rax
movq (%rax), %r14
movl %ebp, %r15d
leaq 0x1(%r15), %r12
movq -0x10(%r14,%r12,8), %rdi
callq 0x1eaf
decq %r12
cmpq $0x1, %r12
ja 0x2d52
testl %ebp, %ebp
jle 0x2d9b
leaq 0x104b0(%rip), %r12     # 0x13220
leaq 0x103a9(%rip), %r13     # 0x13120
leaq 0x97b3(%rip), %r14      # 0xc531
xorl %ebp, %ebp
movq (%r12), %rdi
movq (%r13,%rbp,8), %rdx
movq %r14, %rsi
xorl %eax, %eax
callq 0x10f0
incq %rbp
cmpq %rbp, %r15
jne 0x2d80
movq 0x8(%rbx), %rdi
cmpl $0x0, (%rdi)
je 0x2db4
leaq 0x97a3(%rip), %rsi      # 0xc54e
xorl %eax, %eax
callq 0x5502
jmp 0x2de1
movq 0x50(%rdi), %r14
leaq 0x977c(%rip), %rsi      # 0xc53b
movq %r14, %rdi
callq 0x61b4
testb %al, %al
je 0x2de1
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2c9c
callq 0x1958
movq %rax, %r15
callq 0x1958
movq %rax, %rbx
leaq 0x10428(%rip), %r12     # 0x13220
movq (%r12), %rcx
leaq 0x977a(%rip), %rdi      # 0xc57d
movl $0xf, %esi
movl $0x1, %edx
callq 0x1190
movq (%r12), %rcx
leaq 0x9770(%rip), %rdi      # 0xc58d
movl $0xe, %esi
movl $0x1, %edx
callq 0x1190
movq (%r12), %rdi
leaq 0x9765(%rip), %rsi      # 0xc59c
movq %r15, %rdx
xorl %eax, %eax
callq 0x10f0
movq (%r12), %rcx
leaq 0x975a(%rip), %rdi      # 0xc5a6
movl $0xd, %esi
movl $0x1, %edx
callq 0x1190
movq (%r12), %rdi
movl 0x28(%r14), %edx
movq 0x20(%r14), %rcx
leaq 0x9746(%rip), %r13      # 0xc5b4
movq %r13, %rsi
xorl %eax, %eax
callq 0x10f0
movq (%r12), %rdi
leaq 0x92fd(%rip), %rsi      # 0xc180
movq %rbx, %rdx
xorl %eax, %eax
callq 0x10f0
movq (%r12), %rdi
leaq 0x92e3(%rip), %rbp      # 0xc17b
movq %rbp, %rsi
movq %r15, %rdx
xorl %eax, %eax
callq 0x10f0
movq (%r12), %rcx
leaq 0x9710(%rip), %rdi      # 0xc5c0
movl $0xd, %esi
movl $0x1, %edx
callq 0x1190
movq (%r12), %rcx
movl $0xd, %esi
movl $0x1, %edx
leaq 0x96d2(%rip), %rdi      # 0xc5a6
callq 0x1190
movq (%r12), %rdi
movl 0x28(%r14), %edx
movq 0x20(%r14), %rcx
movq %r13, %rsi
xorl %eax, %eax
callq 0x10f0
movq (%r12), %rcx
leaq 0x96d4(%rip), %rdi      # 0xc5ce
movl $0xd, %esi
movl $0x1, %edx
callq 0x1190
movq (%r12), %rdi
movq %rbp, %rsi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x10f0
movq (%r12), %rcx
leaq 0x9414(%rip), %rdi      # 0xc339
movl $0xa, %esi
movl $0x1, %edx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1190