// File: /workspace/github_c_makefile_star2_O2/pocari[P]compilerbook-9cc/codegen.c
// Function: gen_addr
static void gen_addr(Node *node) {
  // switchの警告を消すpragma
  #pragma clang diagnostic ignored "-Wswitch"
  switch(node->kind) {
    case ND_VAR:
      printfln("  # gen_addr start (var_name: %s, var_type: %s)", node->var->name, node->var->is_local ? "local" : "global");
      printfln("  # gen_addr-ND_VAR start");
      // compound_literaruの場合 この アドレス参照時のvarノードで初めて初期化されるので、そのチェック
      // &(int) { 1 } みたいなケース
      if (node->init) {
        gen(node->init);
      }
      if (node->var->is_local) {
        printfln("  mov rax, rbp");
        printfln("  sub rax, %d", node->var->offset);
        printfln("  push rax");
      } else {
        // global変数の場合は単にそのラベル(=変数名)をpushする
        printfln("  push offset %s", node->var->name);
      }
      printfln("  # gen_addr-ND_VAR end");
      printfln("  # gen_addr end");
      return;
    case ND_DEREF:
      printfln("  # gen_addr start (var_name: none)");
      printfln("  # gen_addr-ND_DEREF start");
      gen(node->lhs);
      printfln("  # gen_addr-ND_DEREF stop");
      printfln("  # gen_addr end");
      return;
    case ND_MEMBER:
      printfln("  # gen_addr start (struct-member: %s)", node->member->name);
      printfln("  # gen_addr-ND_MEMBER start");
      printfln("  # struct var ref start");
      gen_addr(node->lhs);
      printfln("  # struct var ref end");
      printfln("  # struct member ref start");
      printfln("  pop rax"); // 構造体変数のアドレス
      printfln("  add rax, %d", node->member->offset); //構造体のアドレスを元にそのメンバーの位置(オフセットを設定)
      printfln("  push rax"); // 構造体メンバーのアドレスをpush
      printfln("  # struct member ref end");
      printfln("  # gen_addr-ND_MEMBER stop");
      printfln("  # gen_addr end");
      return;
  }

 error("代入の左辺値が変数ではありません");
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movl (%rdi), %eax
cmpl $0x23, %eax
je 0x37c5
cmpl $0x1f, %eax
je 0x3794
cmpl $0x17, %eax
jne 0x386a
movq 0x78(%rbx), %rax
movq 0x8(%rax), %rsi
leaq 0x642c(%rip), %rcx      # 0x9b43
leaq 0x642b(%rip), %rdx      # 0x9b49
cmpb $0x0, 0x14(%rax)
cmovneq %rcx, %rdx
leaq 0x63e6(%rip), %rdi      # 0x9b13
xorl %eax, %eax
callq 0x26c5
leaq 0x6415(%rip), %rdi      # 0x9b50
xorl %eax, %eax
callq 0x26c5
movq 0x58(%rbx), %rdi
testq %rdi, %rdi
je 0x3750
callq 0x2755
movq 0x78(%rbx), %rax
cmpb $0x1, 0x14(%rax)
jne 0x3879
leaq 0x6405(%rip), %rdi      # 0x9b6a
xorl %eax, %eax
callq 0x26c5
movq 0x78(%rbx), %rax
movl 0x10(%rax), %esi
leaq 0x63ff(%rip), %rdi      # 0x9b79
xorl %eax, %eax
callq 0x26c5
leaq 0x5c2b(%rip), %rdi      # 0x93b3
xorl %eax, %eax
callq 0x26c5
jmp 0x388b
leaq 0x6426(%rip), %rdi      # 0x9bc1
xorl %eax, %eax
callq 0x26c5
leaq 0x643c(%rip), %rdi      # 0x9be5
xorl %eax, %eax
callq 0x26c5
movq 0x18(%rbx), %rdi
callq 0x2755
leaq 0x6441(%rip), %rdi      # 0x9c01
jmp 0x3892
movq 0x98(%rbx), %rax
movq 0x10(%rax), %rsi
leaq 0x6445(%rip), %rdi      # 0x9c1c
xorl %eax, %eax
callq 0x26c5
leaq 0x645e(%rip), %rdi      # 0x9c43
xorl %eax, %eax
callq 0x26c5
leaq 0x646d(%rip), %rdi      # 0x9c60
xorl %eax, %eax
callq 0x26c5
movq 0x18(%rbx), %rdi
callq 0x36e7
leaq 0x646f(%rip), %rdi      # 0x9c79
xorl %eax, %eax
callq 0x26c5
leaq 0x6478(%rip), %rdi      # 0x9c90
xorl %eax, %eax
callq 0x26c5
leaq 0x5c42(%rip), %rdi      # 0x9468
xorl %eax, %eax
callq 0x26c5
movq 0x98(%rbx), %rax
movl 0x18(%rax), %esi
leaq 0x646e(%rip), %rdi      # 0x9cac
xorl %eax, %eax
callq 0x26c5
leaq 0x5b67(%rip), %rdi      # 0x93b3
xorl %eax, %eax
callq 0x26c5
leaq 0x6460(%rip), %rdi      # 0x9cba
xorl %eax, %eax
callq 0x26c5
leaq 0x646c(%rip), %rdi      # 0x9cd4
jmp 0x3892
leaq 0x647f(%rip), %rdi      # 0x9cf0
xorl %eax, %eax
popq %rbx
jmp 0x485f
movq 0x8(%rax), %rsi
leaq 0x6303(%rip), %rdi      # 0x9b87
xorl %eax, %eax
callq 0x26c5
leaq 0x6306(%rip), %rdi      # 0x9b98
xorl %eax, %eax
callq 0x26c5
leaq 0x6310(%rip), %rdi      # 0x9bb0
xorl %eax, %eax
popq %rbx
jmp 0x26c5