// File: /workspace/github_c_makefile_star2_O0/sisshiki1969[P]monocc/src/codegen.c
// Function: emit_global
void emit_global(Type *type, Node *init) {
  if (!init) {
    // char str[];  => incomplete type
    if (is_array(type) && type->array_size == 0)
      error_at_token(init->token, "Incomplete type is not allowed.");
    fprintf(output, "\t.zero %d\n", sizeof_type(type));
    return;
  }
  long i = 0;
  Vector *vec;
  MemberInfo *member;
  int offset = 0;
  switch (type->ty) {
    case CHAR:
      fprintf(output, "\t.byte %ld\n", eval_const(init)->num_val);
      return;
    case SHORT:
    case USHORT:
      fprintf(output, "\t.word %ld\n", eval_const(init)->num_val);
      return;
    case INT:
    case UINT:
      fprintf(output, "\t.long %ld\n", eval_const(init)->num_val);
      return;
    case LONG:
    case ULONG:
      fprintf(output, "\t.quad %ld\n", eval_const(init)->num_val);
      return;

    case ARRAY:
      if (type->ptr_to->ty == CHAR) {
        if (init->kind == ND_STR) {
          // char str[] = "sample";
          int str_size = 1;
          fprintf(output, "\t.string \"");
          for (Token *t = init->token; t; t = t->next) {
            fprintf(output, "%.*s", t->len, t->str);
            str_size += t->len;
          }
          fprintf(output, "\"\n");
          int ary_size = type->array_size;
          if (ary_size > str_size)
            fprintf(output, "\t.zero %d\n", ary_size - str_size);
          return;
        }
      }
      if (init->kind != ND_INIT)
        error_at_node(init, "Unsupported initializer.");
      vec = init->nodes;
      type = type->ptr_to;
      for (int i = 0; i < vec_len(vec); i++) {
        emit_global(type, vec->data[i]);
      }
      return;

    case STRUCT:
      if (init->kind != ND_INIT)
        error_at_node(init, "Unsupported initializer.");
      vec = init->nodes;
      member = type->member;
      for (int i = 0; i < vec_len(vec); i++) {
        if (member->offset > offset) {
          fprintf(output, "\t.zero %d\n", member->offset - offset);
          offset = member->offset;
        }
        emit_global(member->type, vec->data[i]);
        offset += sizeof_type(member->type);
        member = member->next;
      }
      if (sizeof_type(type) > offset) {
        fprintf(output, "\t.zero %d\n", sizeof_type(type) - offset);
      }
      return;

    case PTR:
      if (type->ptr_to->ty == CHAR && init->kind == ND_STR) {
        // char *str = "sample";
        fprintf(output, "\t.quad .LS%06d\n", init->str_id);
        return;
      }
      if (init->kind == ND_ADDR && init->lhs->kind == ND_GVAR) {
        fprintf(output, "\t.quad %.*s\n", init->lhs->token->len,
                init->lhs->token->str);
        return;
      }
      if (init->kind == ND_CAST && init->lhs->kind == ND_NUM) {
        fprintf(output, "\t.quad %ld\n", init->lhs->num_val);
        return;
      }
      error_at_node(init, "Unsupported initializer.");
      return;

    default:
      error_at_node(init, "Unsupported initializer.");
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x3b39
movq -0x8(%rbp), %rdi
callq 0xd370
testb $0x1, %al
jne 0x3ae9
jmp 0x3b09
movq -0x8(%rbp), %rax
cmpl $0x0, 0x10(%rax)
jne 0x3b09
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rdi
leaq 0xbf20(%rip), %rsi      # 0xfa22
movb $0x0, %al
callq 0x5d20
leaq 0x11700(%rip), %rax     # 0x15210
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rdi
callq 0xd640
movq -0x50(%rbp), %rdi
movl %eax, %edx
leaq 0xbf15(%rip), %rsi      # 0xfa42
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
movq $0x0, -0x18(%rbp)
movl $0x0, -0x2c(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x58(%rbp)
subl $0xb, %eax
ja 0x3f8c
movq -0x58(%rbp), %rax
leaq 0xb5ae(%rip), %rcx      # 0xf118
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x11696(%rip), %rax     # 0x15210
movq (%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
callq 0x3980
movq -0x60(%rbp), %rdi
movq 0x20(%rax), %rdx
leaq 0xbeb4(%rip), %rsi      # 0xfa4d
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
leaq 0x11664(%rip), %rax     # 0x15210
movq (%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rdi
callq 0x3980
movq -0x68(%rbp), %rdi
movq 0x20(%rax), %rdx
leaq 0xbe8e(%rip), %rsi      # 0xfa59
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
leaq 0x11632(%rip), %rax     # 0x15210
movq (%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rdi
callq 0x3980
movq -0x70(%rbp), %rdi
movq 0x20(%rax), %rdx
leaq 0xbe68(%rip), %rsi      # 0xfa65
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
leaq 0x11600(%rip), %rax     # 0x15210
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rdi
callq 0x3980
movq -0x78(%rbp), %rdi
movq 0x20(%rax), %rdx
leaq 0xbe42(%rip), %rsi      # 0xfa71
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x1, (%rax)
jne 0x3d1c
movq -0x10(%rbp), %rax
cmpl $0x2, (%rax)
jne 0x3d1a
movl $0x1, -0x30(%rbp)
leaq 0x115a9(%rip), %rax     # 0x15210
movq (%rax), %rdi
leaq 0xbe0c(%rip), %rsi      # 0xfa7d
movb $0x0, %al
callq 0x10f0
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x3ccd
leaq 0x1157e(%rip), %rax     # 0x15210
movq (%rax), %rdi
movq -0x38(%rbp), %rax
movl 0x28(%rax), %edx
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rcx
leaq 0xbddd(%rip), %rsi      # 0xfa88
movb $0x0, %al
callq 0x10f0
movq -0x38(%rbp), %rax
movl 0x28(%rax), %eax
addl -0x30(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x3c84
leaq 0x1153c(%rip), %rax     # 0x15210
movq (%rax), %rdi
leaq 0xc3f2(%rip), %rsi      # 0x100d0
movb $0x0, %al
callq 0x10f0
movq -0x8(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jle 0x3d15
leaq 0x11512(%rip), %rax     # 0x15210
movq (%rax), %rdi
movl -0x3c(%rbp), %edx
subl -0x30(%rbp), %edx
leaq 0xbd34(%rip), %rsi      # 0xfa42
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
jmp 0x3d1c
movq -0x10(%rbp), %rax
cmpl $0x3, (%rax)
je 0x3d37
movq -0x10(%rbp), %rdi
leaq 0xcb1e(%rip), %rsi      # 0x1084e
movb $0x0, %al
callq 0x6040
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x8(%rbp)
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
movl %eax, -0x7c(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4000
movl %eax, %ecx
movl -0x7c(%rbp), %eax
cmpl %ecx, %eax
jge 0x3d91
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3ac0
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x3d56
jmp 0x3f9e
movq -0x10(%rbp), %rax
cmpl $0x3, (%rax)
je 0x3db1
movq -0x10(%rbp), %rdi
leaq 0xcaa4(%rip), %rsi      # 0x1084e
movb $0x0, %al
callq 0x6040
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x28(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
movl %eax, -0x80(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4000
movl %eax, %ecx
movl -0x80(%rbp), %eax
cmpl %ecx, %eax
jge 0x3e6c
movq -0x28(%rbp), %rax
movl 0x18(%rax), %eax
cmpl -0x2c(%rbp), %eax
jle 0x3e24
leaq 0x11411(%rip), %rax     # 0x15210
movq (%rax), %rdi
movq -0x28(%rbp), %rax
movl 0x18(%rax), %edx
subl -0x2c(%rbp), %edx
leaq 0xbc2f(%rip), %rsi      # 0xfa42
movb $0x0, %al
callq 0x10f0
movq -0x28(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, -0x2c(%rbp)
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3ac0
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xd640
addl -0x2c(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x28(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x3dd0
movq -0x8(%rbp), %rdi
callq 0xd640
cmpl -0x2c(%rbp), %eax
jle 0x3eae
leaq 0x1138f(%rip), %rax     # 0x15210
movq (%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x8(%rbp), %rdi
callq 0xd640
movq -0x88(%rbp), %rdi
movl %eax, %edx
subl -0x2c(%rbp), %edx
leaq 0xbb9b(%rip), %rsi      # 0xfa42
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x1, (%rax)
jne 0x3eed
movq -0x10(%rbp), %rax
cmpl $0x2, (%rax)
jne 0x3eed
leaq 0x11340(%rip), %rax     # 0x15210
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movl 0x28(%rax), %edx
leaq 0xbbac(%rip), %rsi      # 0xfa8d
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
movq -0x10(%rbp), %rax
cmpl $0x16, (%rax)
jne 0x3f3c
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x19, (%rax)
jne 0x3f3c
leaq 0x11306(%rip), %rax     # 0x15210
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x50(%rax), %rax
movl 0x28(%rax), %edx
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x50(%rax), %rax
movq 0x20(%rax), %rcx
leaq 0xbb6a(%rip), %rsi      # 0xfa9d
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
movq -0x10(%rbp), %rax
cmpl $0x1c, (%rax)
jne 0x3f78
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x1, (%rax)
jne 0x3f78
leaq 0x112b7(%rip), %rax     # 0x15210
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rdx
leaq 0xbb02(%rip), %rsi      # 0xfa71
movb $0x0, %al
callq 0x10f0
jmp 0x3f9e
movq -0x10(%rbp), %rdi
leaq 0xc8cb(%rip), %rsi      # 0x1084e
movb $0x0, %al
callq 0x6040
jmp 0x3f9e
movq -0x10(%rbp), %rdi
leaq 0xc8b7(%rip), %rsi      # 0x1084e
movb $0x0, %al
callq 0x6040
addq $0x90, %rsp
popq %rbp
retq
nopw (%rax,%rax)