// File: /workspace/github_c_makefile_star2_O0/taeguk[P]Compiler-Proj-Cminus/src/cgen.c
// Function: localCodeGen
static int localCodeGen(TreeNode *syntaxTree, FILE *codeStream, int currStack, int travSibling)
{
  TreeNode *t;
  for(t = syntaxTree;
      t != NULL;
      t = travSibling ? t->sibling : NULL)
    {
      switch (t->nodeKind)
        {

        case VariableDeclarationK:
        {
          int size = sizeof(int);

          fprintf(codeStream, "\n# Local variable declaration\n");
          fprintf(codeStream, "addiu $sp, $sp, %d\n", -size);
          currStack += size;
          t->attr.varDecl._var->symbolInfo->attr.intInfo.memloc = -currStack;
          break;
        }
        case ArrayDeclarationK:
        {
          int size = regSize * t->attr.varDecl._var->symbolInfo->attr.arrInfo.arrLen;
          fprintf(codeStream, "\n# Local array declaration\n");
          fprintf(codeStream, "addiu $sp, $sp, %d\n", -size);
          t->attr.varDecl._var->symbolInfo->attr.arrInfo.memloc = -currStack-size;
          currStack += size;
          break;
        }

        case CompoundStatementK:
        {
          fprintf(codeStream, "\n# Compound Statement\n");
          int updateStack = currStack;

          updateStack = localCodeGen(t->attr.cmpdStmt.local_decl, codeStream, updateStack, 1);
          if(localCodeGen(t->attr.cmpdStmt.stmt_list, codeStream, updateStack, 1) != updateStack, 1)
            DONT_OCCUR_PRINT;

          // stack cleanup
          if(updateStack < currStack)
            DONT_OCCUR_PRINT;

          fprintf(codeStream, "\n# Local stack cleanup\n");
          fprintf(codeStream, "addiu $sp, $sp, %d\n", updateStack - currStack);

          /*
          if(updateStack > 0) // it does not have return stmt
            {
              fprintf(codeStream, "\n# Local stack cleanup\n");
              fprintf(codeStream, "addiu $sp, $sp, %d\n", updateStack - currStack);
            }
          */
          break;
        }
        case ExpressionStatementK:
        {
          if(localCodeGen(t->attr.exprStmt.expr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          break;
        }
        case SelectionStatementK:
        {
          fprintf(codeStream, "\n# Selection Statement\n");
          fprintf(codeStream, "# Selection Statement Expression\n");
          if(localCodeGen(t->attr.selectStmt.expr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          int L_exit = labelAlloc(), L_false = labelAlloc();
          fprintf(codeStream, "beqz $v0, L%d\n", L_false);
          fprintf(codeStream, "# Selection Statement If Statement\n");
          if(localCodeGen(t->attr.selectStmt.if_stmt, codeStream, currStack, 1) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "j L%d\n", L_exit);
          fprintf(codeStream, "L%d:\n", L_false);
          fprintf(codeStream, "# Selection Statement Else Statement\n");
          if(localCodeGen(t->attr.selectStmt.else_stmt, codeStream, currStack, 1) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "L%d:\n", L_exit);
          break;
        }
        case IterationStatementK:
        {
          fprintf(codeStream, "\n# Iteration Statement\n");
          int L_cmp = labelAlloc(), L_loop = labelAlloc();
          fprintf(codeStream, "j L%d\n", L_cmp);
          fprintf(codeStream, "L%d:\n", L_loop);
          fprintf(codeStream, "# Iteration Statement Loop Statement\n");
          if(localCodeGen(t->attr.iterStmt.loop_stmt, codeStream, currStack, 1) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "L%d:\n", L_cmp);
          fprintf(codeStream, "# Iteration Statement Expression\n");
          if(localCodeGen(t->attr.iterStmt.expr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "bnez $v0, L%d\n", L_loop);
          break;
        }
        case ReturnStatementK:
        {
          // TODO: review this
          // ex) have to jr immediatly (but have to clean stack with prev value
          // of registers. no need to load. just roll up the stack.)
          // int f(int i) {
          //   if(i) {
          //     int j;
          //     return 1;
          //   }
          //   return 0;
          // }
          if(t->attr.retStmt.expr != NULL)
            if(localCodeGen(t->attr.retStmt.expr, codeStream, currStack, 0) != currStack)
              DONT_OCCUR_PRINT;

          fprintf(codeStream, "j L%d\n", L_cleanup);

          break;

          /*
          // cleanup
          fprintf(codeStream, "\n# Stack cleanup\n");

          // return to original sp
          fprintf(codeStream, "addiu $sp, $sp, %d\n", currStack - 10 * regSize);

          // load register $fp
          fprintf(codeStream, "lw $fp, %d($sp)\n", 0 * regSize);
          // load registers $s0~$s7
          int i;
          for(i=0; i<8; ++i)
            fprintf(codeStream, "lw $s%d, %d($sp)\n", i, (i+1) * regSize);
          // load register $ra
          fprintf(codeStream, "lw $ra, %d($sp)\n", 9 * regSize);

          // free stack
          fprintf(codeStream, "addiu $sp, $sp, %d\n", 10 * regSize);

          // return
          fprintf(codeStream, "\n# Return to caller\n");
          fprintf(codeStream, "jr $ra\n\n");
          */

          // Optimization: do not need to check other stmts
          //return 0;
        }

        case AssignExpressionK:
        {
          if(localCodeGen(t->attr.assignStmt.expr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          if (t->attr.assignStmt._var->nodeKind == VariableK)
            {
              fprintf(codeStream,
                      t->attr.assignStmt._var->symbolInfo->attr.intInfo.globalFlag ?
                      "sw $v0, %d\n" : "sw $v0, %d($fp)\n",
                      t->attr.assignStmt._var->symbolInfo->attr.intInfo.memloc);
            }
          else if (t->attr.assignStmt._var->nodeKind == ArrayK)
            {
              fprintf(codeStream, "move $s1, $v0\n");
              {
                TreeNode* arr = t->attr.assignStmt._var;
                if(localCodeGen(arr->attr.arr.arr_expr, codeStream, currStack, 0) != currStack)
                  DONT_OCCUR_PRINT;
                fprintf(codeStream, "li $s0, %lu\n", sizeof(int));
                fprintf(codeStream, "mul $s0, $v0, $s0\n");
                if(localCodeGen(arr->attr.arr._var, codeStream, currStack, 0) != currStack)
                  DONT_OCCUR_PRINT;
                fprintf(codeStream, "add $v0, $v0, $s0\n");
              }
              /*
              if(localCodeGen(t->attr.assignStmt._var, codeStream, currStack) != currStack)
                DONT_OCCUR_PRINT;*/
              fprintf(codeStream, "sw $s1, 0($v0)\n");
              fprintf(codeStream, "move $v0, $s1\n");
            }
          else
            DONT_OCCUR_PRINT;
          break;
        }
        case ComparisonExpressionK:
        {
          if(localCodeGen(t->attr.cmpExpr.lexpr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "addiu $sp, $sp, -%lu\n", sizeof(int));
          fprintf(codeStream, "sw $v0, 0($sp)\n");
          currStack += sizeof(int);

          if(localCodeGen(t->attr.cmpExpr.rexpr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "lw $s0, 0($sp)\n");
          fprintf(codeStream, "addiu $sp, $sp, %lu\n", sizeof(int));
          currStack -= sizeof(int);

          switch(t->attr.cmpExpr.op->attr.TOK)
            {
            case LT: fprintf(codeStream, "slt $v0, $s0, $v0\n"); break;
            case LE: fprintf(codeStream, "sle $v0, $s0, $v0\n"); break;
            case GT: fprintf(codeStream, "sgt $v0, $s0, $v0\n"); break;
            case GE: fprintf(codeStream, "sge $v0, $s0, $v0\n"); break;
            case EQ: fprintf(codeStream, "seq $v0, $s0, $v0\n"); break;
            case NE: fprintf(codeStream, "sne $v0, $s0, $v0\n"); break;
            default: DONT_OCCUR_PRINT;
            }
          break;
        }
        case AdditiveExpressionK:
        {
          if(localCodeGen(t->attr.addExpr.lexpr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "addiu $sp, $sp, -%lu\n", sizeof(int));
          fprintf(codeStream, "sw $v0, 0($sp)\n");
          currStack += sizeof(int);

          if(localCodeGen(t->attr.addExpr.rexpr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "lw $s0, 0($sp)\n");
          fprintf(codeStream, "addiu $sp, $sp, %lu\n", sizeof(int));
          currStack -= sizeof(int);

          switch(t->attr.addExpr.op->attr.TOK)
            {
            case PLUS: fprintf(codeStream, "add $v0, $s0, $v0\n"); break;
            case MINUS: fprintf(codeStream, "sub $v0, $s0, $v0\n"); break;
            default: DONT_OCCUR_PRINT;
            }
          break;
          //return currStack; //break;
        }
        case MultiplicativeExpressionK:
        {
          if(localCodeGen(t->attr.multExpr.lexpr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "addiu $sp, $sp, -%lu\n", sizeof(int));
          fprintf(codeStream, "sw $v0, 0($sp)\n");
          currStack += sizeof(int);

          if(localCodeGen(t->attr.multExpr.rexpr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "lw $s0, 0($sp)\n");
          fprintf(codeStream, "addiu $sp, $sp, %lu\n", sizeof(int));
          currStack -= sizeof(int);

          switch(t->attr.multExpr.op->attr.TOK)
            {
            case TIMES: fprintf(codeStream, "mul $v0, $s0, $v0\n"); break;
            case OVER: fprintf(codeStream, "div $v0, $s0, $v0\n"); break;
            default: DONT_OCCUR_PRINT;
            }
          break;
        }

        case CallK:
        {
          int accLoc = 0, i;
          TreeNode *expr;
          if (!strcmp(t->attr.call._var->attr.ID, "input"))
            {
              // print "input : "
              fprintf(codeStream, "\n# input\n");
              fprintf(codeStream, "li $v0, 4\n");
              fprintf(codeStream, "la $a0, input_str\n");
              fprintf(codeStream, "syscall\n");
              // read_int
              fprintf(codeStream, "li $v0, 5\n");
              fprintf(codeStream, "syscall\n");
            }
          else if (!strcmp(t->attr.call._var->attr.ID, "output"))
            {
              // print "output : "
              fprintf(codeStream, "\n# output\n");
              fprintf(codeStream, "move $t0, $v0\n");
              fprintf(codeStream, "li $v0, 4\n");
              fprintf(codeStream, "la $a0, output_str\n");
              fprintf(codeStream, "syscall\n");
              fprintf(codeStream, "move $v0, $t0\n");
              // print_int
              if (localCodeGen(t->attr.call.expr_list, codeStream, currStack + accLoc, 1) != (currStack + accLoc))
                DONT_OCCUR_PRINT;
              fprintf(codeStream, "move $a0, $v0\n"); // the argument
              fprintf(codeStream, "li $v0, 1\n");
              fprintf(codeStream, "syscall\n");
              // print newline
              fprintf(codeStream, "li $v0, 4\n");
              fprintf(codeStream, "la $a0, newline\n");
              fprintf(codeStream, "syscall\n");
            }
          else
            {
              for(expr = t->attr.call.expr_list, i = 0;
                  expr != NULL;
                  expr = expr->sibling, i++)
                {
                  int size;
                  switch(t->attr.call._var->symbolInfo->attr.funcInfo.paramTypeList[i])
                    {
                    case IntT: size = sizeof(int); break;
                    case IntArrayT: size = regSize; break;
                    default: DONT_OCCUR_PRINT;
                    }

                  if(localCodeGen(expr, codeStream, currStack + accLoc, 0) != (currStack + accLoc))
                    DONT_OCCUR_PRINT;

                  fprintf(codeStream, "addiu $sp, $sp, %d\n", -size);
                  fprintf(codeStream, "sw $v0, 0($sp)\n");
                  accLoc += size;
                }
              fprintf(codeStream, "jal %s\n", t->attr.call._var->attr.ID);
              fprintf(codeStream, "addiu $sp, $sp, %d\n", accLoc);
            }

          break;
          /* For fixing a bug about iteration of sibling in parameter passing. */
          //return currStack;//break;
        }

        case ArrayK:
        {
          if(localCodeGen(t->attr.arr.arr_expr, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "li $s0, %lu\n", sizeof(int));
          fprintf(codeStream, "mul $s0, $v0, $s0\n");
          if(localCodeGen(t->attr.arr._var, codeStream, currStack, 0) != currStack)
            DONT_OCCUR_PRINT;
          fprintf(codeStream, "add $v0, $v0, $s0\n");
          fprintf(codeStream, "lw $v0, 0($v0)\n");
          
          break;
          /* For fixing a bug about iteration of sibling in parameter passing. */
          //return currStack;//break;
        }
        case VariableK:
        {
          switch(t->symbolInfo->nodeType)
            {
            case IntT:
              fprintf(codeStream,
                      t->symbolInfo->attr.intInfo.globalFlag ? "lw $v0, %d\n" : "lw $v0, %d($fp)\n",
                      t->symbolInfo->attr.intInfo.memloc);
              break;
            case IntArrayT:
              fprintf(codeStream,
                      t->symbolInfo->attr.arrInfo.globalFlag ? "li $v0, %d\n" : "addiu $v0, $fp, %d\n",
                      t->symbolInfo->attr.arrInfo.memloc);
              if (t->symbolInfo->attr.arrInfo.isParam)
                fprintf(codeStream, "lw $v0, 0($v0)\n");
              break;
            default:
              DONT_OCCUR_PRINT;
            }

          break;
          /* For fixing a bug about iteration of sibling in parameter passing. */
          //return currStack;//break;
        }
        case ConstantK:
        {
          fprintf(codeStream, "li $v0, %d\n", t->attr.NUM);
          
          break;
          /* For fixing a bug about iteration of sibling in parameter passing. */
          //return currStack;//break;
        }

        default:
          DONT_OCCUR_PRINT;
        }
    }
  return currStack;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x39cb
movq -0x20(%rbp), %rax
movl 0xc(%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x68(%rbp)
subl $0x11, %eax
ja 0x3996
movq -0x68(%rbp), %rax
leaq 0x68a5(%rip), %rcx      # 0x95e4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x4, -0x24(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x6a90(%rip), %rsi      # 0x97ea
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
xorl %edx, %edx
subl -0x24(%rbp), %edx
leaq 0x6969(%rip), %rsi      # 0x96da
movb $0x0, %al
callq 0x1120
movl -0x24(%rbp), %eax
addl -0x14(%rbp), %eax
movl %eax, -0x14(%rbp)
xorl %ecx, %ecx
subl -0x14(%rbp), %ecx
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x18(%rax), %rax
movl %ecx, 0xc(%rax)
jmp 0x3998
movl 0xb368(%rip), %eax      # 0xe108
movq -0x20(%rbp), %rcx
movq 0x28(%rcx), %rcx
movq 0x18(%rcx), %rcx
imull 0x14(%rcx), %eax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x6a4b(%rip), %rsi      # 0x9809
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
xorl %edx, %edx
subl -0x28(%rbp), %edx
leaq 0x6905(%rip), %rsi      # 0x96da
movb $0x0, %al
callq 0x1120
xorl %ecx, %ecx
subl -0x14(%rbp), %ecx
subl -0x28(%rbp), %ecx
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x18(%rax), %rax
movl %ecx, 0xc(%rax)
movl -0x28(%rbp), %eax
addl -0x14(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0x3998
movq -0x10(%rbp), %rdi
leaq 0x6a19(%rip), %rsi      # 0x9825
movb $0x0, %al
callq 0x1120
movl -0x14(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x2c(%rbp), %edx
movl $0x1, %ecx
callq 0x2cf0
movl %eax, -0x2c(%rbp)
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x2c(%rbp), %edx
movl $0x1, %ecx
callq 0x2cf0
movb $0x1, %al
testb $0x1, %al
jne 0x2e56
jmp 0x2e58
jmp 0x2e58
movl -0x2c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x2e62
jmp 0x2e62
movq -0x10(%rbp), %rdi
leaq 0x69cf(%rip), %rsi      # 0x983c
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %edx
subl -0x14(%rbp), %edx
leaq 0x6855(%rip), %rsi      # 0x96da
movb $0x0, %al
callq 0x1120
jmp 0x3998
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x2eae
jmp 0x2eae
jmp 0x3998
movq -0x10(%rbp), %rdi
leaq 0x6996(%rip), %rsi      # 0x9854
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x699c(%rip), %rsi      # 0x986c
movb $0x0, %al
callq 0x1120
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x2ef4
jmp 0x2ef4
callq 0x2cd0
movl %eax, -0x30(%rbp)
callq 0x2cd0
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rdi
movl -0x34(%rbp), %edx
leaq 0x697c(%rip), %rsi      # 0x988e
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6979(%rip), %rsi      # 0x989d
movb $0x0, %al
callq 0x1120
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl $0x1, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x2f4b
jmp 0x2f4b
movq -0x10(%rbp), %rdi
movl -0x30(%rbp), %edx
leaq 0x6968(%rip), %rsi      # 0x98c1
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
movl -0x34(%rbp), %edx
leaq 0x6810(%rip), %rsi      # 0x977e
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6948(%rip), %rsi      # 0x98c8
movb $0x0, %al
callq 0x1120
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl $0x1, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x2fa7
jmp 0x2fa7
movq -0x10(%rbp), %rdi
movl -0x30(%rbp), %edx
leaq 0x67c9(%rip), %rsi      # 0x977e
movb $0x0, %al
callq 0x1120
jmp 0x3998
movq -0x10(%rbp), %rdi
leaq 0x6922(%rip), %rsi      # 0x98ee
movb $0x0, %al
callq 0x1120
callq 0x2cd0
movl %eax, -0x38(%rbp)
callq 0x2cd0
movl %eax, -0x3c(%rbp)
movq -0x10(%rbp), %rdi
movl -0x38(%rbp), %edx
leaq 0x68d0(%rip), %rsi      # 0x98c1
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %edx
leaq 0x6778(%rip), %rsi      # 0x977e
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x68ee(%rip), %rsi      # 0x9906
movb $0x0, %al
callq 0x1120
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl $0x1, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x303f
jmp 0x303f
movq -0x10(%rbp), %rdi
movl -0x38(%rbp), %edx
leaq 0x6731(%rip), %rsi      # 0x977e
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x68cd(%rip), %rsi      # 0x992c
movb $0x0, %al
callq 0x1120
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x3083
jmp 0x3083
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %edx
leaq 0x68bd(%rip), %rsi      # 0x994e
movb $0x0, %al
callq 0x1120
jmp 0x3998
movq -0x20(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x30c7
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x30c5
jmp 0x30c5
jmp 0x30c7
movq -0x10(%rbp), %rdi
movl 0xb067(%rip), %edx      # 0xe138
leaq 0x67e9(%rip), %rsi      # 0x98c1
movb $0x0, %al
callq 0x1120
jmp 0x3998
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x3101
jmp 0x3101
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
cmpl $0xf, 0xc(%rax)
jne 0x3152
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x18(%rax), %rax
movl 0x10(%rax), %ecx
leaq 0x6840(%rip), %rsi      # 0x9969
leaq 0x682d(%rip), %rax      # 0x995d
cmpl $0x0, %ecx
cmovneq %rax, %rsi
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x18(%rax), %rax
movl 0xc(%rax), %edx
movb $0x0, %al
callq 0x1120
jmp 0x3221
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
cmpl $0x10, 0xc(%rax)
jne 0x321d
movq -0x10(%rbp), %rdi
leaq 0x680b(%rip), %rsi      # 0x997a
movb $0x0, %al
callq 0x1120
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x319f
jmp 0x319f
movq -0x10(%rbp), %rdi
leaq 0x67df(%rip), %rsi      # 0x9989
movl $0x4, %edx
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x67d5(%rip), %rsi      # 0x9996
movb $0x0, %al
callq 0x1120
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x31e5
jmp 0x31e5
movq -0x10(%rbp), %rdi
leaq 0x67b9(%rip), %rsi      # 0x99a9
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x67ba(%rip), %rsi      # 0x99bc
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x67b8(%rip), %rsi      # 0x99cc
movb $0x0, %al
callq 0x1120
jmp 0x321f
jmp 0x321f
jmp 0x3221
jmp 0x3998
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x3243
jmp 0x3243
movq -0x10(%rbp), %rdi
leaq 0x678d(%rip), %rsi      # 0x99db
movl $0x4, %edx
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x678c(%rip), %rsi      # 0x99f1
movb $0x0, %al
callq 0x1120
movslq -0x14(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x14(%rbp)
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x3294
jmp 0x3294
movq -0x10(%rbp), %rdi
leaq 0x6762(%rip), %rsi      # 0x9a01
xorl %eax, %eax
movb %al, -0x71(%rbp)
callq 0x1120
movb -0x71(%rbp), %al
movq -0x10(%rbp), %rdi
leaq 0x675a(%rip), %rsi      # 0x9a11
movl $0x4, %edx
callq 0x1120
movl -0x14(%rbp), %eax
addl $-0x4, %eax
movl %eax, -0x14(%rbp)
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movl 0x20(%rax), %eax
addl $0xfffffef1, %eax       # imm = 0xFFFFFEF1
movl %eax, %ecx
movq %rcx, -0x70(%rbp)
subl $0x5, %eax
ja 0x3375
movq -0x70(%rbp), %rax
leaq 0x6338(%rip), %rcx      # 0x962c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
leaq 0x671e(%rip), %rsi      # 0x9a26
movb $0x0, %al
callq 0x1120
jmp 0x3377
movq -0x10(%rbp), %rdi
leaq 0x671d(%rip), %rsi      # 0x9a39
movb $0x0, %al
callq 0x1120
jmp 0x3377
movq -0x10(%rbp), %rdi
leaq 0x671c(%rip), %rsi      # 0x9a4c
movb $0x0, %al
callq 0x1120
jmp 0x3377
movq -0x10(%rbp), %rdi
leaq 0x671b(%rip), %rsi      # 0x9a5f
movb $0x0, %al
callq 0x1120
jmp 0x3377
movq -0x10(%rbp), %rdi
leaq 0x671a(%rip), %rsi      # 0x9a72
movb $0x0, %al
callq 0x1120
jmp 0x3377
movq -0x10(%rbp), %rdi
leaq 0x6719(%rip), %rsi      # 0x9a85
movb $0x0, %al
callq 0x1120
jmp 0x3377
jmp 0x3377
jmp 0x3998
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x3399
jmp 0x3399
movq -0x10(%rbp), %rdi
leaq 0x6637(%rip), %rsi      # 0x99db
movl $0x4, %edx
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6636(%rip), %rsi      # 0x99f1
movb $0x0, %al
callq 0x1120
movslq -0x14(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x14(%rbp)
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x33ea
jmp 0x33ea
movq -0x10(%rbp), %rdi
leaq 0x660c(%rip), %rsi      # 0x9a01
xorl %eax, %eax
movb %al, -0x79(%rbp)
callq 0x1120
movb -0x79(%rbp), %al
movq -0x10(%rbp), %rdi
leaq 0x6604(%rip), %rsi      # 0x9a11
movl $0x4, %edx
callq 0x1120
movl -0x14(%rbp), %eax
addl $-0x4, %eax
movl %eax, -0x14(%rbp)
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movl 0x20(%rax), %eax
movl %eax, -0x78(%rbp)
subl $0x10b, %eax            # imm = 0x10B
je 0x3443
jmp 0x3437
movl -0x78(%rbp), %eax
subl $0x10c, %eax            # imm = 0x10C
je 0x3457
jmp 0x346b
movq -0x10(%rbp), %rdi
leaq 0x664a(%rip), %rsi      # 0x9a98
movb $0x0, %al
callq 0x1120
jmp 0x346d
movq -0x10(%rbp), %rdi
leaq 0x6649(%rip), %rsi      # 0x9aab
movb $0x0, %al
callq 0x1120
jmp 0x346d
jmp 0x346d
jmp 0x3998
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x348f
jmp 0x348f
movq -0x10(%rbp), %rdi
leaq 0x6541(%rip), %rsi      # 0x99db
movl $0x4, %edx
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6540(%rip), %rsi      # 0x99f1
movb $0x0, %al
callq 0x1120
movslq -0x14(%rbp), %rax
addq $0x4, %rax
movl %eax, -0x14(%rbp)
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x34e0
jmp 0x34e0
movq -0x10(%rbp), %rdi
leaq 0x6516(%rip), %rsi      # 0x9a01
xorl %eax, %eax
movb %al, -0x81(%rbp)
callq 0x1120
movb -0x81(%rbp), %al
movq -0x10(%rbp), %rdi
leaq 0x6508(%rip), %rsi      # 0x9a11
movl $0x4, %edx
callq 0x1120
movl -0x14(%rbp), %eax
addl $-0x4, %eax
movl %eax, -0x14(%rbp)
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movl 0x20(%rax), %eax
movl %eax, -0x80(%rbp)
subl $0x10d, %eax            # imm = 0x10D
je 0x353f
jmp 0x3533
movl -0x80(%rbp), %eax
subl $0x10e, %eax            # imm = 0x10E
je 0x3553
jmp 0x3567
movq -0x10(%rbp), %rdi
leaq 0x6574(%rip), %rsi      # 0x9abe
movb $0x0, %al
callq 0x1120
jmp 0x3569
movq -0x10(%rbp), %rdi
leaq 0x6573(%rip), %rsi      # 0x9ad1
movb $0x0, %al
callq 0x1120
jmp 0x3569
jmp 0x3569
jmp 0x3998
movl $0x0, -0x4c(%rbp)
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rdi
leaq 0x5e33(%rip), %rsi      # 0x93bb
callq 0x1110
cmpl $0x0, %eax
jne 0x3603
movq -0x10(%rbp), %rdi
leaq 0x6547(%rip), %rsi      # 0x9ae4
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x653f(%rip), %rsi      # 0x9aee
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6538(%rip), %rsi      # 0x9af9
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6539(%rip), %rsi      # 0x9b0c
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6530(%rip), %rsi      # 0x9b15
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6515(%rip), %rsi      # 0x9b0c
movb $0x0, %al
callq 0x1120
jmp 0x382f
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rdi
leaq 0x5dfd(%rip), %rsi      # 0x9413
callq 0x1110
cmpl $0x0, %eax
jne 0x3729
movq -0x10(%rbp), %rdi
leaq 0x64f1(%rip), %rsi      # 0x9b20
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x64ea(%rip), %rsi      # 0x9b2b
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x649b(%rip), %rsi      # 0x9aee
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x64d5(%rip), %rsi      # 0x9b3a
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6495(%rip), %rsi      # 0x9b0c
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x64c5(%rip), %rsi      # 0x9b4e
movb $0x0, %al
callq 0x1120
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
addl -0x4c(%rbp), %edx
movl $0x1, %ecx
callq 0x2cf0
movl -0x14(%rbp), %ecx
addl -0x4c(%rbp), %ecx
cmpl %ecx, %eax
je 0x36b8
jmp 0x36b8
movq -0x10(%rbp), %rdi
leaq 0x649a(%rip), %rsi      # 0x9b5d
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6497(%rip), %rsi      # 0x9b6c
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6425(%rip), %rsi      # 0x9b0c
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x63f5(%rip), %rsi      # 0x9aee
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x646c(%rip), %rsi      # 0x9b77
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x63ef(%rip), %rsi      # 0x9b0c
movb $0x0, %al
callq 0x1120
jmp 0x382d
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x58(%rbp)
movl $0x0, -0x50(%rbp)
cmpq $0x0, -0x58(%rbp)
je 0x37fa
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x18(%rax), %rax
movq 0x10(%rax), %rax
movslq -0x50(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x88(%rbp)
subl $0x4, %eax
je 0x3778
jmp 0x376b
movl -0x88(%rbp), %eax
subl $0x5, %eax
je 0x3781
jmp 0x378c
movl $0x4, -0x5c(%rbp)
jmp 0x378e
movl 0xa981(%rip), %eax      # 0xe108
movl %eax, -0x5c(%rbp)
jmp 0x378e
jmp 0x378e
movq -0x58(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
addl -0x4c(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
movl -0x14(%rbp), %ecx
addl -0x4c(%rbp), %ecx
cmpl %ecx, %eax
je 0x37af
jmp 0x37af
movq -0x10(%rbp), %rdi
xorl %edx, %edx
subl -0x5c(%rbp), %edx
leaq 0x5f1b(%rip), %rsi      # 0x96da
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6220(%rip), %rsi      # 0x99f1
movb $0x0, %al
callq 0x1120
movl -0x5c(%rbp), %eax
addl -0x4c(%rbp), %eax
movl %eax, -0x4c(%rbp)
movq -0x58(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x373c
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rdx
leaq 0x6377(%rip), %rsi      # 0x9b88
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
movl -0x4c(%rbp), %edx
leaq 0x5eb4(%rip), %rsi      # 0x96da
movb $0x0, %al
callq 0x1120
jmp 0x382f
jmp 0x3998
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x3851
jmp 0x3851
movq -0x10(%rbp), %rdi
leaq 0x612d(%rip), %rsi      # 0x9989
movl $0x4, %edx
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x6123(%rip), %rsi      # 0x9996
movb $0x0, %al
callq 0x1120
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x2cf0
cmpl -0x14(%rbp), %eax
je 0x3897
jmp 0x3897
movq -0x10(%rbp), %rdi
leaq 0x6107(%rip), %rsi      # 0x99a9
movb $0x0, %al
callq 0x1120
movq -0x10(%rbp), %rdi
leaq 0x62dc(%rip), %rsi      # 0x9b90
movb $0x0, %al
callq 0x1120
jmp 0x3998
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movl (%rax), %eax
movl %eax, -0x8c(%rbp)
subl $0x4, %eax
je 0x38e7
jmp 0x38d7
movl -0x8c(%rbp), %eax
subl $0x5, %eax
je 0x391f
jmp 0x3977
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x10(%rax), %ecx
leaq 0x62af(%rip), %rsi      # 0x9bac
leaq 0x629c(%rip), %rax      # 0x9ba0
cmpl $0x0, %ecx
cmovneq %rax, %rsi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movl 0xc(%rax), %edx
movb $0x0, %al
callq 0x1120
jmp 0x3979
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movl 0x10(%rax), %ecx
leaq 0x6294(%rip), %rsi      # 0x9bc9
leaq 0x6281(%rip), %rax      # 0x9bbd
cmpl $0x0, %ecx
cmovneq %rax, %rsi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movl 0xc(%rax), %edx
movb $0x0, %al
callq 0x1120
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
cmpl $0x0, 0x8(%rax)
je 0x3975
movq -0x10(%rbp), %rdi
leaq 0x6222(%rip), %rsi      # 0x9b90
movb $0x0, %al
callq 0x1120
jmp 0x3979
jmp 0x3979
jmp 0x3998
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x20(%rax), %edx
leaq 0x6230(%rip), %rsi      # 0x9bbd
movb $0x0, %al
callq 0x1120
jmp 0x3998
jmp 0x3998
jmp 0x399a
cmpl $0x0, -0x18(%rbp)
je 0x39b0
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x98(%rbp)
jmp 0x39bb
xorl %eax, %eax
movq %rax, -0x98(%rbp)
jmp 0x39bb
movq -0x98(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x2d11
movl -0x14(%rbp), %eax
addq $0xa0, %rsp
popq %rbp
retq
nopw (%rax,%rax)