// File: /workspace/github_c_makefile_star2_O3/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 0x38b2
cmpl $0x1f, %eax
je 0x3881
cmpl $0x17, %eax
jne 0x3957
movq 0x78(%rbx), %rax
movq 0x8(%rax), %rsi
leaq 0x833f(%rip), %rcx      # 0xbb43
leaq 0x833e(%rip), %rdx      # 0xbb49
cmpb $0x0, 0x14(%rax)
cmovneq %rcx, %rdx
leaq 0x82f9(%rip), %rdi      # 0xbb13
xorl %eax, %eax
callq 0x27b5
leaq 0x8328(%rip), %rdi      # 0xbb50
xorl %eax, %eax
callq 0x27b5
movq 0x58(%rbx), %rdi
testq %rdi, %rdi
je 0x383d
callq 0x2847
movq 0x78(%rbx), %rax
cmpb $0x1, 0x14(%rax)
jne 0x3966
leaq 0x8318(%rip), %rdi      # 0xbb6a
xorl %eax, %eax
callq 0x27b5
movq 0x78(%rbx), %rax
movl 0x10(%rax), %esi
leaq 0x8312(%rip), %rdi      # 0xbb79
xorl %eax, %eax
callq 0x27b5
leaq 0x7b3e(%rip), %rdi      # 0xb3b3
xorl %eax, %eax
callq 0x27b5
jmp 0x3978
leaq 0x8339(%rip), %rdi      # 0xbbc1
xorl %eax, %eax
callq 0x27b5
leaq 0x834f(%rip), %rdi      # 0xbbe5
xorl %eax, %eax
callq 0x27b5
movq 0x18(%rbx), %rdi
callq 0x2847
leaq 0x8354(%rip), %rdi      # 0xbc01
jmp 0x397f
movq 0x98(%rbx), %rax
movq 0x10(%rax), %rsi
leaq 0x8358(%rip), %rdi      # 0xbc1c
xorl %eax, %eax
callq 0x27b5
leaq 0x8371(%rip), %rdi      # 0xbc43
xorl %eax, %eax
callq 0x27b5
leaq 0x8380(%rip), %rdi      # 0xbc60
xorl %eax, %eax
callq 0x27b5
movq 0x18(%rbx), %rdi
callq 0x37d4
leaq 0x8382(%rip), %rdi      # 0xbc79
xorl %eax, %eax
callq 0x27b5
leaq 0x838b(%rip), %rdi      # 0xbc90
xorl %eax, %eax
callq 0x27b5
leaq 0x7b55(%rip), %rdi      # 0xb468
xorl %eax, %eax
callq 0x27b5
movq 0x98(%rbx), %rax
movl 0x18(%rax), %esi
leaq 0x8381(%rip), %rdi      # 0xbcac
xorl %eax, %eax
callq 0x27b5
leaq 0x7a7a(%rip), %rdi      # 0xb3b3
xorl %eax, %eax
callq 0x27b5
leaq 0x8373(%rip), %rdi      # 0xbcba
xorl %eax, %eax
callq 0x27b5
leaq 0x837f(%rip), %rdi      # 0xbcd4
jmp 0x397f
leaq 0x8392(%rip), %rdi      # 0xbcf0
xorl %eax, %eax
popq %rbx
jmp 0x4a3b
movq 0x8(%rax), %rsi
leaq 0x8216(%rip), %rdi      # 0xbb87
xorl %eax, %eax
callq 0x27b5
leaq 0x8219(%rip), %rdi      # 0xbb98
xorl %eax, %eax
callq 0x27b5
leaq 0x8223(%rip), %rdi      # 0xbbb0
xorl %eax, %eax
popq %rbx
jmp 0x27b5