LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgboolean
int cgboolean(int r, int op, int label) {
  fprintf(Outfile, "\ttest\t%s, %s\n", reglist[r], reglist[r]);
  switch (op) {
  case A_IF:
  case A_WHILE:
  case A_LOGAND:
    fprintf(Outfile, "\tje\tL%d\n", label);
    break;
  case A_LOGOR:
    fprintf(Outfile, "\tjne\tL%d\n", label);
    break;
  default:
    fprintf(Outfile, "\tsetnz\t%s\n", breglist[r]);
    fprintf(Outfile, "\tmovzbq\t%s, %s\n", breglist[r], reglist[r]);
  }
  return (r);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %r14d
movl %esi, %r12d
movl %edi, %ebx
leaq 0xc22e(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %r13
leaq 0xbb89(%rip), %rax      # 0xecf0
movq (%rax,%r13,8), %r15
leaq 0x731f(%rip), %rsi      # 0xa491
movq %r15, %rdx
movq %r15, %rcx
xorl %eax, %eax
callq 0x2100
leal -0x1e(%r12), %eax
cmpl $0x2, %eax
jb 0x3195
cmpl $0x8, %r12d
je 0x31a8
cmpl $0x9, %r12d
jne 0x31d4
leaq 0xc1ec(%rip), %rax      # 0xf388
movq (%rax), %rdi
leaq 0x7313(%rip), %rsi      # 0xa4b9
jmp 0x31b9
leaq 0xc1d9(%rip), %rax      # 0xf388
movq (%rax), %rdi
leaq 0x7309(%rip), %rsi      # 0xa4c2
movl %r14d, %edx
xorl %eax, %eax
callq 0x2100
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xc1ad(%rip), %r12      # 0xf388
movq (%r12), %rdi
leaq 0xbb5a(%rip), %rax      # 0xed40
movq (%rax,%r13,8), %r14
leaq 0x72db(%rip), %rsi      # 0xa4cc
movq %r14, %rdx
xorl %eax, %eax
callq 0x2100
movq (%r12), %rdi
leaq 0x72a3(%rip), %rsi      # 0xa4a9
movq %r14, %rdx
movq %r15, %rcx
xorl %eax, %eax
callq 0x2100
jmp 0x31c3
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgcall
int cgcall(struct symtable *sym, int numargs) {
  int outr;

  // 调用函数
  fprintf(Outfile, "\tcall\t%s@PLT\n", sym->name);

  // 删除之前入栈的实参
  if (numargs > 6)
    fprintf(Outfile, "\taddq\t$%d, %%rsp\n", 8 * (numargs - 6));

  // 恢复之前入栈的寄存器
  cgunspillregs();

  // 获取一个新的寄存器,拷贝返回值给他
  outr = cgallocreg();
  fprintf(Outfile, "\tmovq\t%%rax, %s\n", reglist[outr]);
  return (outr);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %esi, %ebx
leaq 0xc15f(%rip), %r14      # 0xf388
movq (%r14), %rax
movq 0x8(%rdi), %rdx
leaq 0x72a0(%rip), %rsi      # 0xa4d7
movq %rax, %rdi
xorl %eax, %eax
callq 0x2100
cmpl $0x7, %ebx
jl 0x325e
movq (%r14), %rdi
leal -0x30(,%rbx,8), %edx
leaq 0x728e(%rip), %rsi      # 0xa4e5
xorl %eax, %eax
callq 0x2100
movl $0x3, %r12d
leaq 0xba85(%rip), %r15      # 0xecf0
leaq 0x7542(%rip), %rbx      # 0xa7b4
movq (%r14), %rdi
movq (%r15,%r12,8), %rdx
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2100
addq $-0x1, %r12
jb 0x3272
callq 0x2507
movq (%r14), %rdi
movslq %eax, %rbx
movq (%r15,%rbx,8), %rdx
leaq 0x7258(%rip), %rsi      # 0xa4f7
xorl %eax, %eax
callq 0x2100
movl %ebx, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgcopyarg
void cgcopyarg(int r, int argposn) {

  // 如果实参数量大于6个,那就把大于的都压入栈中
  if (argposn > 6) {
    fprintf(Outfile, "\tpushq\t%s\n", reglist[r]);
  } else {
    // 否则把实参值拷贝到指定的寄存器
    fprintf(Outfile, "\tmovq\t%s, %s\n", reglist[r],
	    reglist[FIRSTPARAMREG - argposn + 1]);
  }
  cgfreereg(r);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movl %edi, %ebx
leaq 0xc0c8(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rcx
leaq 0xba23(%rip), %rax      # 0xecf0
movq (%rax,%rcx,8), %rdx
cmpl $0x7, %esi
jl 0x32e6
leaq 0x722b(%rip), %rsi      # 0xa508
xorl %eax, %eax
callq 0x2100
jmp 0x32ff
movl $0xa, %ecx
subl %esi, %ecx
movq (%rax,%rcx,8), %rcx
leaq 0x721b(%rip), %rsi      # 0xa513
xorl %eax, %eax
callq 0x2100
movl %ebx, %edi
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x257c
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgstorglob
int cgstorglob(int r, struct symtable *sym) {

  if (cgprimsize(sym->type) == 8) {
    fprintf(Outfile, "\tmovq\t%s, %s(%%rip)\n", reglist[r], sym->name);
  } else
    switch (sym->type) {
    case P_CHAR:
      fprintf(Outfile, "\tmovb\t%s, %s(%%rip)\n", breglist[r], sym->name);
      break;
    case P_INT:
      fprintf(Outfile, "\tmovl\t%s, %s(%%rip)\n", dreglist[r], sym->name);
      break;
    default:
      fatald("Bad type in cgstorglob:", sym->type);
    }
  return (r);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movq %rsi, %r14
movl %edi, %ebx
movl 0x10(%rsi), %edi
callq 0x247a
cmpl $0x8, %eax
jne 0x3384
leaq 0xc022(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rax
leaq 0xb97d(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rdx
movq 0x8(%r14), %rcx
leaq 0x71ae(%rip), %rsi      # 0xa530
jmp 0x33da
movl 0x10(%r14), %esi
cmpl $0x30, %esi
je 0x33b7
cmpl $0x20, %esi
jne 0x33e8
leaq 0xbfef(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rax
leaq 0xb99a(%rip), %rcx      # 0xed40
movq (%rcx,%rax,8), %rdx
movq 0x8(%r14), %rcx
leaq 0x7190(%rip), %rsi      # 0xa545
jmp 0x33da
leaq 0xbfca(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rax
leaq 0xb9c5(%rip), %rcx      # 0xed90
movq (%rcx,%rax,8), %rdx
movq 0x8(%r14), %rcx
leaq 0x7180(%rip), %rsi      # 0xa55a
xorl %eax, %eax
callq 0x2100
movl %ebx, %eax
popq %rbx
popq %r14
popq %rbp
retq
leaq 0x7180(%rip), %rdi      # 0xa56f
callq 0x6991
jmp 0x33e1
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgglobstr
void cgglobstr(int l, char *strvalue, int append) {
  char *cptr;
  if (!append)
    cglabel(l);
  for (cptr = strvalue; *cptr; cptr++) {
    fprintf(Outfile, "\t.byte\t%d\n", *cptr);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
testl %edx, %edx
jne 0x35c0
movl %edi, %eax
leaq 0xbddb(%rip), %rcx      # 0xf388
movq (%rcx), %rdi
leaq 0x70c3(%rip), %rsi      # 0xa67a
movl %eax, %edx
xorl %eax, %eax
callq 0x2100
movb (%rbx), %al
testb %al, %al
je 0x35f0
incq %rbx
leaq 0xbdb8(%rip), %r15      # 0xf388
leaq 0x7019(%rip), %r14      # 0xa5f0
movq (%r15), %rdi
movsbl %al, %edx
movq %r14, %rsi
xorl %eax, %eax
callq 0x2100
movb (%rbx), %al
incq %rbx
testb %al, %al
jne 0x35d7
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgcompare_and_set
int cgcompare_and_set(int ASTop, int r1, int r2, int type) {
  int size = cgprimsize(type);


  // 检查语法树操作的范围
  if (ASTop < A_EQ || ASTop > A_GE)
    fatal("Bad ASTop in cgcompare_and_set()");

  switch (size) {
  case 1:
    fprintf(Outfile, "\tcmpb\t%s, %s\n", breglist[r2], breglist[r1]);
    break;
  case 4:
    fprintf(Outfile, "\tcmpl\t%s, %s\n", dreglist[r2], dreglist[r1]);
    break;
  default:
    fprintf(Outfile, "\tcmpq\t%s, %s\n", reglist[r2], reglist[r1]);
  }

  fprintf(Outfile, "\t%s\t%s\n", cmplist[ASTop - A_EQ], breglist[r2]);
  fprintf(Outfile, "\tmovzbq\t%s, %s\n", breglist[r2], reglist[r2]);
  cgfreereg(r1);
  return (r2);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %r15d
movl %esi, %r14d
movl %edi, %ebx
movl %ecx, %edi
callq 0x247a
movl %eax, %r12d
leal -0x13(%rbx), %eax
cmpl $-0x7, %eax
ja 0x3654
leaq 0x6fd8(%rip), %rdi      # 0xa627
callq 0x6937
leaq 0xbd2d(%rip), %r13      # 0xf388
movq (%r13), %rdi
leaq 0xb6da(%rip), %rax      # 0xed40
cmpl $0x1, %r12d
je 0x3685
cmpl $0x4, %r12d
jne 0x3691
movq %rax, %r12
leaq 0x6fda(%rip), %rsi      # 0xa656
leaq 0xb70d(%rip), %rax      # 0xed90
jmp 0x36a2
leaq 0x6fbc(%rip), %rsi      # 0xa648
movq %rax, %r12
jmp 0x36a2
movq %rax, %r12
leaq 0x6fc9(%rip), %rsi      # 0xa664
leaq 0xb64e(%rip), %rax      # 0xecf0
movslq %r15d, %r15
movslq %r14d, %r14
movq (%rax,%r15,8), %rdx
movq (%rax,%r14,8), %rcx
xorl %eax, %eax
callq 0x2100
movq (%r13), %rdi
movslq %ebx, %rax
leaq 0x71cb(%rip), %rcx      # 0xa890
movslq -0x34(%rcx,%rax,4), %rdx
addq %rcx, %rdx
movq (%r12,%r15,8), %rbx
leaq 0x6f9a(%rip), %rsi      # 0xa672
movq %rbx, %rcx
xorl %eax, %eax
callq 0x2100
movq (%r13), %rdi
leaq 0xb603(%rip), %rax      # 0xecf0
movq (%rax,%r15,8), %rcx
leaq 0x6db1(%rip), %rsi      # 0xa4a9
movq %rbx, %rdx
xorl %eax, %eax
callq 0x2100
movl %r14d, %edi
callq 0x257c
movl %r15d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgcompare_and_jump
int cgcompare_and_jump(int ASTop, int r1, int r2, int label, int type) {
  int size = cgprimsize(type);

  // 检查语法树操作范围
  if (ASTop < A_EQ || ASTop > A_GE)
    fatal("Bad ASTop in cgcompare_and_set()");

  switch (size) {
  case 1:
    fprintf(Outfile, "\tcmpb\t%s, %s\n", breglist[r2], breglist[r1]);
    break;
  case 4:
    fprintf(Outfile, "\tcmpl\t%s, %s\n", dreglist[r2], dreglist[r1]);
    break;
  default:
    fprintf(Outfile, "\tcmpq\t%s, %s\n", reglist[r2], reglist[r1]);
  }

  fprintf(Outfile, "\t%s\tL%d\n", invcmplist[ASTop - A_EQ], label);
  cgfreereg(r1);
  cgfreereg(r2);
  return (NOREG);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %ecx, %ebx
movl %edx, %r15d
movl %esi, %r12d
movl %edi, %r14d
movl %r8d, %edi
callq 0x247a
movl %eax, %r13d
leal -0x13(%r14), %eax
cmpl $-0x7, %eax
ja 0x3774
leaq 0x6eb8(%rip), %rdi      # 0xa627
callq 0x6937
leaq 0xbc0d(%rip), %rax      # 0xf388
movq (%rax), %rdi
cmpl $0x1, %r13d
je 0x379d
cmpl $0x4, %r13d
jne 0x37b0
movq %rax, %r13
leaq 0x6ec2(%rip), %rsi      # 0xa656
leaq 0xb5f5(%rip), %rax      # 0xed90
jmp 0x37c1
movq %rax, %r13
leaq 0x6ea1(%rip), %rsi      # 0xa648
leaq 0xb592(%rip), %rax      # 0xed40
jmp 0x37c1
movq %rax, %r13
leaq 0x6eaa(%rip), %rsi      # 0xa664
leaq 0xb52f(%rip), %rax      # 0xecf0
movslq %r12d, %r12
movslq %r15d, %r15
movq (%rax,%r15,8), %rdx
movq (%rax,%r12,8), %rcx
xorl %eax, %eax
callq 0x2100
movq (%r13), %rdi
movslq %r14d, %rax
leaq 0x70c4(%rip), %rcx      # 0xa8a8
movslq -0x34(%rcx,%rax,4), %rdx
addq %rcx, %rdx
leaq 0x6e97(%rip), %rsi      # 0xa68a
movl %ebx, %ecx
xorl %eax, %eax
callq 0x2100
movl %r12d, %edi
callq 0x257c
movl %r15d, %edi
callq 0x257c
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgreturn
void cgreturn(int reg, struct symtable *sym) {

  // 处理有返回值的
  if (reg != NOREG) {
    // 处理指针，不能把它放在下面的switch语句里面一起处理
    if (ptrtype(sym->type))
      fprintf(Outfile, "\tmovq\t%s, %%rax\n", reglist[reg]);
    else {
      // 根据函数类型生成相应汇编代码
      switch (sym->type) {
      case P_CHAR:
        fprintf(Outfile, "\tmovzbl\t%s, %%eax\n", breglist[reg]);
        break;
      case P_INT:
        fprintf(Outfile, "\tmovl\t%s, %%eax\n", dreglist[reg]);
        break;
      case P_LONG:
        fprintf(Outfile, "\tmovq\t%s, %%rax\n", reglist[reg]);
        break;
      default:
	      fatald("Bad function type in cgreturn:", sym->type);
      }
    }
  }

  cgjump(sym->stu.st_endlabel);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movq %rsi, %rbx
cmpl $-0x1, %edi
je 0x386c
movl %edi, %r14d
movl 0x10(%rbx), %edi
callq 0x8e43
testl %eax, %eax
je 0x388a
leaq 0xbb3b(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %r14d, %rax
leaq 0xb496(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rdx
leaq 0x6e2e(%rip), %rsi      # 0xa693
xorl %eax, %eax
callq 0x2100
movl (%rbx), %edx
leaq 0xbb13(%rip), %rax      # 0xf388
movq (%rax), %rdi
leaq 0x6e01(%rip), %rsi      # 0xa680
xorl %eax, %eax
popq %rbx
popq %r14
popq %rbp
jmp 0x2100
movl 0x10(%rbx), %esi
cmpl $0x40, %esi
je 0x3846
cmpl $0x30, %esi
je 0x38bd
cmpl $0x20, %esi
jne 0x38de
leaq 0xbae5(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %r14d, %rax
leaq 0xb490(%rip), %rcx      # 0xed40
movq (%rcx,%rax,8), %rdx
leaq 0x6de9(%rip), %rsi      # 0xa6a4
jmp 0x3865
leaq 0xbac4(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %r14d, %rax
leaq 0xb4bf(%rip), %rcx      # 0xed90
movq (%rcx,%rax,8), %rdx
leaq 0x6ddb(%rip), %rsi      # 0xa6b7
jmp 0x3865
leaq 0x6de3(%rip), %rdi      # 0xa6c8
callq 0x6991
jmp 0x386c
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgaddress
int cgaddress(struct symtable *sym) {
  int r = cgallocreg();

  if (sym->class == C_GLOBAL ||
      sym->class == C_EXTERN || sym->class == C_STATIC)
    fprintf(Outfile, "\tleaq\t%s(%%rip), %s\n", sym->name, reglist[r]);
  else
    fprintf(Outfile, "\tleaq\t%d(%%rbp), %s\n", sym->stu.st_posn, reglist[r]);
  return (r);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movq %rdi, %r14
callq 0x2507
movl %eax, %ebx
movl 0x24(%r14), %eax
cmpl $0x5, %eax
ja 0x393c
movl $0x32, %ecx
btl %eax, %ecx
jae 0x393c
leaq 0xba71(%rip), %rax      # 0xf388
movq (%rax), %rdi
movq 0x8(%r14), %rdx
movslq %ebx, %rax
leaq 0xb3c8(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x69a4(%rip), %rsi      # 0xa2d7
xorl %eax, %eax
callq 0x2100
jmp 0x3965
leaq 0xba45(%rip), %rax      # 0xf388
movq (%rax), %rdi
movl (%r14), %edx
movslq %ebx, %rax
leaq 0xb39d(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x6964(%rip), %rsi      # 0xa2c2
xorl %eax, %eax
callq 0x2100
movl %ebx, %eax
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgderef
int cgderef(int r, int type) {
  // 获得指针指向的类型
  int newtype = value_at(type);
  // 获得类型大小
  int size = cgprimsize(newtype);

  switch (size) {
  case 1:
    fprintf(Outfile, "\tmovzbq\t(%s), %s\n", reglist[r], reglist[r]);
    break;
  case 4:
    fprintf(Outfile, "\tmovslq\t(%s), %s\n", reglist[r], reglist[r]);
    break;
  case 8:
    fprintf(Outfile, "\tmovq\t(%s), %s\n", reglist[r], reglist[r]);
    break;
  default:
    fatald("Can't cgderef on type:", type);
  }
  return (r);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movl %esi, %r14d
movl %edi, %ebx
movl %esi, %edi
callq 0x8e7b
movl %eax, %edi
callq 0x247a
cmpl $0x8, %eax
je 0x39d7
cmpl $0x4, %eax
je 0x39b6
cmpl $0x1, %eax
jne 0x3a02
leaq 0xb9ec(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rax
leaq 0xb347(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x6d33(%rip), %rsi      # 0xa6e7
jmp 0x39f6
leaq 0xb9cb(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rax
leaq 0xb326(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x6d24(%rip), %rsi      # 0xa6f9
jmp 0x39f6
leaq 0xb9aa(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rax
leaq 0xb305(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x6d15(%rip), %rsi      # 0xa70b
movq %rcx, %rdx
xorl %eax, %eax
callq 0x2100
jmp 0x3a11
leaq 0x6d12(%rip), %rdi      # 0xa71b
movl %r14d, %esi
callq 0x6991
movl %ebx, %eax
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgstorderef
int cgstorderef(int r1, int r2, int type) {
  // 获得类型大小
  int size = cgprimsize(type);

  switch (size) {
  case 1:
    fprintf(Outfile, "\tmovb\t%s, (%s)\n", breglist[r1], reglist[r2]);
    break;
  case 4:
    fprintf(Outfile, "\tmovl\t%s, (%s)\n", dreglist[r1], reglist[r2]);
    break;
  case 8:
    fprintf(Outfile, "\tmovq\t%s, (%s)\n", reglist[r1], reglist[r2]);
    break;
  default:
    fatald("Can't cgstoderef on type:", type);
  }
  return (r1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %r15d
movl %esi, %r14d
movl %edi, %ebx
movl %edx, %edi
callq 0x247a
cmpl $0x8, %eax
je 0x3aa2
cmpl $0x4, %eax
je 0x3a73
cmpl $0x1, %eax
jne 0x3ad1
leaq 0xb93d(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rax
leaq 0xb2e8(%rip), %rcx      # 0xed40
movq (%rcx,%rax,8), %rdx
movslq %r14d, %rax
leaq 0xb28a(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x6cc1(%rip), %rsi      # 0xa732
jmp 0x3ac8
leaq 0xb90e(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rax
leaq 0xb309(%rip), %rcx      # 0xed90
movq (%rcx,%rax,8), %rdx
movslq %r14d, %rax
leaq 0xb25b(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rcx
leaq 0x6ca2(%rip), %rsi      # 0xa742
jmp 0x3ac8
leaq 0xb8df(%rip), %rax      # 0xf388
movq (%rax), %rdi
movslq %ebx, %rax
leaq 0xb23a(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rdx
movslq %r14d, %rax
movq (%rcx,%rax,8), %rcx
leaq 0x6c8a(%rip), %rsi      # 0xa752
xorl %eax, %eax
callq 0x2100
jmp 0x3ae0
leaq 0x6c8a(%rip), %rdi      # 0xa762
movl %r15d, %esi
callq 0x6991
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/cg.c
// Function: cgswitch
void cgswitch(int reg, int casecount, int toplabel,
	      int *caselabel, int *caseval, int defaultlabel) {
  int i, label;

  // 为switch表，获得和生成一个标签
  label = genlabel();
  cglabel(label);

  // 如果没有case，就创建一个case指向默认case
  if (casecount == 0) {
    caseval[0] = 0;
    caselabel[0] = defaultlabel;
    casecount = 1;
  }
  // 生成switch跳表
  fprintf(Outfile, "\t.quad\t%d\n", casecount);
  for (i = 0; i < casecount; i++)
    fprintf(Outfile, "\t.quad\t%d, L%d\n", caseval[i], caselabel[i]);
  fprintf(Outfile, "\t.quad\tL%d\n", defaultlabel);

  // 加载指定寄存器
  cglabel(toplabel);
  fprintf(Outfile, "\tmovq\t%s, %%rax\n", reglist[reg]);
  fprintf(Outfile, "\tleaq\tL%d(%%rip), %%rdx\n", label);
  fprintf(Outfile, "\tjmp\t__switch\n");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %r9d, %ebx
movq %r8, %r15
movq %rcx, %r14
movl %edx, -0x30(%rbp)
movl %esi, %r12d
movl %edi, -0x34(%rbp)
callq 0x5828
leaq 0xb86c(%rip), %r13      # 0xf388
movq (%r13), %rdi
leaq 0x6b53(%rip), %rsi      # 0xa67a
movl %eax, -0x38(%rbp)
movl %eax, %edx
xorl %eax, %eax
callq 0x2100
testl %r12d, %r12d
movl %ebx, -0x2c(%rbp)
je 0x3b60
movq (%r13), %rdi
leaq 0x6acc(%rip), %rsi      # 0xa612
movl %r12d, %edx
xorl %eax, %eax
callq 0x2100
testl %r12d, %r12d
movq %r15, %rax
movq %r14, %r15
movq %rax, %r14
jg 0x3b90
jmp 0x3bb8
movl $0x0, (%r15)
movl %ebx, (%r14)
movq (%r13), %rdi
leaq 0x6a9d(%rip), %rsi      # 0xa612
movl $0x1, %r12d
movl $0x1, %edx
xorl %eax, %eax
callq 0x2100
movq %r15, %rax
movq %r14, %r15
movq %rax, %r14
movl %r12d, %ebx
xorl %r12d, %r12d
movq (%r13), %rdi
movl (%r14,%r12,4), %edx
movl (%r15,%r12,4), %ecx
leaq 0x6bd3(%rip), %rsi      # 0xa77c
xorl %eax, %eax
callq 0x2100
incq %r12
cmpq %r12, %rbx
jne 0x3b96
movq (%r13), %rdi
leaq 0x6a43(%rip), %rsi      # 0xa606
movl -0x2c(%rbp), %edx
xorl %eax, %eax
callq 0x2100
movq (%r13), %rdi
leaq 0x6aa2(%rip), %rsi      # 0xa67a
movl -0x30(%rbp), %edx
xorl %eax, %eax
callq 0x2100
movq (%r13), %rdi
movslq -0x34(%rbp), %rax
leaq 0xb0ff(%rip), %rcx      # 0xecf0
movq (%rcx,%rax,8), %rdx
leaq 0x6a97(%rip), %rsi      # 0xa693
xorl %eax, %eax
callq 0x2100
movq (%r13), %rdi
leaq 0x6b7e(%rip), %rsi      # 0xa78c
movl -0x38(%rbp), %edx
xorl %eax, %eax
callq 0x2100
movq (%r13), %rcx
leaq 0x6b82(%rip), %rdi      # 0xa7a5
movl $0xe, %esi
movl $0x1, %edx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2170
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/decl.c
// Function: parse_stars
int parse_stars(int type) {

  while (1) {
    if (Token.token != T_STAR)
      break;
    type = pointer_to(type);
    scan(&Token);
  }
  return (type);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movl %edi, %ebx
leaq 0xb197(%rip), %r14      # 0xf3a0
cmpl $0x17, (%r14)
jne 0x4222
movl %ebx, %edi
callq 0x8e52
movl %eax, %ebx
movq %r14, %rdi
callq 0x6b20
jmp 0x4209
movl %ebx, %eax
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/decl.c
// Function: parse_cast
int parse_cast(struct symtable **ctype) {
  int type, class = 0;

  // 从括号里面获取类型
  type = parse_stars(parse_type(ctype, &class));

  // 错误检查，目前不支持，强转到复合类型
  if (type == P_STRUCT || type == P_UNION || type == P_VOID)
    fatal("Cannot cast to a struct, union or void type");
  return (type);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
leaq -0xc(%rbp), %rsi
movl $0x0, (%rsi)
callq 0x3c7c
movl %eax, %edi
callq 0x41f9
movl %eax, %ebx
cmpl $0x10, %eax
je 0x4256
cmpl $0x60, %ebx
je 0x4256
cmpl $0x50, %ebx
jne 0x4262
leaq 0x6731(%rip), %rdi      # 0xa98e
callq 0x6937
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/decl.c
// Function: parse_literal
int parse_literal(int type) {
  struct ASTnode *tree;

  // 解析表达式，并优化解析出来的语法树tree
  tree = optimise(binexpr(0));

  // 如果这里有个cast，获取子树应用到tree上
  if (tree->op == A_CAST) {
    tree->left->type = tree->type;
    tree = tree->left;
  }

  // 这颗tree现在必须是个整型或者字符串字面量
  if (tree->op != A_INTLIT && tree->op != A_STRLIT)
    fatal("Cannot initialise globals with a general expression");

  // 如果type是char*
  if (type == pointer_to(P_CHAR)) {
    // tree是字符字面量，返回标签号
    if (tree->op == A_STRLIT)
      return (tree->atu.a_intvalue);
    // tree是整型零值，所以是个NULL，所以返回0
    if (tree->op == A_INTLIT && tree->atu.a_intvalue == 0)
      return (0);
  }

  // 代码走到这里就是处理整型字面量量
  // 输入的type必须是个整型，同时足够宽来容纳这个字面值
  if (inttype(type) && typesize(type, NULL) >= typesize(tree->type, NULL))
    return (tree->atu.a_intvalue);

  fatal("Type mismatch: literal vs. variable");
  return (0);		
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movl %edi, %r14d
xorl %edi, %edi
callq 0x4d39
movq %rax, %rdi
callq 0x6a4c
movq %rax, %rbx
movl 0x4(%rax), %eax
cmpl $0x34, %eax
jne 0x429c
movl 0x8(%rbx), %eax
movq 0x20(%rbx), %rbx
movl %eax, 0x8(%rbx)
movl 0x4(%rbx), %eax
andl $-0x2, %eax
cmpl $0x1a, %eax
je 0x42b0
leaq 0x670f(%rip), %rdi      # 0xa9ba
callq 0x6937
movl $0x20, %edi
callq 0x8e52
cmpl %r14d, %eax
jne 0x42d3
movl 0x4(%rbx), %eax
cmpl $0x1a, %eax
je 0x42ce
cmpl $0x1b, %eax
je 0x430b
jmp 0x42d3
cmpl $0x0, (%rbx)
je 0x4307
movl %r14d, %edi
callq 0x8e28
testl %eax, %eax
je 0x42fb
movl %r14d, %edi
xorl %esi, %esi
callq 0x8ea1
movl %eax, %r14d
movl 0x8(%rbx), %edi
xorl %esi, %esi
callq 0x8ea1
cmpl %eax, %r14d
jge 0x430b
leaq 0x66ec(%rip), %rdi      # 0xa9ee
callq 0x6937
xorl %eax, %eax
jmp 0x430d
movl (%rbx), %eax
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/decl.c
// Function: global_declarations
void global_declarations(void) {
  struct symtable *ctype= NULL;
  struct ASTnode *unused;

  // 循环解析直到文件结束
  while (Token.token != T_EOF) {
    declaration_list(&ctype, C_GLOBAL, T_SEMI, T_EOF, &unused);

    // 跳过分号
    if (Token.token == T_SEMI)
      scan(&Token);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x18, %rsp
movq $0x0, -0x20(%rbp)
leaq 0xa8c9(%rip), %rbx      # 0xf3a0
cmpl $0x0, (%rbx)
je 0x4b10
leaq -0x20(%rbp), %r14
leaq -0x28(%rbp), %r15
movq %r14, %rdi
movl $0x1, %esi
movl $0x35, %edx
xorl %ecx, %ecx
movq %r15, %r8
callq 0x4312
movl (%rbx), %eax
cmpl $0x35, %eax
jne 0x4b0c
movq %rbx, %rdi
callq 0x6b20
movl (%rbx), %eax
testl %eax, %eax
jne 0x4ae4
addq $0x18, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/decl.c
// Function: param_declaration_list
static int param_declaration_list(struct symtable *oldfuncsym,
				  struct symtable *newfuncsym) {
  int type, paramcnt = 0;
  struct symtable *ctype;
  struct symtable *protoptr = NULL;
  struct ASTnode *unused;

  // 获取旧函数的成员
  if (oldfuncsym != NULL)
    protoptr = oldfuncsym->member;

  // 循环获取参数
  while (Token.token != T_RPAREN) {

    // 如果第一个token是'void'
    if (Token.token == T_VOID) {
      // 偷看下个token，如果是')', 表示函数没有参数，离开循环  
      scan(&Peektoken);
      if (Peektoken.token == T_RPAREN) {
        // 把Peektoken放回到Token
        paramcnt = 0;
        scan(&Token);
        break;
      }
    }

    // 获得下一个参数的类型
    type = declaration_list(&ctype, C_PARAM, T_COMMA, T_RPAREN, &unused);
    if (type == -1)
      fatal("Bad type in parameter list");

    // 保证这个参数的类型跟旧的匹配
    if (protoptr != NULL) {
      if (type != protoptr->type)
	      fatald("Type doesn't match prototype for parameter", paramcnt + 1);
      protoptr = protoptr->next;
    }
    paramcnt++;

    // 遇到右括号，退出循环
    if (Token.token == T_RPAREN)
      break;
    // 否则看看是否是个逗号
    comma();
  }

  if (oldfuncsym != NULL && paramcnt != oldfuncsym->nelems)
    fatals("Parameter count mismatch for function", oldfuncsym->name);

  // 返回函数参数
  return (paramcnt);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
xorl %ebx, %ebx
testq %rdi, %rdi
movq %rdi, -0x30(%rbp)
je 0x4b3d
movq 0x40(%rdi), %r12
jmp 0x4b40
xorl %r12d, %r12d
leaq 0xa859(%rip), %r15      # 0xf3a0
leaq -0x38(%rbp), %r13
movl (%r15), %eax
cmpl $0x1e, %eax
je 0x4b5d
cmpl $0x3a, %eax
jne 0x4b72
jmp 0x4bea
leaq 0xa854(%rip), %r14      # 0xf3b8
movq %r14, %rdi
callq 0x6b20
cmpl $0x3a, (%r14)
je 0x4bdc
leaq -0x40(%rbp), %rdi
movl $0x3, %esi
movl $0x3d, %edx
movl $0x3a, %ecx
movq %r13, %r8
callq 0x4312
movl %eax, %r14d
cmpl $-0x1, %eax
jne 0x4ba1
leaq 0x6064(%rip), %rdi      # 0xac00
callq 0x6937
testq %r12, %r12
je 0x4bc3
cmpl 0x10(%r12), %r14d
je 0x4bbc
leal 0x1(%rbx), %esi
leaq 0x6064(%rip), %rdi      # 0xac1b
callq 0x6991
movq 0x38(%r12), %r12
jmp 0x4bc6
xorl %r12d, %r12d
cmpl $0x3a, (%r15)
je 0x4bd8
callq 0x6921
incl %ebx
jmp 0x4b4b
incl %ebx
jmp 0x4bea
leaq 0xa7bd(%rip), %rdi      # 0xf3a0
callq 0x6b20
xorl %ebx, %ebx
movq -0x30(%rbp), %rax
testq %rax, %rax
je 0x4c08
cmpl 0x2c(%rax), %ebx
je 0x4c08
movq 0x8(%rax), %rsi
leaq 0x6043(%rip), %rdi      # 0xac46
callq 0x683f
movl %ebx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/decl.c
// Function: is_new_symbol
static int is_new_symbol(struct symtable *sym, int class, 
		  int type, struct symtable *ctype) {

  // 不存在，代表是新的
  if (sym==NULL) return(1);

  // 如果类型匹配，就转换为global（全局）
  if ((sym->class== C_GLOBAL && class== C_EXTERN)
      || (sym->class== C_EXTERN && class== C_GLOBAL)) {

      // 类型不匹配
      if (type != sym->type)
        fatals("Type mismatch between global/extern", sym->name);

      // Struct/unions, 比较ctype
      if (type >= P_STRUCT && ctype != sym->ctype)
        fatals("Type mismatch between global/extern", sym->name);

      // 到这里，代表类型匹配来，转换为global（全局）
      sym->class= C_GLOBAL;
      // 返回0，表示符号不是新的
      return(0);
  }

  // 如果到了这里，代表重复定义
  fatals("Duplicate global variable declaration", sym->name);
  return(-1);	
}

// Assembly:
testq %rdi, %rdi
je 0x4c89
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rcx, %r14
movl %edx, %r15d
movq %rdi, %rbx
movl 0x24(%rdi), %eax
movl %eax, %ecx
xorl $0x1, %ecx
movl %esi, %edx
xorl $0x4, %edx
orl %ecx, %edx
je 0x4c4c
xorl $0x4, %eax
xorl $0x1, %esi
orl %eax, %esi
jne 0x4c8f
cmpl %r15d, 0x10(%rbx)
je 0x4c62
movq 0x8(%rbx), %rsi
leaq 0x60c3(%rip), %rdi      # 0xad20
callq 0x683f
cmpl $0x50, %r15d
jl 0x4c7e
cmpq %r14, 0x18(%rbx)
je 0x4c7e
movq 0x8(%rbx), %rsi
leaq 0x60a7(%rip), %rdi      # 0xad20
callq 0x683f
movl $0x1, 0x24(%rbx)
xorl %eax, %eax
jmp 0x4ca4
movl $0x1, %eax
retq
movq 0x8(%rbx), %rsi
leaq 0x60aa(%rip), %rdi      # 0xad44
callq 0x683f
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nop
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/expr.c
// Function: expression_list
struct ASTnode *expression_list(int endtoken) {
  struct ASTnode *tree = NULL;
  struct ASTnode *child = NULL;
  int exprcount = 0;

  // 循环直到遇到结束的token
  while (Token.token != endtoken) {

    // 解析下个表达式，同时增加表达式数量
    child = binexpr(0);
    exprcount++;

    // 创建一个A_GLUE节点，左树是之前的tree，右树是新的表达式child，同时保存表达式数量
    tree =
      mkastnode(A_GLUE, P_NONE, NULL, tree, NULL, child, NULL, exprcount);

    // 遇到结束token
    if (Token.token == endtoken)
      break;

    // 必须有逗号
    match(T_COMMA, ",");
  }

  // 返回所有表达式的树
  return (tree);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
leaq 0xa6db(%rip), %r12      # 0xf3a0
cmpl %edi, (%r12)
jne 0x4cd0
xorl %r14d, %r14d
jmp 0x4d27
movl %edi, %ebx
movl $0x1, %r13d
xorl %r14d, %r14d
leaq 0x6176(%rip), %r15      # 0xae58
xorl %edi, %edi
callq 0x4d39
movl $0x1d, %edi
xorl %esi, %esi
xorl %edx, %edx
movq %r14, %rcx
xorl %r8d, %r8d
movq %rax, %r9
pushq %r13
pushq $0x0
callq 0x8828
addq $0x10, %rsp
movq %rax, %r14
cmpl %ebx, (%r12)
je 0x4d27
movl $0x3d, %edi
movq %r15, %rsi
callq 0x6818
incl %r13d
cmpl %ebx, (%r12)
jne 0x4ce2
movq %r14, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/expr.c
// Function: op_precedence
static int op_precedence(int tokentype) {
  int prec;
  if (tokentype > T_MOD)
    fatals("Token with no precedence in op_precedence:", Tstring[tokentype]);
  prec = OpPrec[tokentype];
  if (prec == 0)
    fatals("Syntax error, token", Tstring[tokentype]);
  return (prec);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
cmpl $0x1a, %edi
jl 0x5673
movl %edi, %ebx
leaq 0x9aa9(%rip), %rax      # 0xf100
movq (%rax,%rbx,8), %rsi
leaq 0x5b18(%rip), %rdi      # 0xb17a
callq 0x683f
leaq 0x5782(%rip), %rax      # 0xadf0
movl (%rax,%rbx,4), %ebx
jmp 0x569b
movslq %edi, %rax
leaq 0x5773(%rip), %rcx      # 0xadf0
movl (%rcx,%rax,4), %ebx
testl %edi, %edi
jne 0x569b
leaq 0x9a75(%rip), %rcx      # 0xf100
movq (%rcx,%rax,8), %rsi
leaq 0x5b0f(%rip), %rdi      # 0xb1a5
callq 0x683f
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/expr.c
// Function: member_access
static struct ASTnode *member_access(struct ASTnode *left, int withpointer) {
  struct ASTnode *right;
  struct symtable *typeptr;
  struct symtable *m;

  // 检查左树是不是个struct/union指针
  if (withpointer && left->type != pointer_to(P_STRUCT)
      && left->type != pointer_to(P_UNION))
    fatal("Expression is not a pointer to a struct/union");

  // 否则，检查左树是不是个struct/union
  // 如果是就改变节点类型，从A_IDENT到A_ADDR
  // 这样我们获得的是基地址，而不是地址里面的值
  if (!withpointer) {
    if (left->type == P_STRUCT || left->type == P_UNION)
      left->op = A_ADDR;
    else
      fatal("Expression is not a struct/union");
  }

  // 获取组合类型
  typeptr = left->ctype;

  // 跳过'.' 或者 '->'
  // 获取成员名字
  scan(&Token);
  ident();

  // 查找是否存在这个成员
  for (m = typeptr->member; m != NULL; m = m->next)
    if (!strcmp(m->name, Text))
      break;
  if (m == NULL)
    fatals("No member found in struct/union: ", Text);

  // 令左树为右值
  left->rvalue = 1;

  // 创建一个A_INTLIT节点，表示位移
  right = mkastleaf(A_INTLIT, P_INT, NULL, NULL, m->stu.st_posn);

  // 返回一个语法树节点，该节点是给这个struct/union的基地址加上位移
  // 然后再在这个节点基础上，再加个节点来解引用。现在这些节点还是左值
  left =
    mkastnode(A_ADD, pointer_to(m->type), m->ctype, left, NULL, right, NULL,
	      0);
  left = mkastunary(A_DEREF, m->type, m->ctype, left, NULL, 0);
  return (left);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl 0x8(%rdi), %r14d
testl %esi, %esi
je 0x56e4
movl $0x50, %edi
callq 0x8e52
cmpl %eax, %r14d
je 0x5705
movl 0x8(%rbx), %r14d
movl $0x60, %edi
callq 0x8e52
cmpl %eax, %r14d
je 0x5705
leaq 0x5a27(%rip), %rdi      # 0xb109
jmp 0x5700
cmpl $0x60, %r14d
je 0x56f0
cmpl $0x50, %r14d
jne 0x56f9
movl $0x25, 0x4(%rbx)
jmp 0x5705
leaq 0x5a37(%rip), %rdi      # 0xb137
callq 0x6937
movq 0x10(%rbx), %r14
leaq 0x9c90(%rip), %rdi      # 0xf3a0
callq 0x6b20
callq 0x690b
movq 0x40(%r14), %r15
testq %r15, %r15
je 0x5743
leaq 0x9ca6(%rip), %r14      # 0xf3d0
movq 0x8(%r15), %rdi
movq %r14, %rsi
callq 0x20f0
testl %eax, %eax
je 0x5748
movq 0x38(%r15), %r15
testq %r15, %r15
jne 0x572a
callq 0x21d0
movl $0x1, 0x18(%rbx)
movl (%r15), %r8d
movl $0x1a, %edi
movl $0x30, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x88b3
movq %rax, %r14
movl 0x10(%r15), %edi
callq 0x8e52
movq 0x18(%r15), %rdx
movl $0x15, %edi
movl %eax, %esi
movq %rbx, %rcx
xorl %r8d, %r8d
movq %r14, %r9
pushq $0x0
pushq $0x0
callq 0x8828
addq $0x10, %rsp
movl 0x10(%r15), %esi
movq 0x18(%r15), %rdx
movl $0x24, %edi
movq %rax, %rcx
xorl %r8d, %r8d
xorl %r9d, %r9d
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x88d3
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/expr.c
// Function: funccall
static struct ASTnode *funccall(void) {
  struct ASTnode *tree;
  struct symtable *funcptr;

  // 判断函数是否已经定义了
  if ((funcptr = findsymbol(Text)) == NULL || funcptr->stype != S_FUNCTION) {
    fatals("Undeclared function", Text);
  }

  // 是否匹配'('
  lparen();

  // 解析参数的表达式列表
  tree = expression_list(T_RPAREN);

  // TODO: 要检查每个参数类型是否匹配函数原型

  // 创建函数调用语法树节点，保存函数返回类型作为节点类型
  // 同时记录函数符号号
  tree =
    mkastunary(A_FUNCCALL, funcptr->type, funcptr->ctype, tree, funcptr, 0);

  // 是否匹配')'
  rparen();
  return (tree);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
leaq 0x9c0c(%rip), %rdi      # 0xf3d0
callq 0x8288
movq %rax, %rbx
testq %rax, %rax
je 0x57d7
cmpl $0x1, 0x20(%rbx)
je 0x57ea
leaq 0x58dc(%rip), %rdi      # 0xb0ba
leaq 0x9beb(%rip), %rsi      # 0xf3d0
callq 0x683f
callq 0x68df
movl $0x3a, %edi
callq 0x4cb0
movl 0x10(%rbx), %esi
movq 0x18(%rbx), %rdx
movl $0x23, %edi
movq %rax, %rcx
movq %rbx, %r8
xorl %r9d, %r9d
callq 0x88d3
movq %rax, %rbx
callq 0x68f5
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
nopl (%rax)
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/gen.c
// Function: gen_logandor
static int gen_logandor(struct ASTnode *n) {
  // 生成两个标签
  int Lfalse = genlabel();
  int Lend = genlabel();
  int reg;

  // 为左表达式生成代码, 如果表达式满足条件,则跳到false标签
  // 例如 1&&1+1 这个表达式,由于左边为true,那就不用执行右边,直接跳转到Lfalse
  reg = genAST(n->left, NOLABEL, NOLABEL, NOLABEL, 0);
  cgboolean(reg, n->op, Lfalse);
  genfreeregs(NOREG);

  // 为右表达式生成代码, 如果表达式满足条件,则跳到false标签
  reg = genAST(n->right, NOLABEL, NOLABEL, NOLABEL, 0);
  cgboolean(reg, n->op, Lfalse);
  genfreeregs(reg);

  // 设置寄存器的值
  // 这里很精彩,好好品品:)
  if (n->op == A_LOGAND) {
    cgloadboolean(reg, 1);
    cgjump(Lend);
    cglabel(Lfalse);
    cgloadboolean(reg, 0);
  } else {
    cgloadboolean(reg, 0);
    cgjump(Lend);
    cglabel(Lfalse);
    cgloadboolean(reg, 1);
  }
  cglabel(Lend);
  return (reg);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %r15
movl 0x8fcd(%rip), %r14d     # 0xf0f0
leal 0x1(%r14), %ebx
leal 0x2(%r14), %eax
movl %eax, 0x8fbf(%rip)      # 0xf0f0
movq 0x20(%rdi), %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x583d
movl 0x4(%r15), %esi
movl %eax, %edi
movl %r14d, %edx
callq 0x313d
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x24dc
movq 0x30(%r15), %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x583d
movl %eax, %r12d
movl 0x4(%r15), %esi
movl %eax, %edi
movl %r14d, %edx
callq 0x313d
movl %r12d, %edi
callq 0x24dc
xorl %r13d, %r13d
xorl %esi, %esi
cmpl $0x9, 0x4(%r15)
setne %r13b
sete %sil
movl %r12d, %edi
callq 0x310d
movl %ebx, %edi
callq 0x371c
movl %r14d, %edi
callq 0x295e
movl %r12d, %edi
movl %r13d, %esi
callq 0x310d
movl %ebx, %edi
callq 0x295e
movl %r12d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/main.c
// Function: alter_suffix
char *alter_suffix(char *str, char suffix) {
  char *posn;
  char *newstr;

  // 拷贝字符串
  if ((newstr = strdup(str)) == NULL)
    return (NULL);

  // 找到'.'的位置
  if ((posn = strrchr(newstr, '.')) == NULL)
    return (NULL);

  // 保证这里有个后缀
  posn++;
  if (*posn == '\0')
    return (NULL);

  // 改变后缀，并用NULL终结
  *posn = suffix;
  posn++;
  *posn = '\0';
  return (newstr);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movl %esi, %r14d
callq 0x2180
testq %rax, %rax
je 0x6281
movq %rax, %rbx
movq %rax, %rdi
movl $0x2e, %esi
callq 0x20b0
testq %rax, %rax
je 0x6281
cmpb $0x0, 0x1(%rax)
je 0x6281
movb %r14b, 0x1(%rax)
movb $0x0, 0x2(%rax)
jmp 0x6283
xorl %ebx, %ebx
movq %rbx, %rax
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/main.c
// Function: do_assemble
char *do_assemble(char *filename) {
  char cmd[TEXTLEN];
  int err;

  char *outfilename = alter_suffix(filename, 'o');
  if (outfilename == NULL) {
    fprintf(stderr, "Error: %s has no suffix, try .s on the end\n", filename);
    exit(1);
  }

  // 创建汇编命令,然后运行它
  snprintf(cmd, TEXTLEN, "%s %s %s", ASCMD, outfilename, filename);
  if (O_verbose)
    printf("%s\n", cmd);
  err = system(cmd);
  if (err != 0) {
    fprintf(stderr, "Assembly of %s failed\n", filename);
    exit(1);
  }
  return (outfilename);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x200, %rsp            # imm = 0x200
movq %rdi, %rbx
movl $0x6f, %esi
callq 0x6248
testq %rax, %rax
je 0x6309
movq %rax, %r14
leaq 0x5053(%rip), %rdx      # 0xb308
leaq 0x5055(%rip), %rcx      # 0xb311
leaq -0x210(%rbp), %rdi
movl $0x200, %esi            # imm = 0x200
movq %rax, %r8
movq %rbx, %r9
xorl %eax, %eax
callq 0x20a0
cmpl $0x0, 0x9074(%rip)      # 0xf350
je 0x62ea
leaq -0x210(%rbp), %rdi
callq 0x2060
leaq -0x210(%rbp), %rdi
callq 0x2080
testl %eax, %eax
jne 0x6311
movq %r14, %rax
addq $0x200, %rsp            # imm = 0x200
popq %rbx
popq %r14
popq %rbp
retq
movq %rbx, %rdi
callq 0x220e
movq %rbx, %rdi
callq 0x21e7
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/main.c
// Function: do_link
void do_link(char *outfilename, char **objlist) {
  int cnt, size = TEXTLEN;
  char cmd[TEXTLEN], *cptr;
  int err;

  // 先设置链接器命令和输出文件
  cptr = cmd;
  cnt = snprintf(cptr, size, "%s %s ", LDCMD, outfilename);
  cptr += cnt;
  size -= cnt;

  // 然后添加每个目标文件
  while (*objlist != NULL) {
    cnt = snprintf(cptr, size, "%s ", *objlist);
    cptr += cnt;
    size -= cnt;
    objlist++;
  }

  if (O_verbose)
    printf("%s\n", cmd);
  err = system(cmd);
  if (err != 0) {
    fprintf(stderr, "Linking failed\n");
    exit(1);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x200, %rsp            # imm = 0x200
movq %rsi, %rbx
movq %rdi, %r8
leaq 0x4ffa(%rip), %rdx      # 0xb332
leaq 0x4ffa(%rip), %rcx      # 0xb339
leaq -0x220(%rbp), %rdi
movl $0x200, %esi            # imm = 0x200
xorl %eax, %eax
callq 0x20a0
movq (%rbx), %rcx
testq %rcx, %rcx
je 0x63a2
movl $0x200, %r14d           # imm = 0x200
subl %eax, %r14d
cltq
leaq (%rax,%rbp), %r15
addq $-0x220, %r15           # imm = 0xFDE0
addq $0x8, %rbx
leaq 0x585a(%rip), %r12      # 0xbbd5
movslq %r14d, %r14
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
xorl %eax, %eax
callq 0x20a0
cltq
addq %rax, %r15
subl %eax, %r14d
movq (%rbx), %rcx
addq $0x8, %rbx
testq %rcx, %rcx
jne 0x637b
cmpl $0x0, 0x8fa7(%rip)      # 0xf350
je 0x63b7
leaq -0x220(%rbp), %rdi
callq 0x2060
leaq -0x220(%rbp), %rdi
callq 0x2080
testl %eax, %eax
jne 0x63d7
addq $0x200, %rsp            # imm = 0x200
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
callq 0x2235
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/main.c
// Function: usage
static void usage(char *prog) {
  fprintf(stderr, "Usage: %s [-vcSTM] [-o outfile] file [file ...]\n", prog);
  fprintf(stderr,
	  "       -v give verbose output of the compilation stages\n");
  fprintf(stderr, "       -c generate object files but don't link them\n");
  fprintf(stderr, "       -S generate assembly files but don't link them\n");
  fprintf(stderr, "       -T dump the AST trees for each input file\n");
  fprintf(stderr, "       -M dump the symbol table for each input file\n");
  fprintf(stderr, "       -o outfile, produce the outfile executable file\n");
  exit(1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq %rdi, %rdx
movq 0x888a(%rip), %rbx      # 0xeff0
movq (%rbx), %rdi
leaq 0x4c1b(%rip), %rsi      # 0xb38b
xorl %eax, %eax
callq 0x2100
movq (%rbx), %rcx
leaq 0x4c3b(%rip), %rdi      # 0xb3bc
movl $0x38, %esi
movl $0x1, %edx
callq 0x2170
movq (%rbx), %rcx
leaq 0x4c5b(%rip), %rdi      # 0xb3f5
movl $0x34, %esi
movl $0x1, %edx
callq 0x2170
movq (%rbx), %rcx
leaq 0x4c77(%rip), %rdi      # 0xb42a
movl $0x36, %esi
movl $0x1, %edx
callq 0x2170
movq (%rbx), %rcx
leaq 0x4c95(%rip), %rdi      # 0xb461
movl $0x31, %esi
movl $0x1, %edx
callq 0x2170
movq (%rbx), %rcx
leaq 0x4cae(%rip), %rdi      # 0xb493
movl $0x34, %esi
movl $0x1, %edx
callq 0x2170
movq (%rbx), %rcx
leaq 0x4cca(%rip), %rdi      # 0xb4c8
movl $0x37, %esi
movl $0x1, %edx
callq 0x2170
movl $0x1, %edi
callq 0x2160
nop
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/misc.c
// Function: fatals
void fatals(char *s1, char *s2) {
  fprintf(stderr, "%s:%s on line %d of %s\n", s1, s2, Line, Infilename);
  fclose(Outfile);
  unlink(Outfilename);
  exit(1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rsi, %rcx
movq %rdi, %rdx
movq 0x87a0(%rip), %rax      # 0xeff0
movq (%rax), %rdi
leaq 0x8b0e(%rip), %rax      # 0xf368
movl (%rax), %r8d
leaq 0x8b2c(%rip), %rax      # 0xf390
movq (%rax), %r9
leaq 0x4d48(%rip), %rsi      # 0xb5b6
xorl %eax, %eax
callq 0x2100
leaq 0x8b0c(%rip), %rax      # 0xf388
movq (%rax), %rdi
callq 0x2070
leaq 0x8b0d(%rip), %rax      # 0xf398
movq (%rax), %rdi
callq 0x2050
movl $0x1, %edi
callq 0x2160
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/misc.c
// Function: fatal
void fatal(char *s) {
  fprintf(stderr, "%s on line %d of %s\n", s, Line, Infilename);
  fclose(Outfile);
  unlink(Outfilename);
  exit(1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, %rdx
movq 0x86ab(%rip), %rax      # 0xeff0
movq (%rax), %rdi
leaq 0x8a19(%rip), %rax      # 0xf368
movl (%rax), %ecx
leaq 0x8a38(%rip), %rax      # 0xf390
movq (%rax), %r8
leaq 0x4c57(%rip), %rsi      # 0xb5b9
xorl %eax, %eax
callq 0x2100
leaq 0x8a18(%rip), %rax      # 0xf388
movq (%rax), %rdi
callq 0x2070
leaq 0x8a19(%rip), %rax      # 0xf398
movq (%rax), %rdi
callq 0x2050
movl $0x1, %edi
callq 0x2160
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/misc.c
// Function: fatald
void fatald(char *s, int d) {
  fprintf(stderr, "%s:%d on line %d of %s\n", s, d, Line, Infilename);
  fclose(Outfile);
  unlink(Outfilename);
  exit(1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movl %esi, %ecx
movq %rdi, %rdx
movq 0x864f(%rip), %rax      # 0xeff0
movq (%rax), %rdi
leaq 0x89bd(%rip), %rax      # 0xf368
movl (%rax), %r8d
leaq 0x89db(%rip), %rax      # 0xf390
movq (%rax), %r9
leaq 0x4c0f(%rip), %rsi      # 0xb5ce
xorl %eax, %eax
callq 0x2100
leaq 0x89bb(%rip), %rax      # 0xf388
movq (%rax), %rdi
callq 0x2070
leaq 0x89bc(%rip), %rax      # 0xf398
movq (%rax), %rdi
callq 0x2050
movl $0x1, %edi
callq 0x2160
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/misc.c
// Function: fatalc
void fatalc(char *s, int c) {
  fprintf(stderr, "%s:%c on line %d of %s\n", s, c, Line, Infilename);
  fclose(Outfile);
  unlink(Outfilename);
  exit(1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movl %esi, %ecx
movq %rdi, %rdx
movq 0x85f2(%rip), %rax      # 0xeff0
movq (%rax), %rdi
leaq 0x8960(%rip), %rax      # 0xf368
movl (%rax), %r8d
leaq 0x897e(%rip), %rax      # 0xf390
movq (%rax), %r9
leaq 0x4bca(%rip), %rsi      # 0xb5e6
xorl %eax, %eax
callq 0x2100
leaq 0x895e(%rip), %rax      # 0xf388
movq (%rax), %rdi
callq 0x2070
leaq 0x895f(%rip), %rax      # 0xf398
movq (%rax), %rdi
callq 0x2050
movl $0x1, %edi
callq 0x2160
nop
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/opt.c
// Function: fold
static struct ASTnode *fold(struct ASTnode *n) {

  if (n == NULL)
    return (NULL);

  // 折叠左子树和右子树
  n->left = fold(n->left);
  n->right = fold(n->right);

  // 如果两个子树都是A_INTLITs，使用fold2()折叠
  if (n->left && n->left->op == A_INTLIT) {
    if (n->right && n->right->op == A_INTLIT)
      n = fold2(n);
    else
      // 如果只是左子树是A_INTLIT,使用fold1()折叠
      n = fold1(n);
  }

  // 返回可能折叠过的树
  return (n);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x6aba
movq %rdi, %rbx
movq 0x20(%rdi), %rdi
callq 0x6a53
movq %rax, 0x20(%rbx)
movq 0x30(%rbx), %rdi
callq 0x6a53
movq %rax, 0x30(%rbx)
movq 0x20(%rbx), %rcx
testq %rcx, %rcx
je 0x6abc
cmpl $0x1a, 0x4(%rcx)
jne 0x6abc
testq %rax, %rax
je 0x6ac6
cmpl $0x1a, 0x4(%rax)
jne 0x6ac6
movl 0x4(%rbx), %edx
addl $-0x15, %edx
cmpl $0x3, %edx
ja 0x6abc
movl (%rcx), %ecx
movl (%rax), %r8d
leaq 0x4b54(%rip), %rax      # 0xb600
movslq (%rax,%rdx,4), %rdx
addq %rax, %rdx
jmpq *%rdx
addl %ecx, %r8d
jmp 0x6b06
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
movl (%rcx), %r8d
movl 0x4(%rbx), %eax
cmpl $0x21, %eax
je 0x6b06
cmpl $0x2d, %eax
je 0x6ae0
cmpl $0x2c, %eax
jne 0x6abc
notl %r8d
jmp 0x6b06
xorl %eax, %eax
testl %r8d, %r8d
sete %al
movl %eax, %r8d
jmp 0x6b06
imull %ecx, %r8d
jmp 0x6b06
testl %r8d, %r8d
je 0x6abc
movl %ecx, %eax
cltd
idivl %r8d
jmp 0x6ae8
subl %r8d, %ecx
movl %ecx, %r8d
movl 0x8(%rbx), %esi
movl $0x1a, %edi
xorl %edx, %edx
xorl %ecx, %ecx
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x88b3
nopl (%rax)
// File: /workspace/github_c_makefile_star2_O3/ejunjsh[P]mycc/scan.c
// Function: next
static int next(void) {
  int c, l;

  if (Putback) {		// 如果putback有值，
    c = Putback;		// 就用putback的值
    Putback = 0;
    return (c);
  }

  c = fgetc(Infile);			// 从输入文件读入一个字符

  while (Linestart && c == '#') {	// 预处理开始
    Linestart = 0;			// 不在行首
    scan(&Token);			// 获取行号放到l
    if (Token.token != T_INTLIT)
      fatals("Expecting pre-processor line number, got:", Text);
    l = Token.intvalue;

    scan(&Token);			// 获得文件名放在Text
    if (Token.token != T_STRLIT)
      fatals("Expecting pre-processor file name, got:", Text);

    if (Text[0] != '<') {		// 如果这是真的文件名
      if (strcmp(Text, Infilename))	// 跟我们已有的不一样
	    Infilename = strdup(Text);	// 保存它，然后更新行号
      Line = l;
    }

    while ((c = fgetc(Infile)) != '\n'); // 调到下一行
    c = fgetc(Infile);			// 获取下一个字符
    Linestart = 1;			// 现在在行首了
  }

  Linestart = 0;			// 不在行首
  if ('\n' == c) {
    Line++;				// 增加行号
    Linestart = 1;			// 现在在行首了
  }
  return (c);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
leaq 0x83cc(%rip), %rcx      # 0xf370
movl (%rcx), %eax
testl %eax, %eax
je 0x6fb5
movl $0x0, (%rcx)
jmp 0x70c1
leaq 0x83c4(%rip), %r15      # 0xf380
movq (%r15), %rdi
callq 0x20d0
leaq 0x83a1(%rip), %r13      # 0xf36c
cmpl $0x23, %eax
jne 0x709e
cmpl $0x0, (%r13)
je 0x709e
leaq 0x83ba(%rip), %rbx      # 0xf3a0
leaq 0x83a3(%rip), %r14      # 0xf390
movl $0x0, (%r13)
movq %rbx, %rdi
callq 0x6b20
cmpl $0x33, (%rbx)
je 0x7015
leaq 0x4840(%rip), %rdi      # 0xb849
leaq 0x83c0(%rip), %rsi      # 0xf3d0
callq 0x683f
movl 0x10(%rbx), %r12d
movq %rbx, %rdi
callq 0x6b20
cmpl $0x34, (%rbx)
je 0x7039
leaq 0x4846(%rip), %rdi      # 0xb873
leaq 0x839c(%rip), %rsi      # 0xf3d0
callq 0x683f
leaq 0x8390(%rip), %rax      # 0xf3d0
cmpb $0x3c, (%rax)
je 0x7078
movq %r14, %r13
movq (%r14), %rsi
movq %rax, %rdi
callq 0x20f0
testl %eax, %eax
je 0x7067
leaq 0x8372(%rip), %rdi      # 0xf3d0
callq 0x2180
movq %rax, (%r13)
leaq 0x82fa(%rip), %rax      # 0xf368
movl %r12d, (%rax)
leaq 0x82f4(%rip), %r13      # 0xf36c
movq (%r15), %rdi
callq 0x20d0
cmpl $0xa, %eax
jne 0x7078
movq (%r15), %rdi
callq 0x20d0
movl $0x1, (%r13)
cmpl $0x23, %eax
je 0x6fed
movl $0x0, (%r13)
cmpl $0xa, %eax
jne 0x70c1
leaq 0x82b6(%rip), %rax      # 0xf368
incl (%rax)
movl $0x1, (%r13)
movl $0xa, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq