// File: /workspace/github_c_makefile_star2_O2/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 0x23a0
movl %eax, %ebx
movl 0x10(%r14), %edi
callq 0x8743
testl %eax, %eax
je 0x27f2
movl 0x10(%r14), %edi
callq 0x877b
movq 0x18(%r14), %rsi
movl %eax, %edi
callq 0x87a1
jmp 0x27f5
pushq $0x1
popq %rax
movl %r12d, %ecx
andl $-0x3, %ecx
movl %eax, %r15d
negl %r15d
cmpl $0x28, %ecx
cmovnel %eax, %r15d
leal -0x27(%r12), %eax
movl %ebx, -0x2c(%rbp)
movslq %ebx, %rbx
cmpl $0x1, %eax
ja 0x28b6
movl 0x24(%r14), %eax
andl $-0x2, %eax
leaq 0xbb5e(%rip), %rcx      # 0xe388
movq (%rcx), %rdi
cmpl $0x2, %eax
jne 0x2853
movl (%r14), %edx
leaq 0xb4b4(%rip), %rax      # 0xdcf0
movq (%rax,%rbx,8), %r13
leaq 0x6a7b(%rip), %rsi      # 0x92c2
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
jmp 0x2873
movq 0x8(%r14), %rdx
leaq 0xb492(%rip), %rax      # 0xdcf0
movq (%rax,%rbx,8), %r13
leaq 0x6a6e(%rip), %rsi      # 0x92d7
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
movl 0x28(%r14), %eax
cmpl $0x1, %eax
je 0x2898
cmpl $0x8, %eax
je 0x288f
cmpl $0x4, %eax
jne 0x28b6
leaq 0x6a6f(%rip), %rsi      # 0x92fc
jmp 0x289f
leaq 0x6a76(%rip), %rsi      # 0x930c
jmp 0x289f
leaq 0x6a4d(%rip), %rsi      # 0x92ec
leaq 0xbae2(%rip), %rax      # 0xe388
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 0x2901
cmpl $0x8, %eax
je 0x2980
cmpl $0x4, %eax
je 0x293d
cmpl $0x1, %eax
jne 0x29cf
leaq 0xbaa4(%rip), %rax      # 0xe388
movq (%rax), %rdi
movl (%r14), %edx
leaq 0xb3ff(%rip), %rax      # 0xdcf0
movq (%rax,%rbx,8), %rcx
leaq 0x6a20(%rip), %rsi      # 0x931c
jmp 0x299f
cmpl $0x8, %eax
je 0x29a8
cmpl $0x4, %eax
je 0x295e
cmpl $0x1, %eax
jne 0x29cf
leaq 0xba69(%rip), %rax      # 0xe388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
leaq 0xb3c3(%rip), %rax      # 0xdcf0
movq (%rax,%rbx,8), %rcx
leaq 0x6a27(%rip), %rsi      # 0x935f
jmp 0x29c8
leaq 0xba44(%rip), %rax      # 0xe388
movq (%rax), %rdi
movl (%r14), %edx
leaq 0xb39f(%rip), %rax      # 0xdcf0
movq (%rax,%rbx,8), %rcx
leaq 0x69d7(%rip), %rsi      # 0x9333
jmp 0x299f
leaq 0xba23(%rip), %rax      # 0xe388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
leaq 0xb37d(%rip), %rax      # 0xdcf0
movq (%rax,%rbx,8), %rcx
leaq 0x69f8(%rip), %rsi      # 0x9376
jmp 0x29c8
leaq 0xba01(%rip), %rax      # 0xe388
movq (%rax), %rdi
movl (%r14), %edx
leaq 0xb35c(%rip), %rax      # 0xdcf0
movq (%rax,%rbx,8), %rcx
leaq 0x69ab(%rip), %rsi      # 0x934a
xorl %eax, %eax
callq 0x2100
jmp 0x29cf
leaq 0xb9d9(%rip), %rax      # 0xe388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
leaq 0xb333(%rip), %rax      # 0xdcf0
movq (%rax,%rbx,8), %rcx
leaq 0x69c5(%rip), %rsi      # 0x938d
xorl %eax, %eax
callq 0x2100
addl $-0x29, %r12d
cmpl $0x1, %r12d
ja 0x2a86
callq 0x23a0
movl %eax, %r12d
movl 0x24(%r14), %eax
andl $-0x2, %eax
leaq 0xb995(%rip), %rbx      # 0xe388
movq (%rbx), %rdi
cmpl $0x2, %eax
jne 0x2a1f
movl (%r14), %edx
movslq %r12d, %rax
leaq 0xb2e8(%rip), %rcx      # 0xdcf0
movq (%rcx,%rax,8), %r13
leaq 0x68af(%rip), %rsi      # 0x92c2
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
jmp 0x2a42
movq 0x8(%r14), %rdx
movslq %r12d, %rax
leaq 0xb2c3(%rip), %rcx      # 0xdcf0
movq (%rcx,%rax,8), %r13
leaq 0x689f(%rip), %rsi      # 0x92d7
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
movl 0x28(%r14), %eax
cmpl $0x1, %eax
je 0x2a67
cmpl $0x8, %eax
je 0x2a5e
cmpl $0x4, %eax
jne 0x2a7e
leaq 0x68a0(%rip), %rsi      # 0x92fc
jmp 0x2a6e
leaq 0x68a7(%rip), %rsi      # 0x930c
jmp 0x2a6e
leaq 0x687e(%rip), %rsi      # 0x92ec
movq (%rbx), %rdi
movl %r15d, %edx
movq %r13, %rcx
xorl %eax, %eax
callq 0x2100
movl %r12d, %edi
callq 0x241e
movl -0x2c(%rbp), %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq