// File: /workspace/github_c_makefile_star2_O0/ejunjsh[P]mycc/gen.c
// Function: genSWITCH
static int genSWITCH(struct ASTnode *n) {
  int *caseval, *caselabel;
  int Ljumptop, Lend;
  int i, reg, defaultlabel = 0, casecount = 0;
  struct ASTnode *c;

  // 分别创建case值和相关联的标签的数组
  // 保证数组至少有一个元素
  caseval = (int *) malloc((n->atu.a_intvalue + 1) * sizeof(int));
  caselabel = (int *) malloc((n->atu.a_intvalue + 1) * sizeof(int));

  // 生成跳表的标签和整个SWITCH语句的结束标签
  // 设置默认标签为结束标签
  Ljumptop = genlabel();
  Lend = genlabel();
  defaultlabel = Lend;

  // 输出switch条件判断的汇编
  reg = genAST(n->left, NOLABEL, NOLABEL, NOLABEL, 0);
  cgjump(Ljumptop);
  genfreeregs(reg);

  // 沿着右子树去生成每个case的汇编
  for (i = 0, c = n->right; c != NULL; i++, c = c->right) {

    // 获得一个case的标签号,保存它和值到数组里
    // 如果有default case,就存到defaultlabel
    caselabel[i] = genlabel();
    caseval[i] = c->atu.a_intvalue;
    cglabel(caselabel[i]);
    if (c->op == A_DEFAULT)
      defaultlabel = caselabel[i];
    else
      casecount++;

    // 生成case body的汇编代码,传Lend是为了处理break的情况
    // 如果case没有body,直接到下个case
    if (c->left)
      genAST(c->left, NOLABEL, NOLABEL, Lend, 0);
    genfreeregs(NOREG);
  }

  // 保证最后个case跳过switch表
  cgjump(Lend);

  // 输出switch表和结束标签
  cgswitch(reg, casecount, Ljumptop, caselabel, caseval, defaultlabel);
  cglabel(Lend);
  return (NOREG);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movl $0x0, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
addl $0x1, %eax
movslq %eax, %rdi
shlq $0x2, %rdi
callq 0x2100
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
addl $0x1, %eax
movslq %eax, %rdi
shlq $0x2, %rdi
callq 0x2100
movq %rax, -0x18(%rbp)
callq 0x6830
movl %eax, -0x1c(%rbp)
callq 0x6830
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
xorl %r8d, %r8d
movl %r8d, %esi
movl %r8d, %edx
movl %r8d, %ecx
callq 0x6850
movl %eax, -0x28(%rbp)
movl -0x1c(%rbp), %edi
callq 0x3bc0
movl -0x28(%rbp), %edi
callq 0x7520
movl $0x0, -0x24(%rbp)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x728a
callq 0x6830
movl %eax, %edx
movq -0x18(%rbp), %rax
movslq -0x24(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x38(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x18(%rbp), %rax
movslq -0x24(%rbp), %rcx
movl (%rax,%rcx,4), %edi
callq 0x2960
movq -0x38(%rbp), %rax
cmpl $0x33, 0x4(%rax)
jne 0x7239
movq -0x18(%rbp), %rax
movslq -0x24(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x2c(%rbp)
jmp 0x7242
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
movq -0x38(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x7266
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rdi
movl -0x20(%rbp), %ecx
xorl %r8d, %r8d
movl %r8d, %esi
movl %r8d, %edx
callq 0x6850
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x7520
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x71e1
movl -0x20(%rbp), %edi
callq 0x3bc0
movl -0x28(%rbp), %edi
movl -0x30(%rbp), %esi
movl -0x1c(%rbp), %edx
movq -0x18(%rbp), %rcx
movq -0x10(%rbp), %r8
movl -0x2c(%rbp), %r9d
callq 0x4130
movl -0x20(%rbp), %edi
callq 0x2960
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x40, %rsp
popq %rbp
retq
nop