// File: /workspace/github_c_makefile_star2_O3/sisshiki1969[P]monocc/src/codegen.c
// Function: gen_fdecl
void gen_fdecl(Node *node) {
  if (!node->lhs) return;
  current_fn = node;

  fprintf(output, "%.*s:\n", node->token->len, node->token->str);
  // Prologue
  fprintf(output, "\tpush rbp\n");
  fprintf(output, "\tmov  rbp, rsp\n");
  int offset = ((node->offset - 1) & (-16)) + 16;
  fprintf(output, "\tsub  rsp, %d\n", offset);
  fprintf(output, "\tmov  [rbp -  8], r12\n");
  fprintf(output, "\tmov  [rbp - 16], r13\n");
  fprintf(output, "\tmov  [rbp - 24], r14\n");
  fprintf(output, "\tmov  [rbp - 32], r15\n");

  if (node->type->variadic) {
    fprintf(output, "\tmov  [rbp - 128], rdi\n");
    fprintf(output, "\tmov  [rbp - 120], rsi\n");
    fprintf(output, "\tmov  [rbp - 112], rdx\n");
    fprintf(output, "\tmov  [rbp - 104], rcx\n");
    fprintf(output, "\tmov  [rbp -  96], r8\n");
    fprintf(output, "\tmov  [rbp -  88], r9\n");
  }

  int len = vec_len(node->nodes);
  Node **params = node->nodes->data;
  for (int i = 0; i < len; i++) {
    fprintf(output, "\tmov  [rbp - %d], %s\n", params[i]->lvar->offset,
            registers[reg_size(type(params[i]))][i]);
  }

  gen_block(node->lhs);

  // Epilogue
  emit_return_label(node);
  fprintf(output, "\tmov  r12, [rbp -  8]\n");
  fprintf(output, "\tmov  r13, [rbp - 16]\n");
  fprintf(output, "\tmov  r14, [rbp - 24]\n");
  fprintf(output, "\tmov  r15, [rbp - 32]\n");
  fprintf(output, "\tmov  rsp, rbp\n");
  fprintf(output, "\tpop  rbp\n");
  fprintf(output, "\tret\n");
}

// Assembly:
cmpq $0x0, 0x8(%rdi)
je 0x322e
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq %rdi, 0x10296(%rip)     # 0x131f8
leaq 0x102b7(%rip), %r15     # 0x13220
movq (%r15), %rdi
movq 0x50(%rbx), %rax
movl 0x28(%rax), %edx
movq 0x20(%rax), %rcx
leaq 0x9216(%rip), %rsi      # 0xc194
xorl %eax, %eax
callq 0x10f0
movq (%r15), %rcx
leaq 0x964d(%rip), %rdi      # 0xc5dc
movl $0xa, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x963f(%rip), %rdi      # 0xc5e7
movl $0xf, %esi
movl $0x1, %edx
callq 0x1190
movl 0x38(%rbx), %edx
decl %edx
andl $-0x10, %edx
addl $0x10, %edx
movq (%r15), %rdi
leaq 0x962b(%rip), %rsi      # 0xc5f7
xorl %eax, %eax
callq 0x10f0
movq (%r15), %rcx
leaq 0x9629(%rip), %rdi      # 0xc606
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9627(%rip), %rdi      # 0xc61d
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9625(%rip), %rdi      # 0xc634
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9623(%rip), %rdi      # 0xc64b
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq 0x58(%rbx), %rax
cmpb $0x1, 0x38(%rax)
jne 0x30db
movq (%r15), %rcx
leaq 0x9613(%rip), %rdi      # 0xc662
movl $0x17, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9612(%rip), %rdi      # 0xc67a
movl $0x17, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9611(%rip), %rdi      # 0xc692
movl $0x17, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9610(%rip), %rdi      # 0xc6aa
movl $0x17, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x960f(%rip), %rdi      # 0xc6c2
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x960d(%rip), %rdi      # 0xc6d9
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq %rbx, (%rsp)
movq 0x48(%rbx), %rdi
callq 0x3f3a
testl %eax, %eax
jle 0x3148
movq (%rsp), %rcx
movq 0x48(%rcx), %rcx
movq (%rcx), %r13
movl %eax, %ebx
xorl %r12d, %r12d
movq (%r15), %r14
movq (%r13,%r12,8), %rdi
movq 0x30(%rdi), %rax
movl 0x18(%rax), %ebp
callq 0xb225
movq %rax, %rdi
callq 0x1b38
cltq
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
addq 0xfebf(%rip), %rax      # 0x12fe8
movq (%rax,%r12,8), %rcx
movq %r14, %rdi
leaq 0x95b9(%rip), %rsi      # 0xc6f0
movl %ebp, %edx
xorl %eax, %eax
callq 0x10f0
incq %r12
cmpq %r12, %rbx
jne 0x30fc
movq (%rsp), %rbx
movq 0x8(%rbx), %rdi
callq 0x2c62
movq (%r15), %rdi
movq 0x50(%rbx), %rax
movl 0x28(%rax), %edx
movq 0x20(%rax), %rcx
leaq 0x9020(%rip), %rsi      # 0xc18a
xorl %eax, %eax
callq 0x10f0
movq (%r15), %rcx
leaq 0x958b(%rip), %rdi      # 0xc706
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9589(%rip), %rdi      # 0xc71d
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9587(%rip), %rdi      # 0xc734
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9585(%rip), %rdi      # 0xc74b
movl $0x16, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x9583(%rip), %rdi      # 0xc762
movl $0xf, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x957a(%rip), %rdi      # 0xc772
movl $0xa, %esi
movl $0x1, %edx
callq 0x1190
movq (%r15), %rcx
leaq 0x956c(%rip), %rdi      # 0xc77d
movl $0x5, %esi
movl $0x1, %edx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1190
retq