// File: /workspace/github_c_makefile_star2_O1/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 0x38ba
cmpl $0x1f, %eax
je 0x3889
cmpl $0x17, %eax
jne 0x395f
movq 0x78(%rbx), %rax
movq 0x8(%rax), %rsi
leaq 0x8337(%rip), %rcx      # 0xbb43
leaq 0x8336(%rip), %rdx      # 0xbb49
cmpb $0x0, 0x14(%rax)
cmovneq %rcx, %rdx
leaq 0x82f1(%rip), %rdi      # 0xbb13
xorl %eax, %eax
callq 0x27b5
leaq 0x8320(%rip), %rdi      # 0xbb50
xorl %eax, %eax
callq 0x27b5
movq 0x58(%rbx), %rdi
testq %rdi, %rdi
je 0x3845
callq 0x2847
movq 0x78(%rbx), %rax
cmpb $0x1, 0x14(%rax)
jne 0x396e
leaq 0x8310(%rip), %rdi      # 0xbb6a
xorl %eax, %eax
callq 0x27b5
movq 0x78(%rbx), %rax
movl 0x10(%rax), %esi
leaq 0x830a(%rip), %rdi      # 0xbb79
xorl %eax, %eax
callq 0x27b5
leaq 0x7b36(%rip), %rdi      # 0xb3b3
xorl %eax, %eax
callq 0x27b5
jmp 0x3980
leaq 0x8331(%rip), %rdi      # 0xbbc1
xorl %eax, %eax
callq 0x27b5
leaq 0x8347(%rip), %rdi      # 0xbbe5
xorl %eax, %eax
callq 0x27b5
movq 0x18(%rbx), %rdi
callq 0x2847
leaq 0x834c(%rip), %rdi      # 0xbc01
jmp 0x3987
movq 0x98(%rbx), %rax
movq 0x10(%rax), %rsi
leaq 0x8350(%rip), %rdi      # 0xbc1c
xorl %eax, %eax
callq 0x27b5
leaq 0x8369(%rip), %rdi      # 0xbc43
xorl %eax, %eax
callq 0x27b5
leaq 0x8378(%rip), %rdi      # 0xbc60
xorl %eax, %eax
callq 0x27b5
movq 0x18(%rbx), %rdi
callq 0x37dc
leaq 0x837a(%rip), %rdi      # 0xbc79
xorl %eax, %eax
callq 0x27b5
leaq 0x8383(%rip), %rdi      # 0xbc90
xorl %eax, %eax
callq 0x27b5
leaq 0x7b4d(%rip), %rdi      # 0xb468
xorl %eax, %eax
callq 0x27b5
movq 0x98(%rbx), %rax
movl 0x18(%rax), %esi
leaq 0x8379(%rip), %rdi      # 0xbcac
xorl %eax, %eax
callq 0x27b5
leaq 0x7a72(%rip), %rdi      # 0xb3b3
xorl %eax, %eax
callq 0x27b5
leaq 0x836b(%rip), %rdi      # 0xbcba
xorl %eax, %eax
callq 0x27b5
leaq 0x8377(%rip), %rdi      # 0xbcd4
jmp 0x3987
leaq 0x838a(%rip), %rdi      # 0xbcf0
xorl %eax, %eax
popq %rbx
jmp 0x4a3b
movq 0x8(%rax), %rsi
leaq 0x820e(%rip), %rdi      # 0xbb87
xorl %eax, %eax
callq 0x27b5
leaq 0x8211(%rip), %rdi      # 0xbb98
xorl %eax, %eax
callq 0x27b5
leaq 0x821b(%rip), %rdi      # 0xbbb0
xorl %eax, %eax
popq %rbx
jmp 0x27b5