// File: /workspace/github_c_makefile_star2_O3/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 0x2507
movl %eax, %ebx
movl 0x10(%r14), %edi
callq 0x8e43
testl %eax, %eax
je 0x29f9
movl 0x10(%r14), %edi
callq 0x8e7b
movq 0x18(%r14), %rsi
movl %eax, %edi
callq 0x8ea1
jmp 0x29fe
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 0x2abf
movl 0x24(%r14), %eax
andl $-0x2, %eax
leaq 0xc95b(%rip), %rcx      # 0xf388
movq (%rcx), %rdi
cmpl $0x2, %eax
jne 0x2a59
movl (%r14), %edx
movslq %ebx, %rax
leaq 0xc2ae(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %r13
leaq 0x7875(%rip), %rsi      # 0xa2c2
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
jmp 0x2a7c
movq 0x8(%r14), %rdx
movslq %ebx, %rax
leaq 0xc289(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %r13
leaq 0x7865(%rip), %rsi      # 0xa2d7
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
movl 0x28(%r14), %eax
cmpl $0x1, %eax
je 0x2aa1
cmpl $0x8, %eax
je 0x2a98
cmpl $0x4, %eax
jne 0x2abf
leaq 0x7866(%rip), %rsi      # 0xa2fc
jmp 0x2aa8
leaq 0x786d(%rip), %rsi      # 0xa30c
jmp 0x2aa8
leaq 0x7844(%rip), %rsi      # 0xa2ec
leaq 0xc8d9(%rip), %rax      # 0xf388
movq (%rax), %rdi
movl %r15d, %edx
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
movl 0x24(%r14), %ecx
movl 0x28(%r14), %eax
andl $-0x2, %ecx
cmpl $0x2, %ecx
jne 0x2b0d
cmpl $0x8, %eax
je 0x2b95
cmpl $0x4, %eax
je 0x2b4c
cmpl $0x1, %eax
jne 0x2bea
leaq 0xc89b(%rip), %rax      # 0xf388
movq (%rax), %rdi
movl (%r14), %edx
movslq %ebx, %rax
leaq 0xc1f3(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x7814(%rip), %rsi      # 0xa31c
jmp 0x2bb7
cmpl $0x8, %eax
je 0x2bc0
cmpl $0x4, %eax
je 0x2b70
cmpl $0x1, %eax
jne 0x2bea
leaq 0xc85d(%rip), %rax      # 0xf388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
movslq %ebx, %rax
leaq 0xc1b4(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x7818(%rip), %rsi      # 0xa35f
jmp 0x2be3
leaq 0xc835(%rip), %rax      # 0xf388
movq (%rax), %rdi
movl (%r14), %edx
movslq %ebx, %rax
leaq 0xc18d(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x77c5(%rip), %rsi      # 0xa333
jmp 0x2bb7
leaq 0xc811(%rip), %rax      # 0xf388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
movslq %ebx, %rax
leaq 0xc168(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x77e3(%rip), %rsi      # 0xa376
jmp 0x2be3
leaq 0xc7ec(%rip), %rax      # 0xf388
movq (%rax), %rdi
movl (%r14), %edx
movslq %ebx, %rax
leaq 0xc144(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x7793(%rip), %rsi      # 0xa34a
xorl %eax, %eax
callq 0x2100
jmp 0x2bea
leaq 0xc7c1(%rip), %rax      # 0xf388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
movslq %ebx, %rax
leaq 0xc118(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x77aa(%rip), %rsi      # 0xa38d
xorl %eax, %eax
callq 0x2100
addl $-0x29, %r12d
cmpl $0x1, %r12d
ja 0x2ca8
callq 0x2507
movl %eax, %r12d
movl 0x24(%r14), %eax
andl $-0x2, %eax
leaq 0xc77a(%rip), %rcx      # 0xf388
movq (%rcx), %rdi
cmpl $0x2, %eax
jne 0x2c3a
movl (%r14), %edx
movslq %r12d, %rax
leaq 0xc0cd(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %r13
leaq 0x7694(%rip), %rsi      # 0xa2c2
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
jmp 0x2c5d
movq 0x8(%r14), %rdx
movslq %r12d, %rax
leaq 0xc0a8(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %r13
leaq 0x7684(%rip), %rsi      # 0xa2d7
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
movl 0x28(%r14), %eax
cmpl $0x1, %eax
je 0x2c82
cmpl $0x8, %eax
je 0x2c79
cmpl $0x4, %eax
jne 0x2ca0
leaq 0x7685(%rip), %rsi      # 0xa2fc
jmp 0x2c89
leaq 0x768c(%rip), %rsi      # 0xa30c
jmp 0x2c89
leaq 0x7663(%rip), %rsi      # 0xa2ec
leaq 0xc6f8(%rip), %rax      # 0xf388
movq (%rax), %rdi
movl %r15d, %edx
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
movl %r12d, %edi
callq 0x257c
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq