// File: /workspace/github_cpp_makefile_star2_O3/rofl0r[P]ascc/cs_parser.cpp
// Function: process_function_declaration(ccInternalList&, ccCompiledScript*, int*, int, int&, int&, int, int, int, int, int, int, int*, SymbolDef*, int)
int process_function_declaration(ccInternalList &targ, ccCompiledScript*scrip,
                                 int *funcsymptr, int vtwas, int &in_func,
                                 int &nested_level, int next_is_readonly,
                                 int is_const,
                                 int next_is_import, int isMemberFunction,
                                 int returnsPointer, int func_is_static,
								 int *isMemberFunctionPtr, SymbolDef *oldDefinition,
                 int returnsDynArray) {
  int numparams = 1;
  int funcsym = *funcsymptr;
  int varsize = sym.entries[vtwas].ssize;
  // skip the opening (
  targ.getnext();

  char functionName[MAX_SYM_LEN];
  strcpy(functionName, sym.get_name(funcsym));

  if (check_not_eof(targ))
    return -1;
  if (strcmp(sym.get_name(targ.peeknext()), "this") == 0 || sym.get_type(targ.peeknext()) == SYM_STATIC)
  {
    if(sym.get_type(targ.peeknext()) == SYM_STATIC)
      func_is_static = 1;
    // extender function, eg.  function GoAway(this Character *someone)
    targ.getnext();
	  if (sym.get_type(targ.peeknext()) != SYM_VARTYPE)
	  {
	    if(func_is_static)
	      cc_error("'static' must be followed by a struct name");
	    else
	      cc_error("'this' must be followed by a struct name");
	    return -1;
	  }
	  if ((sym.entries[targ.peeknext()].flags & SFLG_STRUCTTYPE) == 0)
	  {
	    if(func_is_static)
	      cc_error("'static' cannot be used with primitive types");
	    else
	      cc_error("'this' cannot be used with primitive types");
	    return -1;
	  }
	  if (strchr(functionName, ':') != NULL)
	  {
	    cc_error("extender functions cannot be part of a struct");
	    return -1;
	  }

	  sprintf(functionName, "%s::%s", sym.get_name(targ.peeknext()), sym.get_name(funcsym));
	  if (isMemberFunctionPtr != NULL)
	  {
		  *isMemberFunctionPtr = targ.peeknext();
	  }

	  funcsym = sym.find(functionName);
	  if (funcsym < 0)
	  {
		  funcsym = sym.add(functionName);
	  }
    *funcsymptr = funcsym;

	  if (next_is_import == 0) {
      if (scrip->remove_any_import(functionName, oldDefinition))
        return -1;
    }

	  if (sym.entries[funcsym].stype != 0)
	  {
	    cc_error("function '%s' is already defined", functionName);
	    return -1;
	  }
	  sym.entries[funcsym].flags = SFLG_STRUCTMEMBER;
	  if(func_is_static) {
	    sym.entries[funcsym].flags |= SFLG_STATIC;
      }

	  targ.getnext();
	  if (!func_is_static && strcmp(sym.get_name(targ.getnext()), "*") != 0)
	  {
	    cc_error("instance extender function must be pointer");
	    return -1;
	  }

	  if ((sym.get_type(targ.peeknext()) != SYM_COMMA) &&
	      (sym.get_type(targ.peeknext()) != SYM_CLOSEPARENTHESIS))
	  {
	    if(strcmp(sym.get_name(targ.getnext()), "*") == 0)
	      cc_error("static extender function cannot be pointer");
	    else
	      cc_error("parameter name cannot be defined for extender type");
	    return -1;
	  }

	  if (sym.get_type(targ.peeknext()) == SYM_COMMA)
	  {
		  targ.getnext();
	  }
  }
  else if(sym.get_type(funcsym) == SYM_VARTYPE) {
      // Attempt to prefix a vartype with the struct name
      // e.g. MyStruct::Object
      if(isMemberFunction)
      {
          sprintf(functionName, "%s::%s", sym.get_name(isMemberFunction), sym.get_name(funcsym));
          funcsym = sym.find(functionName);
          if (funcsym < 0)
              funcsym = sym.add(functionName);
          *funcsymptr = funcsym;
      }
      if (sym.entries[funcsym].stype != 0) 
      {
          cc_error("function '%s' is already defined", functionName);
          return -1;
      }
  }

  sym.entries[funcsym].stype = SYM_FUNCTION;
  sym.entries[funcsym].ssize = varsize;  // save return type size
  sym.entries[funcsym].funcparamtypes[0] = vtwas;  // return type

  if (is_const)
  {
    sym.entries[funcsym].funcparamtypes[0] |= STYPE_CONST;
  }
  if (returnsPointer)
  {
    sym.entries[funcsym].funcparamtypes[0] |= STYPE_POINTER;
  }
  if (returnsDynArray)
  {
    sym.entries[funcsym].funcparamtypes[0] |= STYPE_DYNARRAY;
  }

  if ((!returnsPointer) && (!returnsDynArray) &&
      ((sym.entries[vtwas].flags & SFLG_STRUCTTYPE) != 0))
  {
    cc_error("Cannot return entire struct from function");
    return -1;
  }
  if ((in_func >= 0) || (nested_level > 0)) {
    cc_error("Nested functions not supported (you may have forgotten a closing brace)");
    return -1;
  }
  if (next_is_readonly) {
    cc_error("readonly cannot be applied to a function");
    return -1;
  }

  int funcNum = -1;

  if (next_is_import)
    in_func = scrip->add_new_import(functionName);
  else
    in_func = scrip->add_new_function(functionName, &funcNum);

  if (in_func < 0) {
    // don't overwrite the "used import" error message
    if (in_func != -2)
      cc_error("Internal compiler error: table overflow");
    return -1;
  }
  sym.entries[funcsym].soffs = in_func;  // save code offset of function
  scrip->cur_sp += 4;  // the return address will be pushed

  int prototype = 0;
  bool next_is_const = false;
  char functype[100]="\0";
  while (1) {
    int cursym = targ.getnext();
    int next_type = sym.get_type(cursym);
    if (next_type == SYM_CLOSEPARENTHESIS) break;
    else if (next_type == SYM_VARARGS) {
      // variable number of arguments
      numparams+=100;
      cursym = targ.getnext();
      if (sym.get_type(cursym) != SYM_CLOSEPARENTHESIS) {
        cc_error("expected ')' after variable-args");
        return -1;
      }
      break;
    }
    else if (next_type == SYM_CONST) {
      next_is_const = true;
    }
    else if (next_type == SYM_VARTYPE) {
      // function parameter
      if ((numparams % 100) >= MAX_FUNCTION_PARAMETERS) {
        cc_error("too many parameters defined for function");
        return -1;
      }
      if (cursym == sym.normalVoidSym) {
        cc_error("'void' invalid type for function parameter");
        return -1;
      }
      int isPointerParam = 0, isRawPointer = 0;
      // save the parameter type (numparams starts from 1)
      sym.entries[funcsym].funcparamtypes[numparams % 100] = cursym;
      sym.entries[funcsym].funcParamDefaultValues[numparams % 100] = 0;
      sym.entries[funcsym].funcParamHasDefaultValues[numparams % 100] = false;

      if (next_is_const)
        sym.entries[funcsym].funcparamtypes[numparams % 100] |= STYPE_CONST;

      functype[strlen(functype)+1] = 0;
      functype[strlen(functype)] = (char)cursym;  // save variable type
      if (check_not_eof(targ))
        return -1;
      if (strcmp(sym.get_name(targ.peeknext()), "*") == 0) {
        // pointer
        targ.getnext();
        if(strcmp("char", sym.get_name(cursym)) == 0) isRawPointer = 1;
        else if (strcmp("int", sym.get_name(cursym)) == 0) isRawPointer = 4;
        else if (strcmp("short", sym.get_name(cursym)) == 0) isRawPointer = 2;
        else if (strcmp("long", sym.get_name(cursym)) == 0 ) isRawPointer = 4;
        if(isRawPointer) {
          /* treat the pointer value as if it was an int */
          sym.entries[funcsym].funcparamtypes[numparams % 100] = sym.normalIntSym;
        } else {
          sym.entries[funcsym].funcparamtypes[numparams % 100] |= STYPE_POINTER;
          isPointerParam = 1;
        }
        if ((sym.entries[cursym].flags & SFLG_MANAGED) == 0 && !isRawPointer) {
          // can only point to managed structs
          cc_error("Cannot declare pointer to non-managed type");
          return -1;
        }
        if (sym.entries[cursym].flags & SFLG_AUTOPTR) {
          cc_error("Invalid use of pointer");
          return -1;
        }
      }

      if (sym.entries[cursym].flags & SFLG_AUTOPTR) {
        sym.entries[funcsym].funcparamtypes[numparams % 100] |= STYPE_POINTER;
        isPointerParam = 1;
      }

      bool createdLocalVar = false;

      if (sym.get_type(targ.peeknext()) != 0) {
        // next token is not a variable name, so it must be a prototype
        prototype = 1;

        if ((sym.get_type(targ.peeknext()) == SYM_GLOBALVAR) && (next_is_import)) {
          // if the paramter name is a global var, but this is just an import declaration
          // then ignore it
          targ.getnext();
        }

        if (check_for_default_value(targ, funcsym, numparams))
          return -1;

        numparams++;
      }
      else if ((next_is_import) || (prototype)) {
        // imported function, so ignore the parameter names
        targ.getnext();

        if (check_for_default_value(targ, funcsym, numparams))
          return -1;

        numparams++;
      }
      else {
        // it's a parameter
        int vartypesym = cursym;
        if ((sym.entries[cursym].flags & SFLG_STRUCTTYPE) && (!isPointerParam)) {
          cc_error("struct cannot be passed as parameter");
          return -1;
        }
        cursym = targ.getnext();
        sym.entries[cursym].stype = SYM_LOCALVAR;
        sym.entries[cursym].extends = 0;
        sym.entries[cursym].arrsize = isRawPointer ? 0 : 1;
        sym.entries[cursym].vartype = isRawPointer ? sym.normalIntSym : vartypesym;
        sym.entries[cursym].ssize = isRawPointer ? isRawPointer : 4; //oldsize;  fix param to 4 bytes for djgpp
        sym.entries[cursym].sscope = nested_level + 1;
        sym.entries[cursym].flags |= SFLG_PARAMETER;
        if (isPointerParam)
          sym.entries[cursym].flags |= SFLG_POINTER;
        else if (isRawPointer)
          sym.entries[cursym].flags |= SFLG_ARRAY;
        if (next_is_const)
          sym.entries[cursym].flags |= SFLG_CONST | SFLG_READONLY;
        // the parameters are pushed backwards, so the top of the
        // stack has the first parameter. The +1 is because the
        // call will push the return address onto the stack as well
        sym.entries[cursym].soffs = scrip->cur_sp - (numparams+1)*4;
        createdLocalVar = true;
        numparams++;
      }

      int dynArrayStatus = check_for_dynamic_array_declaration(targ, cursym, !!isPointerParam);
      if (dynArrayStatus < 0)
      {
        return -1;
      }
      else if (dynArrayStatus > 0)
      {
        sym.entries[funcsym].funcparamtypes[(numparams - 1) % 100] |= STYPE_DYNARRAY;
        if (createdLocalVar)
        {
          sym.entries[cursym].flags |= SFLG_DYNAMICARRAY | SFLG_ARRAY;
        }
      }

      next_type = sym.get_type(cursym=targ.getnext());
      if (next_type == SYM_CLOSEPARENTHESIS) break;
      else if (next_type == SYM_GLOBALVAR) {
        cc_error("'%s' is a global var; cannot use as name for local",sym.get_friendly_name(cursym).c_str());
        return -1;
      }
      else if (next_type != SYM_COMMA) {
        cc_error("PE02: Parse error at '%s'",sym.get_friendly_name(cursym).c_str());
        return -1;
      }

      next_is_const = false;
    }
    else {
      // something odd was inside the parentheses
      cc_error("PE03: Parse error at '%s'",sym.get_friendly_name(cursym).c_str());
      return -1;
    }
  }
  // save the number of parameters
  sym.entries[funcsym].sscope = (numparams-1);
  if (funcNum >= 0)
    scrip->funcnumparams[funcNum] = sym.entries[funcsym].sscope;

  if (func_is_static)
    sym.entries[funcsym].flags |= SFLG_STATIC;

  if (next_is_import) {
    sym.entries[funcsym].flags |= SFLG_IMPORTED;

    if (isMemberFunction) {
      // for imported member functions, append the number of parameters
      // to the name of the import
      char appendage[10];
      sprintf(appendage, "^%d", sym.entries[funcsym].sscope);

      strcat(scrip->imports[in_func], appendage);
    }

    int nextvar = targ.peeknext();
    // member function expects the ; to still be there whereas
    // normal function does not
    if (!isMemberFunction)
      nextvar = targ.getnext();

    if (sym.get_type(nextvar) != SYM_SEMICOLON) {
      cc_error("';' expected (cannot define body of imported function)");
      return -1;
    }
    in_func=-1;
  }
  else if (sym.get_type(targ.peeknext()) == SYM_OPENBRACE) {
  }
  else {
    cc_error("Expected '{'");
    return -1;
  }

  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2e8, %rsp            # imm = 0x2E8
movq %r9, 0x70(%rsp)
movq %r8, 0x30(%rsp)
movq %rdx, %r13
movq %rsi, 0x28(%rsp)
movq %rdi, %r15
movl (%rdx), %r14d
movslq %ecx, %rbp
leaq 0x1f237(%rip), %rbx     # 0x256e0
movq 0x28(%rbx), %rax
imulq $0xb0, %rbp, %r12
movq 0x38(%rax,%r12), %rax
movq %rax, 0x10(%rsp)
callq 0x10e44
movq %rbx, %rdi
movl %r14d, %esi
callq 0x124c6
leaq 0xf0(%rsp), %rdi
movq %rax, %rsi
callq 0x32d0
movq %r15, %rdi
callq 0x626b
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0x6940
movq %r13, 0x40(%rsp)
movq 0x30(%rsp), %rbx
movq %rbp, 0x20(%rsp)
movq %r12, (%rsp)
movl %r14d, %r12d
movl 0x348(%rsp), %r13d
movl 0x338(%rsp), %ebp
movq %r15, %rdi
callq 0x10e06
leaq 0x1f1b9(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x124c6
leaq 0x146f1(%rip), %rsi     # 0x1ac26
movq %rax, %rdi
callq 0x3450
testl %eax, %eax
je 0x6560
movq %r15, %rdi
callq 0x10e06
leaq 0x1f190(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
cmpl $0x2c, %eax
jne 0x65ec
movq %r15, %rdi
callq 0x10e06
leaq 0x1f171(%rip), %r14     # 0x256e0
movq %r14, %rdi
movl %eax, %esi
callq 0x1106e
cmpl $0x2c, %eax
movl $0x1, %eax
cmovel %eax, %r13d
movq %r15, %rdi
callq 0x10e44
movq %r15, %rdi
callq 0x10e06
movq %r14, %rdi
movl %eax, %esi
callq 0x1106e
cmpl $0x2e, %eax
jne 0x65d7
movq %r15, %rdi
callq 0x10e06
movq 0x28(%r14), %rcx
imulq $0xb0, %rax, %rax
testb $0x4, 0x29(%rcx,%rax)
jne 0x6688
testl %r13d, %r13d
je 0x66d3
leaq 0x146ad(%rip), %rdi     # 0x1ac7f
jmp 0x6934
testl %r13d, %r13d
je 0x66c7
leaq 0x14644(%rip), %rdi     # 0x1ac2b
jmp 0x6934
leaq 0x1f0ed(%rip), %rdi     # 0x256e0
movl %r12d, %r14d
movl %r12d, %esi
callq 0x1106e
cmpl $0x2e, %eax
jne 0x66ab
testl %ebp, %ebp
je 0x683a
leaq 0x1f0ca(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x124c6
movq %rax, %r14
movq %rbx, %rdi
movl %r12d, %esi
callq 0x124c6
leaq 0x1433b(%rip), %rsi     # 0x1a970
leaq 0xf0(%rsp), %r12
movq %r12, %rdi
movq %r14, %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x30d0
movq %rbx, %rdi
movq %r12, %rsi
callq 0x11e22
movl %eax, %r10d
testl %eax, %eax
jns 0x6676
leaq 0x1f07a(%rip), %rdi     # 0x256e0
leaq 0xf0(%rsp), %rsi
callq 0x125d0
movl %eax, %r10d
movq 0x40(%rsp), %rax
movl %r10d, (%rax)
movq 0x30(%rsp), %r14
jmp 0x6840
leaq 0xf0(%rsp), %rdi
movl $0x3a, %esi
callq 0x3180
testq %rax, %rax
je 0x66df
leaq 0x14631(%rip), %rdi     # 0x1acd7
jmp 0x6934
movslq %r14d, %r12
movl %r14d, %r10d
movq (%rsp), %r9
movq 0x20(%rsp), %r8
movq 0x10(%rsp), %rdi
movq %rbx, %r14
jmp 0x6886
leaq 0x14588(%rip), %rdi     # 0x1ac56
jmp 0x6934
leaq 0x145d2(%rip), %rdi     # 0x1acac
jmp 0x6934
movq 0x350(%rsp), %rbx
movq %r15, %rdi
callq 0x10e06
leaq 0x1efea(%rip), %rbp     # 0x256e0
movq %rbp, %rdi
movl %eax, %esi
callq 0x124c6
movq %rax, %r14
movq %rbp, %rdi
movl %r12d, %esi
callq 0x124c6
leaq 0x1425b(%rip), %rsi     # 0x1a970
leaq 0xf0(%rsp), %rdi
movq %r14, %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x30d0
testq %rbx, %rbx
je 0x6739
movq %r15, %rdi
callq 0x10e06
movl %eax, (%rbx)
leaq 0x1efa0(%rip), %r14     # 0x256e0
leaq 0xf0(%rsp), %rsi
movq %r14, %rdi
callq 0x11e22
movl %eax, %r8d
testl %eax, %eax
movq 0x40(%rsp), %rbx
jns 0x6773
leaq 0x1ef7d(%rip), %rdi     # 0x256e0
leaq 0xf0(%rsp), %rsi
callq 0x125d0
movl %eax, %r8d
movl %r8d, (%rbx)
cmpl $0x0, 0x330(%rsp)
je 0x6982
movslq %r8d, %r12
movq 0x28(%r14), %rax
imulq $0xb0, %r12, %rcx
cmpw $0x0, 0x20(%rax,%rcx)
jne 0x686b
movl %r8d, %ebx
addq %rcx, %rax
movq $0x80, 0x28(%rax)
testl %r13d, %r13d
je 0x6fc9
movq $0x2080, 0x28(%rax)     # imm = 0x2080
movq %r15, %rdi
callq 0x10e44
movq 0x30(%rsp), %r14
movq %r15, %rdi
callq 0x10e06
leaq 0x1ef07(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
cmpl $0x2a, %eax
je 0x6804
movq %r15, %rdi
callq 0x10e06
leaq 0x1eeec(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
cmpl $0x6, %eax
jne 0x7131
movq %r15, %rdi
callq 0x10e06
leaq 0x1eecd(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
cmpl $0x2a, %eax
jne 0x6827
movq %r15, %rdi
callq 0x10e44
movl %ebx, %r10d
movq (%rsp), %r9
movq 0x20(%rsp), %r8
movq 0x10(%rsp), %rdi
jmp 0x6886
movl %r12d, %r10d
movq %rbx, %r14
movslq %r10d, %r12
leaq 0x1ee96(%rip), %rax     # 0x256e0
movq 0x28(%rax), %rax
imulq $0xb0, %r12, %rcx
cmpw $0x0, 0x20(%rax,%rcx)
movq (%rsp), %r9
movq 0x20(%rsp), %r8
movq 0x10(%rsp), %rdi
je 0x6886
leaq 0x14493(%rip), %rdi     # 0x1ad05
leaq 0xf0(%rsp), %rsi
xorl %eax, %eax
callq 0x102f4
jmp 0x693b
movl 0x360(%rsp), %ecx
movl 0x340(%rsp), %edx
movl 0x328(%rsp), %esi
leaq 0x1ee3e(%rip), %rax     # 0x256e0
movq 0x28(%rax), %rax
imulq $0xb0, %r12, %r12
movw $0x4, 0x20(%rax,%r12)
movslq %edi, %rdi
movq %rdi, 0x38(%rax,%r12)
movq %r8, %rdi
orq $0x20000000, %rdi       # imm = 0x20000000
testl %esi, %esi
cmoveq %r8, %rdi
movq %rdi, %rsi
orq $0x40000000, %rsi       # imm = 0x40000000
testl %edx, %edx
cmoveq %rdi, %rsi
movq 0x58(%rax,%r12), %rdi
movq %rsi, %r8
orq $0x10000000, %r8        # imm = 0x10000000
testl %ecx, %ecx
cmoveq %rsi, %r8
movq %r8, (%rdi)
orl %edx, %ecx
jne 0x6901
testb $0x4, 0x29(%rax,%r9)
jne 0x692d
cmpl $0x0, (%r14)
movq 0x70(%rsp), %rax
jns 0x6924
cmpl $0x0, (%rax)
jg 0x6924
cmpl $0x0, 0x320(%rsp)
je 0x6954
leaq 0x144ff(%rip), %rdi     # 0x1ae21
jmp 0x6934
leaq 0x144ae(%rip), %rdi     # 0x1add9
jmp 0x6934
leaq 0x1447b(%rip), %rdi     # 0x1adaf
xorl %eax, %eax
callq 0x102f4
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movl %ecx, %eax
addq $0x2e8, %rsp            # imm = 0x2E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %r10d, 0x20(%rsp)
movl $0xffffffff, 0x3c(%rsp) # imm = 0xFFFFFFFF
leaq 0xf0(%rsp), %rsi
cmpl $0x0, 0x330(%rsp)
je 0x69ab
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
callq 0x1385a
jmp 0x69bd
movq 0x358(%rsp), %rdx
leaq 0xf0(%rsp), %rsi
movq 0x28(%rsp), %rdi
movl %r8d, %ebx
callq 0x138da
movl %ebx, %r8d
testl %eax, %eax
jne 0x693b
jmp 0x6784
leaq 0x3c(%rsp), %rdx
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
callq 0x137d2
movl %eax, (%r14)
testl %eax, %eax
js 0x6faf
movl %r13d, 0x40(%rsp)
leaq 0x1ed0c(%rip), %rcx     # 0x256e0
movq 0x28(%rcx), %rcx
movl %eax, 0x34(%rcx,%r12)
addq $0x4, 0x8d40(%rbx)
xorps %xmm0, %xmm0
movaps %xmm0, 0xd0(%rsp)
movaps %xmm0, 0xc0(%rsp)
movaps %xmm0, 0xb0(%rsp)
movaps %xmm0, 0xa0(%rsp)
movaps %xmm0, 0x90(%rsp)
movaps %xmm0, 0x80(%rsp)
movl $0x0, 0xe0(%rsp)
movl $0x0, 0x38(%rsp)
movl $0x1, %ebx
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
addq $0x3f, %rax
movq %rax, 0x78(%rsp)
movq %rbx, 0x10(%rsp)
xorl %ecx, %ecx
leaq 0x1ec8f(%rip), %r14     # 0x256e0
movl %ecx, %r13d
movq %r15, %rdi
callq 0x10e44
movq %rax, %rbx
movq %r14, %rdi
movl %ebx, %esi
callq 0x1106e
movb $0x1, %cl
cmpl $0x31, %eax
je 0x6a51
movq %rbx, (%rsp)
cmpl $0x6, %eax
je 0x7007
cmpl $0x2e, %eax
movq 0x10(%rsp), %rbx
jne 0x6f75
movslq %ebx, %rcx
imulq $0x51eb851f, %rcx, %rax # imm = 0x51EB851F
movq %rax, %rdx
shrq $0x3f, %rdx
sarq $0x25, %rax
addl %edx, %eax
imull $0x64, %eax, %eax
subl %eax, %ecx
cmpl $0xf, %ecx
jge 0x71de
movq (%rsp), %rax
cmpl %eax, 0x18(%r14)
je 0x71ea
movslq %eax, %rsi
movq 0x28(%r14), %rdx
movslq %ecx, %r9
movq 0x58(%rdx,%r12), %rax
movq %rsi, 0x18(%rsp)
movq %rsi, (%rax,%r9,8)
movq 0x70(%rdx,%r12), %rsi
movl $0x0, (%rsi,%r9,4)
movl %ecx, %esi
sarb $0x7, %sil
shrb $0x2, %sil
addb %cl, %sil
sarb $0x6, %sil
movsbq %sil, %rsi
shlq $0x3, %rsi
addq 0x88(%rdx,%r12), %rsi
movq %r9, %rdx
andq 0x78(%rsp), %rdx
xorl %edi, %edi
movabsq $-0x8000000000000000, %r8 # imm = 0x8000000000000000
cmpq %r8, %rdx
setbe %dil
movq $-0x2, %rdx
rolq %cl, %rdx
andq %rdx, -0x8(%rsi,%rdi,8)
testb $0x1, %r13b
je 0x6b3a
orb $0x20, 0x3(%rax,%r9,8)
movq %r9, 0x48(%rsp)
leaq 0x80(%rsp), %rbx
movq %rbx, %rdi
callq 0x31a0
movb $0x0, 0x1(%rax,%rbx)
movq %rbx, %rdi
callq 0x31a0
movq (%rsp), %rcx
movb %cl, 0x80(%rsp,%rax)
movq %r15, %rdi
callq 0x626b
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0x6940
movq %r15, %rdi
callq 0x10e06
movq %r14, %rdi
movl %eax, %esi
callq 0x124c6
cmpb $0x2a, (%rax)
jne 0x6b9d
cmpb $0x0, 0x1(%rax)
je 0x6d2f
movq 0x28(%r14), %rax
xorl %edx, %edx
movl $0x0, 0xc(%rsp)
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %rsi
imulq $0xb0, %rsi, %r14
testb $0x2, 0x2a(%rax,%r14)
je 0x6bdb
movq 0x58(%rax,%r12), %rax
movq 0x48(%rsp), %rcx
orq $0x40000000, (%rax,%rcx,8) # imm = 0x40000000
movl $0x1, %edx
movl %edx, 0x18(%rsp)
movq %r15, %rdi
callq 0x10e06
leaq 0x1eaf2(%rip), %rbp     # 0x256e0
movq %rbp, %rdi
movl %eax, %esi
callq 0x1106e
testl %eax, %eax
je 0x6c58
movq %r15, %rdi
callq 0x10e06
movq %rbp, %rdi
movl %eax, %esi
callq 0x1106e
cmpl $0x0, 0x330(%rsp)
movl 0x338(%rsp), %r13d
je 0x6c2d
cmpl $0x1, %eax
jne 0x6c2d
movq %r15, %rdi
callq 0x10e44
movq %r15, %rdi
movl 0x20(%rsp), %esi
movl %ebx, %edx
callq 0x62a8
testl %eax, %eax
jne 0x693b
incl %ebx
movl $0x1, 0x38(%rsp)
xorl %ebp, %ebp
movq (%rsp), %rax
movl %eax, %r11d
jmp 0x6c9a
movl 0x330(%rsp), %eax
orl 0x38(%rsp), %eax
je 0x6e0f
movq %r15, %rdi
callq 0x10e44
movq %r15, %rdi
movl 0x20(%rsp), %esi
movl %ebx, %edx
callq 0x62a8
testl %eax, %eax
jne 0x693b
incl %ebx
xorl %ebp, %ebp
movq (%rsp), %rax
movl %eax, %r11d
movl 0x338(%rsp), %r13d
movl 0x18(%rsp), %edx
movq %r15, %rdi
movq %r11, %r14
movl %r11d, %esi
callq 0x63d5
testl %eax, %eax
js 0x693b
je 0x6d07
leaq 0x1ea23(%rip), %rax     # 0x256e0
movq 0x28(%rax), %rax
leal -0x1(%rbx), %ecx
movslq %ecx, %rcx
imulq $0x51eb851f, %rcx, %rdx # imm = 0x51EB851F
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x25, %rdx
addl %esi, %edx
imull $0x64, %edx, %edx
subl %edx, %ecx
movslq %ecx, %rcx
movq 0x58(%rax,%r12), %rdx
orq $0x10000000, (%rdx,%rcx,8) # imm = 0x10000000
testb %bpl, %bpl
je 0x6d07
movslq %r14d, %rcx
imulq $0xb0, %rcx, %rcx
orl $0x40002, 0x28(%rax,%rcx) # imm = 0x40002
movq %r15, %rdi
callq 0x10e44
movq %rax, %r14
leaq 0x1e9c7(%rip), %rdi     # 0x256e0
movl %r14d, %esi
callq 0x1106e
cmpl $0x2a, %eax
je 0x6a43
jmp 0x71a7
movq %r15, %rdi
callq 0x10e44
movq %r14, %rdi
movq (%rsp), %rbp
movl %ebp, %esi
callq 0x124c6
leaq 0x16674(%rip), %rdi     # 0x1d3c0
movq %rax, %rsi
callq 0x3450
testl %eax, %eax
movq 0x10(%rsp), %rbx
je 0x6f25
movq %r14, %rdi
movl %ebp, %esi
callq 0x124c6
leaq 0x14798(%rip), %rdi     # 0x1b50a
movq %rax, %rsi
callq 0x3450
movl $0x4, 0xc(%rsp)
testl %eax, %eax
je 0x6f37
movq %r14, %rdi
movl %ebp, %esi
callq 0x124c6
leaq 0x1414c(%rip), %rdi     # 0x1aee7
movq %rax, %rsi
callq 0x3450
testl %eax, %eax
je 0x6f2f
movq %r14, %rdi
movl %ebp, %esi
callq 0x124c6
leaq 0x14442(%rip), %rdi     # 0x1b1fe
movq %rax, %rsi
callq 0x3450
testl %eax, %eax
je 0x6f37
movq 0x28(%r14), %rax
movq 0x58(%rax,%r12), %rcx
movq 0x48(%rsp), %rdx
orq $0x40000000, (%rcx,%rdx,8) # imm = 0x40000000
movq 0x18(%rsp), %rsi
imulq $0xb0, %rsi, %rcx
movq 0x28(%rax,%rcx), %rcx
btl $0xc, %ecx
jae 0x7227
movl $0x0, 0xc(%rsp)
movl $0x1, %edx
jmp 0x6f5f
cmpl $0x0, 0x18(%rsp)
jne 0x6e31
leaq 0x1e8c3(%rip), %rax     # 0x256e0
movq 0x28(%rax), %rax
movq 0x28(%rax,%r14), %rax
andl $0x400, %eax            # imm = 0x400
jne 0x721b
movq %r15, %rdi
callq 0x10e44
movq %rax, %r11
movslq %r11d, %rcx
leaq 0x1e89a(%rip), %rsi     # 0x256e0
movq 0x28(%rsi), %rax
imulq $0xb0, %rcx, %rcx
movw $0x2, 0x20(%rax,%rcx)
movw $0x0, 0x50(%rax,%rcx)
xorl %edx, %edx
movl 0xc(%rsp), %edi
testl %edi, %edi
sete %dl
movq %rdx, 0x48(%rax,%rcx)
movzwl (%rsi), %edx
cmovew (%rsp), %dx
movw %dx, 0x30(%rax,%rcx)
movl %edi, %edx
movl $0x4, %esi
cmovel %esi, %edx
movq %rdx, 0x38(%rax,%rcx)
movq 0x70(%rsp), %rdx
movl (%rdx), %edx
incl %edx
movw %dx, 0x40(%rax,%rcx)
movq 0x28(%rax,%rcx), %rsi
movq %rsi, %r10
orq $0x1, %r10
movl 0x18(%rsp), %edx
orl %edx, %edi
setne %dil
movl %edi, %r8d
orb %r13b, %r8b
testb $0x1, %r8b
je 0x6ee9
testl %edx, %edx
movl $0x3, %r8d
movl $0x101, %r9d            # imm = 0x101
cmovneq %r9, %r8
orq %r8, %rsi
testb %dil, %dil
cmovneq %rsi, %r10
movq %r10, %rsi
orq $0x10040, %rsi          # imm = 0x10040
testb $0x1, %r13b
cmovneq %rsi, %r10
movq 0x28(%rsp), %rsi
movl 0x338(%rsp), %r13d
addq %rcx, %rax
movq %r10, 0x28(%rax)
movl 0x8d40(%rsi), %ecx
leal 0x4(,%rbx,4), %edi
movl %ebx, %esi
incl %esi
subl %edi, %ecx
movl %ecx, 0x34(%rax)
movb $0x1, %bpl
movl $0x0, 0x38(%rsp)
movl %esi, %ebx
jmp 0x6c9e
movl $0x1, 0xc(%rsp)
jmp 0x6f37
movl $0x2, 0xc(%rsp)
movslq (%r14), %rcx
movq 0x28(%r14), %rax
movq 0x58(%rax,%r12), %rdx
movq 0x48(%rsp), %rsi
movq %rcx, (%rdx,%rsi,8)
movq 0x18(%rsp), %rsi
imulq $0xb0, %rsi, %rcx
movq 0x28(%rax,%rcx), %rcx
xorl %edx, %edx
btl $0x11, %ecx
jae 0x6bb5
leaq 0x13fa8(%rip), %rdi     # 0x1af18
jmp 0x6934
cmpl $0x1b, %eax
movq 0x30(%rsp), %r14
jne 0x70ab
movq %r15, %rdi
callq 0x10e44
leaq 0x1e74e(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
cmpl $0x6, %eax
jne 0x7125
addl $0x64, %ebx
movl 0x338(%rsp), %r13d
jmp 0x7019
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpl $-0x2, %eax
je 0x6940
leaq 0x13e86(%rip), %rdi     # 0x1ae4a
jmp 0x6934
movq %r15, %rdi
callq 0x10e44
movq %r15, %rdi
callq 0x10e44
leaq 0x1e700(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x124c6
cmpb $0x2a, (%rax)
movq 0x30(%rsp), %r14
jne 0x6ffb
cmpb $0x0, 0x1(%rax)
je 0x67ca
leaq 0x13d24(%rip), %rdi     # 0x1ad26
jmp 0x6934
movq 0x30(%rsp), %r14
movl 0x338(%rsp), %r13d
movq 0x10(%rsp), %rbx
decl %ebx
leaq 0x1e6be(%rip), %rax     # 0x256e0
movq 0x28(%rax), %rax
movw %bx, 0x40(%rax,%r12)
movslq 0x3c(%rsp), %rcx
testq %rcx, %rcx
js 0x7043
movq 0x28(%rsp), %rdx
movw %bx, 0x7d98(%rdx,%rcx,2)
addq %r12, %rax
cmpl $0x0, 0x40(%rsp)
je 0x7051
orb $0x20, 0x29(%rax)
cmpl $0x0, 0x330(%rsp)
je 0x70f8
orb $0x4, 0x28(%rax)
testl %r13d, %r13d
je 0x715e
movswl 0x40(%rax), %edx
leaq 0x13f44(%rip), %rsi     # 0x1afbb
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x30d0
movq 0x28(%rsp), %rax
movq 0x50(%rax), %rax
movslq (%r14), %rcx
movq (%rax,%rcx,8), %rdi
movq %rbx, %rsi
callq 0x3570
movq %r15, %rdi
callq 0x10e06
jmp 0x716e
leaq 0x1e62e(%rip), %rsi     # 0x256e0
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq (%rsp), %rdx
callq 0x11e2c
movq (%rbx), %rsi
leaq 0x13ed4(%rip), %rdi     # 0x1afa1
xorl %eax, %eax
callq 0x102f4
leaq 0x60(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x693b
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x3320
jmp 0x693b
movq %r15, %rdi
callq 0x10e06
leaq 0x1e5d9(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
xorl %ecx, %ecx
cmpl $0x17, %eax
je 0x6940
leaq 0x13ed6(%rip), %rdi     # 0x1aff6
jmp 0x6934
leaq 0x13d46(%rip), %rdi     # 0x1ae72
jmp 0x6934
movq %r15, %rdi
callq 0x10e44
leaq 0x1e5a0(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x124c6
cmpb $0x2a, (%rax)
jne 0x7152
cmpb $0x0, 0x1(%rax)
je 0x719b
leaq 0x13c23(%rip), %rdi     # 0x1ad7c
jmp 0x6934
movq %r15, %rdi
callq 0x10e06
movq %r15, %rdi
callq 0x10e44
leaq 0x1e56b(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
cmpl $0x28, %eax
jne 0x718f
movl $0xffffffff, (%r14)     # imm = 0xFFFFFFFF
xorl %ecx, %ecx
jmp 0x6940
leaq 0x13e29(%rip), %rdi     # 0x1afbf
jmp 0x6934
leaq 0x13baf(%rip), %rdi     # 0x1ad51
jmp 0x6934
cmpl $0x6, %eax
je 0x71f6
leaq 0x1e52d(%rip), %rsi     # 0x256e0
leaq 0x50(%rsp), %r15
movq %r15, %rdi
movl %r14d, %edx
cmpl $0x1, %eax
jne 0x7200
callq 0x11e2c
movq (%r15), %rsi
leaq 0x13d82(%rip), %rdi     # 0x1af54
xorl %eax, %eax
callq 0x102f4
jmp 0x70d4
leaq 0x13cae(%rip), %rdi     # 0x1ae93
jmp 0x6934
leaq 0x13ccb(%rip), %rdi     # 0x1aebc
jmp 0x6934
movq 0x30(%rsp), %r14
jmp 0x7019
callq 0x11e2c
movq (%r15), %rsi
leaq 0x13d78(%rip), %rdi     # 0x1af87
xorl %eax, %eax
callq 0x102f4
jmp 0x70d4
leaq 0x13d0d(%rip), %rdi     # 0x1af2f
jmp 0x6934
leaq 0x13cbf(%rip), %rdi     # 0x1aeed
jmp 0x6934
jmp 0x7237
jmp 0x7237
movq %rax, %rbx
leaq 0x60(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x7255
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x3320
movq %rbx, %rdi
callq 0x3560