// File: /workspace/github_c_makefile_star2_O1/ejunjsh[P]mycc/cg.c
// Function: cgloadvar
int cgloadvar(struct symtable *sym, int op) {
  int r, postreg, offset = 1;

  // 分配一个新的寄存器
  r = cgallocreg();

  // 如果是指针，用指针指向的类型大小作为++或--的大小
  // 如果不是，那大小就是1
  if (ptrtype(sym->type))
    offset = typesize(value_at(sym->type), sym->ctype);

  // 如果是--，就把它变成负数
  if (op == A_PREDEC || op == A_POSTDEC)
    offset = -offset;

  // 如果是++i
  if (op == A_PREINC || op == A_PREDEC) {
    // 获取变量地址
    if (sym->class == C_LOCAL || sym->class == C_PARAM)
      fprintf(Outfile, "\tleaq\t%d(%%rbp), %s\n", sym->stu.st_posn, reglist[r]);
    else
      fprintf(Outfile, "\tleaq\t%s(%%rip), %s\n", sym->name, reglist[r]);

    // 改变那个地址里面的值
    switch (sym->size) {
    case 1:
      fprintf(Outfile, "\taddb\t$%d,(%s)\n", offset, reglist[r]);
      break;
    case 4:
      fprintf(Outfile, "\taddl\t$%d,(%s)\n", offset, reglist[r]);
      break;
    case 8:
      fprintf(Outfile, "\taddq\t$%d,(%s)\n", offset, reglist[r]);
      break;
    }
  }

  // 加载变量值到寄存器
  if (sym->class == C_LOCAL || sym->class == C_PARAM) {
    switch (sym->size) {
    case 1:
      fprintf(Outfile, "\tmovzbq\t%d(%%rbp), %s\n", sym->stu.st_posn, reglist[r]);
      break;
    case 4:
      fprintf(Outfile, "\tmovslq\t%d(%%rbp), %s\n", sym->stu.st_posn, reglist[r]);
      break;
    case 8:
      fprintf(Outfile, "\tmovq\t%d(%%rbp), %s\n", sym->stu.st_posn, reglist[r]);
    }
  } else {
    switch (sym->size) {
    case 1:
      fprintf(Outfile, "\tmovzbq\t%s(%%rip), %s\n", sym->name, reglist[r]);
      break;
    case 4:
      fprintf(Outfile, "\tmovslq\t%s(%%rip), %s\n", sym->name, reglist[r]);
      break;
    case 8:
      fprintf(Outfile, "\tmovq\t%s(%%rip), %s\n", sym->name, reglist[r]);
    }
  }

  // 如果是i++
  if (op == A_POSTINC || op == A_POSTDEC) {
    postreg = cgallocreg(); // 分配一个新寄存器

    // 获取变量地址
    if (sym->class == C_LOCAL || sym->class == C_PARAM)
      fprintf(Outfile, "\tleaq\t%d(%%rbp), %s\n", sym->stu.st_posn,
	      reglist[postreg]);
    else
      fprintf(Outfile, "\tleaq\t%s(%%rip), %s\n", sym->name,
	      reglist[postreg]);

    // 改变那个地址里面的值
    switch (sym->size) {
    case 1:
      fprintf(Outfile, "\taddb\t$%d,(%s)\n", offset, reglist[postreg]);
      break;
    case 4:
      fprintf(Outfile, "\taddl\t$%d,(%s)\n", offset, reglist[postreg]);
      break;
    case 8:
      fprintf(Outfile, "\taddq\t$%d,(%s)\n", offset, reglist[postreg]);
      break;
    }

    // 最后释放这个寄存器
    cgfreereg(postreg);
  }

  // 返回带有值的寄存器
  return (r);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %esi, %r12d
movq %rdi, %r14
callq 0x24e7
movl %eax, %ebx
movl 0x10(%r14), %edi
callq 0x8dcb
testl %eax, %eax
je 0x29d9
movl 0x10(%r14), %edi
callq 0x8e03
movq 0x18(%r14), %rsi
movl %eax, %edi
callq 0x8e29
jmp 0x29de
movl $0x1, %eax
movl %r12d, %ecx
andl $-0x3, %ecx
movl %eax, %r15d
negl %r15d
cmpl $0x28, %ecx
cmovnel %eax, %r15d
leal -0x27(%r12), %eax
cmpl $0x1, %eax
ja 0x2a9f
movl 0x24(%r14), %eax
andl $-0x2, %eax
leaq 0xc97b(%rip), %r13      # 0xf388
movq (%r13), %rdi
cmpl $0x2, %eax
jne 0x2a37
movl (%r14), %edx
movslq %ebx, %rax
leaq 0xc2cd(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x7894(%rip), %rsi      # 0xa2c2
xorl %eax, %eax
callq 0x2100
jmp 0x2a57
movq 0x8(%r14), %rdx
movslq %ebx, %rax
leaq 0xc2ab(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x7887(%rip), %rsi      # 0xa2d7
xorl %eax, %eax
callq 0x2100
movl 0x28(%r14), %eax
cmpl $0x1, %eax
je 0x2a7c
cmpl $0x8, %eax
je 0x2a73
cmpl $0x4, %eax
jne 0x2a9f
leaq 0x788b(%rip), %rsi      # 0xa2fc
jmp 0x2a83
leaq 0x7892(%rip), %rsi      # 0xa30c
jmp 0x2a83
leaq 0x7869(%rip), %rsi      # 0xa2ec
movq (%r13), %rdi
movslq %ebx, %rax
leaq 0xc25f(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
movl %r15d, %edx
xorl %eax, %eax
callq 0x2100
movl 0x24(%r14), %ecx
movl 0x28(%r14), %eax
andl $-0x2, %ecx
cmpl $0x2, %ecx
jne 0x2aed
cmpl $0x8, %eax
je 0x2b75
cmpl $0x4, %eax
je 0x2b2c
cmpl $0x1, %eax
jne 0x2bca
leaq 0xc8bb(%rip), %rax      # 0xf388
movq (%rax), %rdi
movl (%r14), %edx
movslq %ebx, %rax
leaq 0xc213(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x7834(%rip), %rsi      # 0xa31c
jmp 0x2b97
cmpl $0x8, %eax
je 0x2ba0
cmpl $0x4, %eax
je 0x2b50
cmpl $0x1, %eax
jne 0x2bca
leaq 0xc87d(%rip), %rax      # 0xf388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
movslq %ebx, %rax
leaq 0xc1d4(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x7838(%rip), %rsi      # 0xa35f
jmp 0x2bc3
leaq 0xc855(%rip), %rax      # 0xf388
movq (%rax), %rdi
movl (%r14), %edx
movslq %ebx, %rax
leaq 0xc1ad(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x77e5(%rip), %rsi      # 0xa333
jmp 0x2b97
leaq 0xc831(%rip), %rax      # 0xf388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
movslq %ebx, %rax
leaq 0xc188(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x7803(%rip), %rsi      # 0xa376
jmp 0x2bc3
leaq 0xc80c(%rip), %rax      # 0xf388
movq (%rax), %rdi
movl (%r14), %edx
movslq %ebx, %rax
leaq 0xc164(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x77b3(%rip), %rsi      # 0xa34a
xorl %eax, %eax
callq 0x2100
jmp 0x2bca
leaq 0xc7e1(%rip), %rax      # 0xf388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
movslq %ebx, %rax
leaq 0xc138(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x77ca(%rip), %rsi      # 0xa38d
xorl %eax, %eax
callq 0x2100
addl $-0x29, %r12d
cmpl $0x1, %r12d
ja 0x2c87
callq 0x24e7
movl %eax, %r12d
movl 0x24(%r14), %eax
andl $-0x2, %eax
leaq 0xc79a(%rip), %rcx      # 0xf388
movq (%rcx), %rdi
movslq %r12d, %r13
cmpl $0x2, %eax
jne 0x2c17
movl (%r14), %edx
leaq 0xc0ed(%rip), %rax      # 0xecf0
movq (%rax,%r13,8), %rcx
leaq 0x76b4(%rip), %rsi      # 0xa2c2
xorl %eax, %eax
callq 0x2100
jmp 0x2c34
movq 0x8(%r14), %rdx
leaq 0xc0ce(%rip), %rax      # 0xecf0
movq (%rax,%r13,8), %rcx
leaq 0x76aa(%rip), %rsi      # 0xa2d7
xorl %eax, %eax
callq 0x2100
movl 0x28(%r14), %eax
cmpl $0x1, %eax
je 0x2c59
cmpl $0x8, %eax
je 0x2c50
cmpl $0x4, %eax
jne 0x2c7f
leaq 0x76ae(%rip), %rsi      # 0xa2fc
jmp 0x2c60
leaq 0x76b5(%rip), %rsi      # 0xa30c
jmp 0x2c60
leaq 0x768c(%rip), %rsi      # 0xa2ec
leaq 0xc721(%rip), %rax      # 0xf388
movq (%rax), %rdi
leaq 0xc07f(%rip), %rax      # 0xecf0
movq (%rax,%r13,8), %rcx
movl %r15d, %edx
xorl %eax, %eax
callq 0x2100
movl %r12d, %edi
callq 0x255c
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq