// File: /workspace/github_cpp_makefile_star2_O2/rofl0r[P]ascc/cs_parser.cpp
// Function: do_variable_ax(int, long*, ccCompiledScript*, int, int, bool)
int do_variable_ax(int slilen,long*syml,ccCompiledScript*scrip,int writing, int mustBeWritable, bool negateLiteral = false) {
  // read the various types of values into AX
  int ee;

  if (!writing)
    set_ax_scope(scrip, syml[0]);

  // separate out the variable path, into a variablePath
  // for the bit between each dot
  VariableSymlist variablePath[MAX_VARIABLE_PATH];

  int variablePathSize = extractPathIntoParts(variablePath, slilen, syml);
  if (variablePathSize == -1)
    return -1;

  int currentByteOffset = 0;
  // remember the type of the first variable in the list (since
  // that determines whether this is global/local)
  int firstVariableType, firstVariableSym = -1;
  bool isArrayOffset = false;
  bool isPointer = false;
  bool isDynamicArray = false;

  for (ee = 0; ee < variablePathSize; ee++) {
    VariableSymlist *thisClause = &variablePath[ee];

    int variableSym = thisClause->syml[0];
    int variableSymType = sym.get_type(variableSym);
    if (firstVariableSym < 0) {
      firstVariableSym = variableSym;
      firstVariableType = variableSymType;
    }

    // each clause in the chain can be marked as Accessed
    sym.entries[variableSym].flags |= SFLG_ACCESSED;

    bool getAddressOnlyIntoAX = false;
    bool doMemoryAccessNow = false;
    bool isLastClause = (ee == variablePathSize - 1);
    bool cannotAssign = false;
    bool isProperty = false;
    bool accessActualPointer = false;

    // the memory access only wants to write if this is the
    // end of the path, not an intermediate pathing property
    bool writingThisTime = isLastClause && writing;

    // offset to add to CX after array index is calculated for struct member in dynarray
    int array_struct_offset_add = 0;

    if (sym.entries[variableSym].flags & SFLG_PROPERTY) { }
    else if (sym.entries[variableSym].flags & SFLG_IMPORTED) { }
    else if (isDynamicArray && variableSymType == SYM_STRUCTMEMBER) {
      array_struct_offset_add = sym.entries[variableSym].soffs;
    }
    else if ((variableSymType == SYM_GLOBALVAR) || (variableSymType == SYM_LOCALVAR) ||
        (variableSymType == SYM_STRUCTMEMBER) || (variableSymType == SYM_STRING)) {
      // since the member has a fixed offset into the structure, don't
      // write out any code to calculate the offset - instead, modify
      // the hard offset value which will be written to MAR
      currentByteOffset += sym.entries[variableSym].soffs;
    }

    if (variableSymType == SYM_FUNCTION) {
      // member function. all that's wanted is the owning object's
      // address
      getAddressOnlyIntoAX = true;
      doMemoryAccessNow = true;

      if (!isLastClause) {
        cc_error("Function().Member not supported");
        return -1;
      }
    }
    else if (sym.entries[variableSym].flags & SFLG_PROPERTY) {
      // since a property is effectively a function call, load
      // the object's address
      getAddressOnlyIntoAX = true;
      doMemoryAccessNow = true;
      isProperty = true;

      if ((sym.entries[variableSym].flags & SFLG_ARRAY) &&
          ((thisClause->len <= 1) ||
           (sym.get_type(thisClause->syml[1]) != SYM_OPENBRACKET))) {
        // normally, the whole array can be used as a pointer.
        // this is not the case with an property array, so catch
        // it here and give an error
        cc_error("Expected array index after '%s'", sym.get_friendly_name(variableSym).c_str());
        return -1;
      }

      if (parseArrayIndexOffsets(scrip, thisClause, writing != 0, &isArrayOffset))
        return -1;

      if (mustBeWritable) {
        // cannot use ++ or -- with property, because the memory
        // access shortcut won't work
        // Therefore, tell the caller to do it properly
        // and call us again to write the value
        readonly_cannot_cause_error = 1;
      }
      else if (writing) {

        if ((writingThisTime) && (sym.entries[variableSym].flags & SFLG_READONLY)) {
          cc_error("property '%s' is read-only", sym.get_friendly_name(variableSym).c_str());
          return -1;
        }

        // Property Set -- move the new value into BX, so
        // that the object address can be retrieved into AX
        scrip->write_cmd2(SCMD_REGTOREG, SREG_AX, SREG_BX);
      }

    }
    else if (sym.entries[variableSym].flags & SFLG_POINTER) {
      bool isArrayOfPointers = false;

      if (sym.entries[variableSym].flags & SFLG_ARRAY) {
        // array of pointers

        if ((thisClause->len <= 1) ||
           (sym.get_type(thisClause->syml[1]) != SYM_OPENBRACKET)) {
          // normally, the whole array can be used as a pointer.
          // this is not the case with an pointer array, so catch
          // it here and give an error
          if (sym.entries[variableSym].flags & SFLG_DYNAMICARRAY)
          {
            isDynamicArray = true;
          }
          else
          {
            cc_error("Expected array index after '%s'", sym.get_friendly_name(variableSym).c_str());
            return -1;
          }
        }
        else
        {
          // put array index into DX
          if (parseArrayIndexOffsets(scrip, thisClause, writing != 0, &isArrayOffset))
            return -1;

          isArrayOfPointers = true;
        }
      }

      // if they are just saying "ptr" (or doing a "ptr.Func" call)
      // then move the address being pointed to into AX
      // (member function call passes in "ptr.")
      if (isLastClause)
        getAddressOnlyIntoAX = true;

      // Push the pointer address onto the stack, where it can be
      // retrieved by do_variable_memory_access later on
      if (sym.entries[variableSym].flags & SFLG_THISPTR) {
        if (isPointer) {
          // already a pointer on the stack
          cc_error("Nested this pointers??");
          return -1;
        }

        // for the "this" pointer, just use the Object Pointer
        scrip->push_reg(SREG_OP);
      }
      else {
        // currentByteOffset has been set at the start of this loop
        // so it is safe to use

        if (isPointer) {
          // already a pointer on the stack
          scrip->pop_reg(SREG_MAR);
          scrip->write_cmd(SCMD_CHECKNULL);
          if (currentByteOffset > 0)
            scrip->write_cmd2(SCMD_ADD, SREG_MAR, currentByteOffset);
        }
        else if (firstVariableType == SYM_LOCALVAR) {
          load_stack_variable(scrip, scrip->cur_sp - currentByteOffset);
        }
        else if (firstVariableType == SYM_GLOBALVAR) {

          if (sym.entries[firstVariableSym].flags & SFLG_IMPORTED) {
            scrip->write_cmd2(SCMD_LITTOREG, SREG_MAR, sym.entries[firstVariableSym].soffs);
            scrip->fixup_previous(FIXUP_IMPORT);
            if (currentByteOffset)
              scrip->write_cmd2(SCMD_ADD, SREG_MAR, currentByteOffset);
          }
          else {
            scrip->write_cmd2(SCMD_LITTOREG, SREG_MAR, currentByteOffset);
            scrip->fixup_previous(FIXUP_GLOBALDATA);
          }
        }
        else {
          cc_error("Invalid type for pointer");
          return -1;
        }

        // if an array, the array indexer was put into DX
        if (isArrayOfPointers)
        {
          scrip->write_cmd2(SCMD_MUL, SREG_DX, 4);

          if (sym.entries[variableSym].flags & SFLG_DYNAMICARRAY)
          {
            // pointer to an array -- dereference the pointer
            scrip->write_cmd1(SCMD_MEMREADPTR, SREG_MAR);
            scrip->write_cmd(SCMD_CHECKNULL);
            scrip->write_cmd1(SCMD_DYNAMICBOUNDS, SREG_DX);
          }

          scrip->write_cmd2(SCMD_ADDREG, SREG_MAR, SREG_DX);
        }

        // push the pointer's address
        scrip->push_reg(SREG_MAR);
        getAddressOnlyIntoAX = true;
        accessActualPointer = true;
        doMemoryAccessNow = true;
      }
      currentByteOffset = 0;

      // Pointer
      isPointer = true;
    }
    else {

      if (sym.entries[variableSym].flags & SFLG_DYNAMICARRAY)
      {
        isDynamicArray = true;
      }

      if (parseArrayIndexOffsets(scrip, thisClause, writing != 0, &isArrayOffset))
        return -1;

    }

    // if one of the struct members in the path is read-only, don't allow it
    if (((writing) || (mustBeWritable)) && (readonly_cannot_cause_error == 0)) {
      // allow writing to read-only pointers if it's actually
      // a property being accessed
      if ((sym.entries[variableSym].flags & SFLG_POINTER) && (!isLastClause)) { }
      else if (sym.entries[variableSym].flags & SFLG_READONLY) {
        cc_error("variable '%s' is read-only", sym.get_friendly_name(variableSym).c_str());
        return -1;
      }
      else if (sym.entries[variableSym].flags & SFLG_WRITEPROTECTED) {
        // write-protected variables can only be written by
        // the this ptr
        if ((ee > 0) && (sym.entries[variablePath[ee - 1].syml[0]].flags & SFLG_THISPTR)) { }
        else {
          cc_error("variable '%s' is write-protected", sym.get_friendly_name(variableSym).c_str());
          return -1;
        }

      }
    }


    if (sym.entries[variableSym].flags & SFLG_ARRAY) {
      // array without index specified -- get address
      if ((thisClause->len == 1) ||
          (sym.get_type(thisClause->syml[1]) != SYM_OPENBRACKET)) {

        if ((sym.entries[variableSym].flags & SFLG_DYNAMICARRAY) == 0
           && sym.entries[variableSym].arrsize != 0)
        {
          getAddressOnlyIntoAX = true;
          cannotAssign = true;
        }
      }

    }

    if (sym.entries[variableSym].flags & SFLG_POINTER) { }
    else if (sym.entries[sym.entries[variableSym].vartype].flags & SFLG_STRUCTTYPE) {
      // struct variable without member access
      if (isLastClause)
      {
        if ((sym.entries[variableSym].flags & SFLG_DYNAMICARRAY) == 0)
        {
          getAddressOnlyIntoAX = true;
          cannotAssign = true;
        }
      }
    }

    if ((writing) && (cannotAssign)) {
      // an entire array or struct cannot be assigned to
      cc_error("cannot assign to '%s'", sym.get_friendly_name(variableSym).c_str());
      return -1;
    }

    if ((doMemoryAccessNow) || (isLastClause)) {

      int cachedAxValType = scrip->ax_val_type;

      // if a pointer in use, then its address was pushed on the
      // stack, so restore it here
      if (isPointer)
        scrip->pop_reg(SREG_MAR);

      // in a writing operation, but not doing it just yet -- push
      // AX to save the value to write
      if ((writing) && (!writingThisTime))
        scrip->push_reg(SREG_AX);

      if (do_variable_memory_access(scrip, variableSym, variableSymType,
                                    isProperty, writingThisTime, mustBeWritable,
                                    getAddressOnlyIntoAX, isArrayOffset,
                                    currentByteOffset, isPointer,
                                    accessActualPointer,
                                    firstVariableSym, firstVariableType,
                                    isDynamicArray, negateLiteral, array_struct_offset_add))
        return -1;

      // reset stuff
      currentByteOffset = 0;
      array_struct_offset_add = 0;
      isArrayOffset = false;
      isPointer = false;
      isDynamicArray = false;
      //firstVariableSym = -1;
      firstVariableType = SYM_GLOBALVAR;

      if (!isLastClause) {
        if ((isProperty) || (getAddressOnlyIntoAX)) {
          // pathing, eg. lstItems.OwningGUI.ID
          // we just read a pointer address, so re-push it for use
          // next time round
          if (writing) {
            scrip->ax_val_type = cachedAxValType;
            // the value to write was pushed onto the stack,
            // pop it back into BX
            scrip->pop_reg(SREG_BX);
            // meanwhile push the pointer
            // that was just read into AX onto the stack in its place
            scrip->push_reg(SREG_AX);
            // and then copy the value back into AX
            scrip->write_cmd2(SCMD_REGTOREG, SREG_BX, SREG_AX);
          }
          else
            scrip->push_reg(SREG_AX);

          isPointer = true;
        }
        else {
          cc_error("Invalid pathing: unexpected '%s'", sym.get_friendly_name(variablePath[ee + 1].syml[0]).c_str());
          return -1;
        }

      }

      // proceed round loop to next clause
    }


  }

  // free the VariablePaths
  for (ee = 0; ee < variablePathSize; ee++)
    variablePath[ee].destroy();

  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movl %r9d, 0x88(%rsp)
movl %r8d, 0x44(%rsp)
movq %rdx, %r15
movq %rsi, %rbx
movl %edi, %ebp
movl %ecx, 0x10(%rsp)
testl %ecx, %ecx
jne 0x95fe
movl (%rbx), %esi
movq %r15, %rdi
callq 0x779a
leaq 0xa0(%rsp), %rdi
movl %ebp, %esi
movq %rbx, %rdx
callq 0x78b4
cmpl $-0x1, %eax
je 0x9f27
movl 0x10(%rsp), %esi
testl %esi, %esi
sete 0x17(%rsp)
leaq 0x6(%rsp), %rcx
movb $0x0, (%rcx)
leal -0x1(%rax), %ecx
movl 0x44(%rsp), %edx
orl %esi, %edx
movl %edx, 0x8c(%rsp)
xorl %r12d, %r12d
testl %eax, %eax
cmovlel %r12d, %eax
movq %rax, 0x90(%rsp)
shlq $0x4, %rax
movq %rax, 0x98(%rsp)
shlq $0x4, %rcx
movq %rcx, 0x38(%rsp)
pushq $-0x1
popq %rax
leaq 0x1c084(%rip), %rbp     # 0x256f0
movl $0x0, 0x8(%rsp)
movl $0x0, 0xc(%rsp)
movq %rax, 0x78(%rsp)
xorl %eax, %eax
movq %r15, 0x80(%rsp)
cmpq %r12, 0x98(%rsp)
je 0x9d90
movq %r15, %rbx
movq %rax, 0x20(%rsp)
cmpl $0x0, 0x10(%rsp)
setne %r15b
leaq 0xa0(%rsp,%r12), %rax
movq %rax, 0x18(%rsp)
movq 0x8(%rax), %rax
movq (%rax), %r14
movq %rbp, %rdi
movl %r14d, %esi
callq 0xfe60
movq 0x78(%rsp), %rcx
testl %ecx, %ecx
cmovsl %r14d, %ecx
movq %rcx, 0x78(%rsp)
cmovsl %eax, %r13d
movq %r13, 0x48(%rsp)
movq %r14, 0x30(%rsp)
movslq %r14d, %rdx
movq 0x28(%rbp), %rcx
imulq $0xb0, %rdx, %r13
movq 0x28(%rcx,%r13), %rsi
movq %rsi, %rdx
orq $0x8, %rdx
movq %rdx, 0x28(%rcx,%r13)
movq %r12, %r8
cmpq %r12, 0x38(%rsp)
sete %r14b
andb %r14b, %r15b
movb %r15b, 0x7(%rsp)
btl $0x9, %esi
jb 0x9756
testb $0x4, %sil
jne 0x9768
leaq (%rcx,%r13), %rdx
cmpl $0xa, %eax
movq %rbx, %r15
jne 0x97e9
testb $0x1, 0xc(%rsp)
je 0x97e9
movl 0x34(%rdx), %eax
movq %rax, 0x70(%rsp)
movq 0x18(%rsp), %rbx
movq %r8, %r12
jmp 0x983c
cmpl $0x4, %eax
jne 0x9770
movq 0x18(%rsp), %rbx
movq %r8, %r12
jmp 0x981b
movq %rbx, %r15
jmp 0x9805
movq %rbx, %r15
testb $0x2, %sil
movq 0x18(%rsp), %rbx
movq %r8, %r12
je 0x97aa
cmpl $0x2, (%rbx)
jl 0x9dfd
movq 0xa8(%rsp,%r12), %rax
movl 0x8(%rax), %esi
leaq 0x1bf54(%rip), %rdi     # 0x256f0
callq 0xfe60
cmpl $0x7, %eax
jne 0x9dfd
xorl %edx, %edx
cmpl $0x0, 0x10(%rsp)
setne %dl
movq %r15, %rdi
movq %rbx, %rsi
leaq 0x6(%rsp), %rcx
callq 0x8bf6
testl %eax, %eax
jne 0x9f27
cmpl $0x0, 0x44(%rsp)
je 0x98e5
movl $0x1, 0x1bee3(%rip)     # 0x256c4
movb $0x1, %r14b
jmp 0x991d
cmpl $0x12, %eax
ja 0x9805
movl $0x40406, %edi          # imm = 0x40406
btl %eax, %edi
jae 0x9805
movq 0x20(%rsp), %rdi
addl 0x34(%rdx), %edi
movq %rdi, 0x20(%rsp)
movq 0x18(%rsp), %rbx
movq $0x0, 0x70(%rsp)
cmpl $0x4, %eax
movq %r8, %r12
jne 0x983c
cmpq %r12, 0x38(%rsp)
jne 0x9dea
movb $0x1, %r14b
xorl %ebp, %ebp
movb $0x1, %r15b
movq $0x0, 0x28(%rsp)
jmp 0x9929
btl $0x8, %esi
jb 0x9881
xorl %edx, %edx
cmpl $0x0, 0x10(%rsp)
setne %dl
btl $0x12, %esi
movl 0xc(%rsp), %ecx
movzbl %cl, %ecx
pushq $0x1
popq %rax
cmovbl %eax, %ecx
movl %ecx, 0xc(%rsp)
movq %r15, %rdi
movq %rbx, %rsi
leaq 0x6(%rsp), %rcx
callq 0x8bf6
testl %eax, %eax
jne 0x9f27
xorl %r14d, %r14d
jmp 0x99b6
testb $0x2, %sil
je 0x9946
cmpl $0x2, (%rbx)
jl 0x9934
movq 0xa8(%rsp,%r12), %rax
movl 0x8(%rax), %esi
leaq 0x1be4a(%rip), %rbp     # 0x256f0
movq %rbp, %rdi
callq 0xfe60
cmpl $0x7, %eax
jne 0x9930
xorl %edx, %edx
cmpl $0x0, 0x10(%rsp)
setne %dl
movq %r15, %rdi
movq %rbx, %rsi
leaq 0x6(%rsp), %rcx
callq 0x8bf6
testl %eax, %eax
jne 0x9f27
leaq 0x1be14(%rip), %rax     # 0x256f0
movq 0x28(%rax), %rcx
movb $0x1, %bpl
jmp 0x9948
movb $0x1, %r14b
cmpl $0x0, 0x10(%rsp)
je 0x991d
cmpb $0x0, 0x7(%rsp)
je 0x990d
leaq 0x1bdf3(%rip), %rax     # 0x256f0
movq 0x28(%rax), %rax
testb $0x40, 0x28(%rax,%r13)
jne 0x9ef3
movq %r15, %rdi
pushq $0x3
popq %rdx
movl %edx, %esi
pushq $0x4
popq %rcx
callq 0x11e6a
xorl %ebp, %ebp
movb $0x1, %r15b
movb $0x1, %al
movq %rax, 0x28(%rsp)
xorl %edi, %edi
jmp 0x9aec
movq 0x28(%rbp), %rcx
testb $0x4, 0x2a(%rcx,%r13)
je 0x9ec7
movb $0x1, %al
movl %eax, 0xc(%rsp)
xorl %ebp, %ebp
testb $0x8, 0x29(%rcx,%r13)
jne 0x9991
testb $0x1, 0x8(%rsp)
je 0x99ce
movq %r15, %rdi
pushq $0x2
popq %rsi
callq 0x11eea
movq %r15, %rdi
pushq $0x34
popq %rsi
callq 0x11de8
movq 0x20(%rsp), %rcx
testl %ecx, %ecx
pushq $0x7
popq %r14
jle 0x9a5a
movq %r15, %rdi
pushq $0x1
popq %rsi
pushq $0x2
popq %rdx
callq 0x11e6a
jmp 0x9a5a
testb $0x1, 0x8(%rsp)
jne 0x9ebb
movq %r15, %rdi
pushq $0x6
popq %rsi
callq 0x11ed2
movq $0x0, 0x20(%rsp)
movb $0x1, %al
movl %eax, 0x8(%rsp)
xorl %r15d, %r15d
movq $0x0, 0x28(%rsp)
xorl %edi, %edi
movq 0x70(%rsp), %rbp
jmp 0x9aec
movq 0x48(%rsp), %rax
cmpl $0x1, %eax
pushq $0x7
popq %r14
je 0x99fa
cmpl $0x2, %eax
jne 0x9f3c
movl 0x8d40(%r15), %esi
subl 0x20(%rsp), %esi
movq %r15, %rdi
callq 0x5035
jmp 0x9a5a
movslq 0x78(%rsp), %rax
imulq $0xb0, %rax, %rax
testb $0x4, 0x28(%rcx,%rax)
jne 0x9a2d
movq %r15, %rdi
pushq $0x6
popq %rsi
pushq $0x2
popq %rdx
movq 0x20(%rsp), %rcx
callq 0x11e6a
movq %r15, %rdi
pushq $0x1
popq %rsi
callq 0x120e4
jmp 0x9a5a
addq %rax, %rcx
movl 0x34(%rcx), %ecx
movq %r15, %rdi
pushq $0x6
popq %rsi
pushq $0x2
popq %rdx
callq 0x11e6a
movq %r15, %rdi
pushq $0x4
popq %rsi
callq 0x120e4
movq 0x20(%rsp), %rcx
testl %ecx, %ecx
je 0x9a5a
jmp 0x997e
testb %bpl, %bpl
movq 0x70(%rsp), %rbp
je 0x9ac0
movq %r15, %rdi
pushq $0x20
popq %rsi
movl %r14d, %edx
pushq $0x4
popq %rcx
callq 0x11e6a
leaq 0x1bc74(%rip), %rax     # 0x256f0
movq 0x28(%rax), %rax
testb $0x4, 0x2a(%rax,%r13)
je 0x9aaf
movq %r15, %rdi
pushq $0x30
popq %rsi
pushq $0x2
popq %rdx
callq 0x11e4a
movq %r15, %rdi
pushq $0x34
popq %rsi
callq 0x11de8
movq %r15, %rdi
pushq $0x47
popq %rsi
movl %r14d, %edx
callq 0x11e4a
movq %r15, %rdi
pushq $0xb
popq %rsi
pushq $0x2
popq %rdx
movl %r14d, %ecx
callq 0x11e6a
movq %r15, %rdi
pushq $0x2
popq %rsi
callq 0x11ed2
movb $0x1, %al
movl %eax, 0x8(%rsp)
movq $0x0, 0x20(%rsp)
movb $0x1, %r14b
movb $0x1, %r15b
movq $0x0, 0x28(%rsp)
movb $0x1, %dil
leaq 0x1bbfd(%rip), %rax     # 0x256f0
movq 0x28(%rax), %rcx
movq 0x28(%rcx,%r13), %rax
cmpl $0x0, 0x8c(%rsp)
je 0x9b4c
cmpl $0x0, 0x1bbb7(%rip)     # 0x256c4
jne 0x9b4c
btl $0x8, %eax
jae 0x9b1c
cmpq %r12, 0x38(%rsp)
jne 0x9b4c
testb $0x40, %al
jne 0x9e2c
testw %ax, %ax
jns 0x9b4c
testq %r12, %r12
je 0x9e5b
movq 0x98(%rsp,%r12), %rdx
imulq $0xb0, (%rdx), %rdx
testb $0x8, 0x29(%rcx,%rdx)
je 0x9e5b
testb $0x2, %al
je 0x9bb6
cmpl $0x1, (%rbx)
je 0x9b9d
movl %r14d, 0x18(%rsp)
movq %rdi, %r14
movq %rbp, %rbx
movq 0xa8(%rsp,%r12), %rax
movl 0x8(%rax), %esi
leaq 0x1bb7e(%rip), %rbp     # 0x256f0
movq %rbp, %rdi
callq 0xfe60
movq 0x28(%rbp), %rcx
cmpl $0x7, %eax
jne 0x9b92
xorl %eax, %eax
movq %rbx, %rbp
movq %r14, %rdi
movl 0x18(%rsp), %r14d
jmp 0x9bb8
movq %rbx, %rbp
movq %r14, %rdi
movl 0x18(%rsp), %r14d
testb $0x4, 0x2a(%rcx,%r13)
jne 0x9bb6
leaq (%rcx,%r13), %rax
cmpq $0x0, 0x48(%rax)
setne %al
orb %al, %r14b
jmp 0x9bb8
xorl %eax, %eax
movq 0x28(%rcx,%r13), %rdx
btl $0x8, %edx
jb 0x9bf3
addq %rcx, %r13
movswq 0x30(%r13), %rsi
imulq $0xb0, %rsi, %rsi
testb $0x4, 0x29(%rcx,%rsi)
je 0x9bf3
cmpq %r12, 0x38(%rsp)
movq 0x48(%rsp), %r13
jne 0x9bf8
btl $0x12, %edx
setae %cl
orb %cl, %r14b
orb %cl, %al
jmp 0x9bf8
movq 0x48(%rsp), %r13
cmpl $0x0, 0x10(%rsp)
je 0x9c07
testb $0x1, %al
jne 0x9dbb
cmpq %r12, 0x38(%rsp)
sete %al
orb %al, %r15b
cmpb $0x1, %r15b
jne 0x9d50
movq %rdi, %rbx
movq 0x80(%rsp), %r15
movl 0x8d4c(%r15), %eax
movl %eax, 0x18(%rsp)
testb $0x1, 0x8(%rsp)
je 0x9c44
movq %r15, %rdi
pushq $0x2
popq %rsi
callq 0x11eea
cmpq %r12, 0x38(%rsp)
sete %al
orb 0x17(%rsp), %al
jne 0x9c5d
movq %r15, %rdi
pushq $0x3
popq %rsi
callq 0x11ed2
movzbl 0x7(%rsp), %r8d
movzbl 0x6(%rsp), %eax
movzbl 0x88(%rsp), %r11d
movzbl 0xc(%rsp), %r13d
andl $0x1, %r13d
movq %r15, %rdi
movzbl %bl, %r15d
movzbl 0x8(%rsp), %r10d
andl $0x1, %r10d
movzbl %r14b, %edx
andl $0x1, %edx
movzbl 0x28(%rsp), %ecx
movq 0x30(%rsp), %rsi
movl 0x44(%rsp), %r9d
pushq %rbp
pushq %r11
pushq %r13
pushq 0x60(%rsp)
pushq 0x98(%rsp)
pushq %r15
pushq %r10
pushq 0x58(%rsp)
pushq %rax
pushq %rdx
callq 0x8faa
addq $0x50, %rsp
testl %eax, %eax
jne 0x9f27
movl $0x0, 0x8(%rsp)
movb $0x0, 0x6(%rsp)
movl $0x0, 0xc(%rsp)
pushq $0x1
popq %rax
movl %eax, %r13d
movl $0x0, %eax
cmpq %r12, 0x38(%rsp)
movq 0x80(%rsp), %r15
je 0x9d80
movq 0x28(%rsp), %rax
orb %r14b, %al
testb $0x1, %al
je 0x9e8a
cmpl $0x0, 0x10(%rsp)
je 0x9d5f
movl 0x18(%rsp), %eax
movl %eax, 0x8d4c(%r15)
movq %r15, %rdi
pushq $0x4
popq %rbp
movl %ebp, %esi
callq 0x11eea
movq %r15, %rdi
pushq $0x3
popq %r14
movl %r14d, %esi
callq 0x11ed2
movq %r15, %rdi
movl %r14d, %esi
movl %ebp, %edx
movl %r14d, %ecx
callq 0x11e6a
jmp 0x9d6a
movq 0x80(%rsp), %r15
movq 0x20(%rsp), %rax
jmp 0x9d80
movq %r15, %rdi
pushq $0x3
popq %rsi
callq 0x11ed2
movl $0x0, 0xc(%rsp)
movb $0x1, %al
movl %eax, 0x8(%rsp)
pushq $0x1
popq %rax
movl %eax, %r13d
xorl %eax, %eax
addq $0x10, %r12
leaq 0x1b965(%rip), %rbp     # 0x256f0
jmp 0x968b
leaq 0xa0(%rsp), %r14
movq 0x90(%rsp), %rbx
subq $0x1, %rbx
jb 0x9db4
movq %r14, %rdi
callq 0xe9a4
addq $0x10, %r14
jmp 0x9da0
xorl %eax, %eax
jmp 0x9f2a
leaq 0x1b92e(%rip), %rsi     # 0x256f0
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq 0x30(%rsp), %rdx
callq 0x10864
movq (%rbx), %rsi
leaq 0xf68f(%rip), %rdi      # 0x1946d
xorl %eax, %eax
callq 0xf258
jmp 0x9f1d
leaq 0xf5b5(%rip), %rdi      # 0x193a6
xorl %eax, %eax
callq 0xf258
jmp 0x9f27
leaq 0x1b8ec(%rip), %rsi     # 0x256f0
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq 0x30(%rsp), %rdx
callq 0x10864
movq (%rbx), %rsi
leaq 0xf5a6(%rip), %rdi      # 0x193c6
xorl %eax, %eax
callq 0xf258
jmp 0x9f1d
leaq 0x1b8bd(%rip), %rsi     # 0x256f0
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq 0x30(%rsp), %rdx
callq 0x10864
movq (%rbx), %rsi
leaq 0xf5e2(%rip), %rdi      # 0x19431
xorl %eax, %eax
callq 0xf258
jmp 0x9f1d
leaq 0x1b88e(%rip), %rsi     # 0x256f0
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq 0x30(%rsp), %rdx
callq 0x10864
movq (%rbx), %rsi
leaq 0xf5ce(%rip), %rdi      # 0x1944c
xorl %eax, %eax
callq 0xf258
jmp 0x9f1d
movq 0xb8(%rsp,%r12), %rax
movl (%rax), %edx
leaq 0x1b855(%rip), %rsi     # 0x256f0
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
callq 0x10864
movq (%rbx), %rsi
leaq 0xf5d1(%rip), %rdi      # 0x19483
xorl %eax, %eax
callq 0xf258
jmp 0x9f1d
leaq 0xf53f(%rip), %rdi      # 0x19401
jmp 0x9df1
leaq 0x1b822(%rip), %rsi     # 0x256f0
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq 0x30(%rsp), %rdx
callq 0x10864
movq (%rbx), %rsi
leaq 0xf4dc(%rip), %rdi      # 0x193c6
xorl %eax, %eax
callq 0xf258
jmp 0x9f1d
leaq 0x1b7f6(%rip), %rsi     # 0x256f0
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq 0x30(%rsp), %rdx
callq 0x10864
movq (%rbx), %rsi
leaq 0xf4d0(%rip), %rdi      # 0x193e6
xorl %eax, %eax
callq 0xf258
leaq 0x50(%rsp), %rdi
callq 0x31a0
pushq $-0x1
popq %rax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xf4d5(%rip), %rdi      # 0x19418
jmp 0x9df1
jmp 0x9f54
jmp 0x9f54
jmp 0x9f54
jmp 0x9f54
jmp 0x9f54
jmp 0x9f54
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x31a0
movq %rbx, %rdi
callq 0x3560