// File: /workspace/github_c_makefile_star2_O0/pocari[P]compilerbook-9cc/codegen.c
// Function: codegen_data
static void codegen_data(Program *pgm) {
  for (VarList *v = pgm->global_var; v; v = v->next) {
    Var *var = v->var;
    if (!var->is_static) {
      printfln(".global %s", var->name);
    }
  }

  // https://ja.wikipedia.org/wiki/.bss
  // 初期化敷なしのグローバル変数や static 変数は.bssセクション、それ以外は .data セクションに置くらしい
  //
  // どっちにしろ zero 初期化するならどっちでもいいような気もしたが、
  // .data セクションで使う初期化用の値は、 rom領域に置かれて、それをプログラム起動時にram上にコピーされるらしい。
  // 一方.bssに置かれた変数はもともとzero初期化用途決まっているので、.dataで使われたようなrom領域がない分メモリや実行時の効率がいいらしい。
  // http://blog.kmckk.com/archives/1242072.html
  // > .dataセクションに割り当られた変数はRAMだけでなく、その初期値の保持のためにROMも占有します。
  // とのことらしい
  printfln(".bss");
  for (VarList *v = pgm->global_var; v; v = v->next) {
    Var *var = v->var;
    if (!var->initializer) {
      // 初期化式が無いもののみ対象

      // ここの .align については
      // http://www.swlab.cs.okayama-u.ac.jp/~nom/lect/p3/what-is-directive.html
      // 参照
      // 上の説明では、mipsなので 「.align n が 2のn乗にアライン」とあるが、x86では単に「nバイトアライン」という意味らしい
      printfln(".align %d", var->type->align);
      printfln("%s:", var->name);
      printfln("  .zero %d", var->type->size);
      continue;
    }
  }

  printfln(".data");
  for (VarList *v = pgm->global_var; v; v = v->next) {
    Var *var = v->var;
    if (!var->initializer) {
      continue;
    }

    printfln(".align %d", var->type->align);
    printfln("%s:", var->name);
    for (Initializer *i = var->initializer; i; i = i->next) {
      if (i->label) {
        // 別のグローバル変数の参照の場合
        printfln("  .quad %s+%ld", i->label, i->addend);
      } else if (i->sz == 1) {
        // 文字の場合
        printfln("  .byte %ld", i->val);
      } else {
        printfln("  .%dbyte %ld", i->sz, i->val);
      }
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x2429
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
testb $0x1, 0x20(%rax)
jne 0x241a
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0xccf0(%rip), %rdi      # 0xf103
movb $0x0, %al
callq 0x2320
jmp 0x241c
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x10(%rbp)
jmp 0x23e7
leaq 0xccde(%rip), %rdi      # 0xf10e
movb $0x0, %al
callq 0x2320
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x24b7
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x24a8
movq -0x28(%rbp), %rax
movq (%rax), %rax
movl 0x8(%rax), %esi
leaq 0xcca2(%rip), %rdi      # 0xf113
movb $0x0, %al
callq 0x2320
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0xce0b(%rip), %rdi      # 0xf292
movb $0x0, %al
callq 0x2320
movq -0x28(%rbp), %rax
movq (%rax), %rax
movl 0x4(%rax), %esi
leaq 0xcc7e(%rip), %rdi      # 0xf11d
movb $0x0, %al
callq 0x2320
jmp 0x24aa
jmp 0x24aa
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x2442
leaq 0xcc6a(%rip), %rdi      # 0xf128
movb $0x0, %al
callq 0x2320
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x25c8
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x24f7
jmp 0x25b8
movq -0x38(%rbp), %rax
movq (%rax), %rax
movl 0x8(%rax), %esi
leaq 0xcc0b(%rip), %rdi      # 0xf113
movb $0x0, %al
callq 0x2320
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0xcd74(%rip), %rdi      # 0xf292
movb $0x0, %al
callq 0x2320
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x25b6
movq -0x40(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x2563
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x40(%rbp), %rax
movq 0x20(%rax), %rdx
leaq 0xcbd4(%rip), %rdi      # 0xf12e
movb $0x0, %al
callq 0x2320
jmp 0x25a4
movq -0x40(%rbp), %rax
cmpl $0x1, 0x8(%rax)
jne 0x2585
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rsi
leaq 0xcbc1(%rip), %rdi      # 0xf13d
movb $0x0, %al
callq 0x2320
jmp 0x25a2
movq -0x40(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdx
leaq 0xcbae(%rip), %rdi      # 0xf149
movb $0x0, %al
callq 0x2320
jmp 0x25a4
jmp 0x25a6
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x2531
jmp 0x25b8
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x24d0
addq $0x40, %rsp
popq %rbp
retq
nop