// File: /workspace/github_c_makefile_star2_O0/pocari[P]compilerbook-9cc/codegen.c
// Function: gen_bin_op
static void gen_bin_op(Node *node) {
  gen(node->lhs);
  gen(node->rhs);

  printfln("  pop rdi");
  printfln("  pop rax");

  switch (node->kind) {
    case ND_ADD:
      printfln("  add rax, rdi");
      break;
    case ND_PTR_ADD:
      printfln("  imul rdi, %d", node->ty->ptr_to->size);
      printfln("  add rax, rdi");
      break;
    case ND_SUB:
      printfln("  sub rax, rdi");
      break;
    case ND_PTR_SUB:
      printfln("  imul rdi, %d", node->ty->ptr_to->size);
      printfln("  sub rax, rdi");
      break;
    case ND_PTR_DIFF:
      // 普通に引き算した結果をポインタの指す先の型のサイズで割って、個数に変換
      // 例)
      // int ary[] = { ... };
      // int *third = ary + 3;
      // int z = third - ary;
      // z が 3になるようにする。
      //
      // rax - rdi
      // の結果が
      // rax
      // に入るので、
      // raxをlhsのポインターが指す型のサイズで割った商をraxに入れる。
      // このため、割る数(rdi)に「ポインターが指す方のサイズ」を設定する必要がある
      printfln("  sub rax, rdi");
      printfln("  cqo");
      printfln("  mov rdi, %d", node->lhs->ty->ptr_to->size);
      printfln("  idiv rdi");
      break;
    case ND_MUL:
      printfln("  imul rax, rdi");
      break;
    case ND_DIV:
      printfln("  cqo");
      printfln("  idiv rdi");
      break;
    case ND_MOD:
      printfln("  cqo");
      printfln("  idiv rdi");
      printfln("  mov rax, rdx");
      break;
    case ND_LT:
      printfln("  cmp rax, rdi");
      printfln("  setl al");
      printfln("  movzb rax, al");
      break;
    case ND_LTE:
      printfln("  cmp rax, rdi");
      printfln("  setle al");
      printfln("  movzb rax, al");
      break;
    case ND_EQL:
      printfln("  cmp rax, rdi");
      printfln("  sete al");
      printfln("  movzb rax, al");
      break;
    case ND_NOT_EQL:
      printfln("  cmp rax, rdi");
      printfln("  setne al");
      printfln("  movzb rax, al");
      break;
    case ND_BIT_AND:
      printfln("  and rax, rdi");
      break;
    case ND_BIT_OR:
      printfln("  or rax, rdi");
      break;
    case ND_BIT_XOR:
      printfln("  xor rax, rdi");
      break;
    case ND_A_LSHIFT:
      // シフトする数はcl(rcxの下位8bit)に設定すると決まってるらしい
      printfln("  mov cl, dil");
      printfln("  sal rax, cl");
      break;
    case ND_A_RSHIFT:
      printfln("  mov cl, dil");
      printfln("  sar rax, cl");
      break;
    default:
      error("予期しないNodeです。 kind: %d", node->kind);
  }
  printfln("  push rax");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x2950
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x2950
leaq 0xbdf5(%rip), %rdi      # 0xfd12
xorl %eax, %eax
movb %al, -0x11(%rbp)
callq 0x2320
movb -0x11(%rbp), %al
leaq 0xb4af(%rip), %rdi      # 0xf3e0
callq 0x2320
movq -0x8(%rbp), %rax
movl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x10(%rbp)
subl $0x12, %eax
ja 0x41c2
movq -0x10(%rbp), %rax
leaq 0xb148(%rip), %rcx      # 0xf0a0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0xbe9c(%rip), %rdi      # 0xfe04
movb $0x0, %al
callq 0x2320
jmp 0x41d6
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rax
movl 0x4(%rax), %esi
leaq 0xbe89(%rip), %rdi      # 0xfe13
movb $0x0, %al
callq 0x2320
leaq 0xbe6c(%rip), %rdi      # 0xfe04
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbe77(%rip), %rdi      # 0xfe22
movb $0x0, %al
callq 0x2320
jmp 0x41d6
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rax
movl 0x4(%rax), %esi
leaq 0xbe46(%rip), %rdi      # 0xfe13
movb $0x0, %al
callq 0x2320
leaq 0xbe47(%rip), %rdi      # 0xfe22
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbe34(%rip), %rdi      # 0xfe22
movb $0x0, %al
callq 0x2320
leaq 0xbe35(%rip), %rdi      # 0xfe31
movb $0x0, %al
callq 0x2320
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rax
movl 0x4(%rax), %esi
leaq 0xbe1a(%rip), %rdi      # 0xfe37
movb $0x0, %al
callq 0x2320
leaq 0xbe1a(%rip), %rdi      # 0xfe45
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbe12(%rip), %rdi      # 0xfe50
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbde0(%rip), %rdi      # 0xfe31
movb $0x0, %al
callq 0x2320
leaq 0xbde6(%rip), %rdi      # 0xfe45
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbdbf(%rip), %rdi      # 0xfe31
movb $0x0, %al
callq 0x2320
leaq 0xbdc5(%rip), %rdi      # 0xfe45
movb $0x0, %al
callq 0x2320
leaq 0xbdd2(%rip), %rdi      # 0xfe60
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbdce(%rip), %rdi      # 0xfe6f
movb $0x0, %al
callq 0x2320
leaq 0xbdcf(%rip), %rdi      # 0xfe7e
movb $0x0, %al
callq 0x2320
leaq 0xb890(%rip), %rdi      # 0xf94d
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbd9f(%rip), %rdi      # 0xfe6f
movb $0x0, %al
callq 0x2320
leaq 0xbdaa(%rip), %rdi      # 0xfe88
movb $0x0, %al
callq 0x2320
leaq 0xb861(%rip), %rdi      # 0xf94d
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbd70(%rip), %rdi      # 0xfe6f
movb $0x0, %al
callq 0x2320
leaq 0xb8c1(%rip), %rdi      # 0xf9ce
movb $0x0, %al
callq 0x2320
leaq 0xb832(%rip), %rdi      # 0xf94d
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbd41(%rip), %rdi      # 0xfe6f
movb $0x0, %al
callq 0x2320
leaq 0xbc6b(%rip), %rdi      # 0xfda7
movb $0x0, %al
callq 0x2320
leaq 0xb803(%rip), %rdi      # 0xf94d
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbd36(%rip), %rdi      # 0xfe93
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbd35(%rip), %rdi      # 0xfea2
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbd33(%rip), %rdi      # 0xfeb0
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbd32(%rip), %rdi      # 0xfebf
movb $0x0, %al
callq 0x2320
leaq 0xbd32(%rip), %rdi      # 0xfecd
movb $0x0, %al
callq 0x2320
jmp 0x41d6
leaq 0xbd14(%rip), %rdi      # 0xfebf
movb $0x0, %al
callq 0x2320
leaq 0xbd22(%rip), %rdi      # 0xfedb
movb $0x0, %al
callq 0x2320
jmp 0x41d6
movq -0x8(%rbp), %rax
movl (%rax), %esi
leaq 0xbd1a(%rip), %rdi      # 0xfee9
movb $0x0, %al
callq 0x65d0
leaq 0xb136(%rip), %rdi      # 0xf313
movb $0x0, %al
callq 0x2320
addq $0x20, %rsp
popq %rbp
retq
nopw (%rax,%rax)