// File: /workspace/github_cpp_makefile_star2_O1/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 $0x158, %rsp            # imm = 0x158
movl %r9d, 0x90(%rsp)
movl %r8d, 0x6c(%rsp)
movl %ecx, %r15d
movq %rdx, 0x18(%rsp)
movq %rsi, %rbx
movl %edi, %ebp
testl %ecx, %ecx
jne 0xa1e2
movl (%rbx), %esi
movq 0x18(%rsp), %rdi
callq 0x7ff4
leaq 0xb0(%rsp), %rdi
movl %ebp, %esi
movq %rbx, %rdx
callq 0x813d
cmpl $-0x1, %eax
je 0xac49
movl %eax, %ecx
movb $0x0, 0xb(%rsp)
movl %eax, %eax
movq %rax, 0x98(%rsp)
movq %rcx, 0xa0(%rsp)
testl %ecx, %ecx
jle 0xac50
testl %r15d, %r15d
sete 0x27(%rsp)
movq 0xa0(%rsp), %rax
decl %eax
movl 0x6c(%rsp), %ecx
orl %r15d, %ecx
movl %ecx, 0x94(%rsp)
shlq $0x4, %rax
movq %rax, 0x60(%rsp)
movq 0x98(%rsp), %rax
shlq $0x4, %rax
movq %rax, 0xa8(%rsp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rax, 0x80(%rsp)
leaq 0x1b471(%rip), %r8      # 0x256e0
xorl %r13d, %r13d
movq $0x0, 0x28(%rsp)
movl $0x0, 0x10(%rsp)
movl $0x0, 0xc(%rsp)
movl %r15d, 0x14(%rsp)
testl %r15d, %r15d
setne %r14b
movq 0xb8(%rsp,%r13), %rax
movq %rax, 0x58(%rsp)
movq (%rax), %rbp
movq %r8, %rdi
movl %ebp, %esi
callq 0x111aa
leaq 0x1b428(%rip), %r8      # 0x256e0
movq 0x80(%rsp), %rcx
testl %ecx, %ecx
cmovsl %ebp, %ecx
movq %rcx, 0x80(%rsp)
cmovsl %eax, %ebx
movq %rbx, 0x78(%rsp)
movslq %ebp, %rcx
movq 0x28(%r8), %rdx
imulq $0xb0, %rcx, %rbx
movq 0x28(%rdx,%rbx), %rcx
movq %rcx, %rsi
orq $0x8, %rsi
movq %rsi, 0x28(%rdx,%rbx)
cmpq %r13, 0x60(%rsp)
sete %r12b
testl $0x204, %ecx            # imm = 0x204
je 0xa39c
movq $0x0, 0x70(%rsp)
leaq (%rsp,%r13), %rsi
addq $0xb0, %rsi
andb %r12b, %r14b
cmpl $0x4, %eax
jne 0xa340
cmpq %r13, 0x60(%rsp)
jne 0xa3b8
movb $0x1, %r12b
xorl %edi, %edi
movb $0x1, %r10b
xorl %r9d, %r9d
jmp 0xa81f
btl $0x9, %ecx
jb 0xa3cd
btl $0x8, %ecx
jb 0xa435
xorl %edx, %edx
movl %r15d, %r12d
testl %r15d, %r15d
setne %dl
btl $0x12, %ecx
movl 0x10(%rsp), %ecx
movzbl %cl, %ecx
movl $0x1, %eax
cmovbl %eax, %ecx
movl %ecx, 0x10(%rsp)
movq 0x18(%rsp), %rdi
movq %rsi, %r15
leaq 0xb(%rsp), %rcx
callq 0x96b9
xorl %edi, %edi
testl %eax, %eax
jne 0xa3fb
xorl %r12d, %r12d
xorl %r10d, %r10d
xorl %r9d, %r9d
jmp 0xa526
addq %rbx, %rdx
cmpl $0xa, %eax
jne 0xa40c
testb $0x1, 0x10(%rsp)
je 0xa40c
movl 0x34(%rdx), %edx
movq %rdx, 0x70(%rsp)
jmp 0xa312
xorl %ebx, %ebx
leaq 0x11005(%rip), %rdi     # 0x1b3c6
xorl %eax, %eax
callq 0x10418
jmp 0xaaba
testb $0x2, %cl
jne 0xa49a
xorl %edx, %edx
movl %r15d, %r12d
testl %r15d, %r15d
setne %dl
movq 0x18(%rsp), %rdi
movq %rsi, %r15
leaq 0xb(%rsp), %rcx
callq 0x96b9
testl %eax, %eax
je 0xa505
xorl %ebx, %ebx
leaq 0x1b2dc(%rip), %r8      # 0x256e0
movl %r12d, %r15d
jmp 0xaac1
cmpl $0x12, %eax
ja 0xa309
movl $0x40406, %esi          # imm = 0x40406
btl %eax, %esi
jae 0xa309
movq 0x28(%rsp), %rsi
addl 0x34(%rdx), %esi
movq %rsi, 0x28(%rsp)
jmp 0xa309
testb $0x2, %cl
je 0xa58c
cmpl $0x2, (%rsi)
jl 0xa535
movq 0x58(%rsp), %rax
movq %rsi, 0x50(%rsp)
movl 0x8(%rax), %esi
movq %r8, %rdi
callq 0x111aa
movq 0x50(%rsp), %rsi
leaq 0x1b278(%rip), %r8      # 0x256e0
cmpl $0x7, %eax
jne 0xa535
xorl %edx, %edx
testl %r15d, %r15d
setne %dl
movq 0x18(%rsp), %rdi
leaq 0xb(%rsp), %rcx
callq 0x96b9
xorl %ecx, %ecx
testl %eax, %eax
je 0xa71b
xorl %r12d, %r12d
jmp 0xa713
cmpl $0x2, (%rsi)
jl 0xa4cb
movq 0x58(%rsp), %rax
movl %r15d, %r12d
movq %rsi, %r15
movl 0x8(%rax), %esi
movq %r8, %rdi
callq 0x111aa
movq %r15, %rsi
movl %r12d, %r15d
leaq 0x1b21e(%rip), %r8      # 0x256e0
cmpl $0x7, %eax
je 0xa3d6
leaq 0x30(%rsp), %rdi
movq %r8, %rsi
movl %ebp, %edx
callq 0x11fa0
movq 0x30(%rsp), %rsi
leaq 0x10f00(%rip), %rdi     # 0x1b3e6
xorl %eax, %eax
callq 0x10418
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
jne 0xaaab
jmp 0xaab8
cmpl $0x0, 0x6c(%rsp)
je 0xa669
movl $0x1, 0x1b19a(%rip)     # 0x256b4
movb $0x1, %r12b
xorl %r9d, %r9d
movb $0x1, %r10b
movb $0x1, %dil
leaq 0x1b1b3(%rip), %r8      # 0x256e0
movq %r15, %rsi
jmp 0xa81f
movq 0x28(%r8), %rax
testb $0x4, 0x2a(%rax,%rbx)
jne 0xa586
movq %rsi, %r15
leaq 0x30(%rsp), %rdi
movq %r8, %rsi
movl %ebp, %edx
callq 0x11fa0
movq 0x30(%rsp), %rsi
leaq 0x10e88(%rip), %rdi     # 0x1b3e6
xorl %eax, %eax
callq 0x10418
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0xa581
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x3320
xorl %r12d, %r12d
jmp 0xa603
movb $0x1, %al
movl %eax, 0x10(%rsp)
xorl %r15d, %r15d
movq 0x28(%r8), %rax
testb $0x8, 0x29(%rax,%rbx)
jne 0xa5eb
testb $0x1, 0xc(%rsp)
movq %rsi, 0x50(%rsp)
je 0xa607
movq 0x18(%rsp), %r12
movq %r12, %rdi
movl $0x2, %esi
callq 0x136b2
movq %r12, %rdi
movl $0x34, %esi
callq 0x1359c
movq 0x28(%rsp), %rcx
testl %ecx, %ecx
jle 0xa767
movq 0x18(%rsp), %rdi
movl $0x1, %esi
movl $0x2, %edx
callq 0x1361c
jmp 0xa767
movq %rsi, %r15
testb $0x1, 0xc(%rsp)
je 0xa637
leaq 0x10e25(%rip), %rdi     # 0x1b421
xorl %eax, %eax
callq 0x10418
xorl %ecx, %ecx
jmp 0xa657
movq 0x78(%rsp), %rcx
cmpl $0x1, %ecx
je 0xa6c2
cmpl $0x2, %ecx
jne 0xa703
movq 0x18(%rsp), %rdi
movl 0x8d40(%rdi), %esi
subl 0x28(%rsp), %esi
callq 0x5291
jmp 0xa767
movq 0x18(%rsp), %rdi
movl $0x6, %esi
callq 0x13684
movb $0x1, %al
movl %eax, 0xc(%rsp)
movq $0x0, 0x28(%rsp)
movb $0x1, %cl
xorl %r10d, %r10d
leaq 0x1b07f(%rip), %r8      # 0x256e0
movq %r15, %rsi
jmp 0xa812
testl %r12d, %r12d
leaq 0x1b06d(%rip), %r8      # 0x256e0
je 0xa6ae
testb %r14b, %r14b
je 0xa689
movq 0x28(%r8), %rax
testb $0x40, 0x28(%rax,%rbx)
jne 0xac0c
movq 0x18(%rsp), %rdi
movl $0x3, %esi
movl $0x3, %edx
movl $0x4, %ecx
callq 0x1361c
movq %r15, %rsi
leaq 0x1b034(%rip), %r8      # 0x256e0
jmp 0xa6b1
movq %r15, %rsi
movb $0x1, %r12b
xorl %r9d, %r9d
movb $0x1, %r10b
movb $0x1, %dil
jmp 0xa81f
movslq 0x80(%rsp), %rcx
imulq $0xb0, %rcx, %rcx
testb $0x4, 0x28(%rax,%rcx)
jne 0xa72f
movq 0x18(%rsp), %r12
movq %r12, %rdi
movl $0x6, %esi
movl $0x2, %edx
movq 0x28(%rsp), %rcx
callq 0x1361c
movq %r12, %rdi
movl $0x1, %esi
callq 0x13950
jmp 0xa767
leaq 0x10d2e(%rip), %rdi     # 0x1b438
xorl %eax, %eax
callq 0x10418
xorl %ecx, %ecx
xorl %r10d, %r10d
jmp 0xa806
movb $0x1, %r15b
leaq 0x1afbb(%rip), %r8      # 0x256e0
movq 0x50(%rsp), %rsi
jmp 0xa58f
addq %rcx, %rax
movl 0x34(%rax), %ecx
movq 0x18(%rsp), %r12
movq %r12, %rdi
movl $0x6, %esi
movl $0x2, %edx
callq 0x1361c
movq %r12, %rdi
movl $0x4, %esi
callq 0x13950
movq 0x28(%rsp), %rcx
testl %ecx, %ecx
je 0xa767
jmp 0xa5d2
testb %r15b, %r15b
movq 0x18(%rsp), %r15
je 0xa7e2
movq %r15, %rdi
movl $0x20, %esi
movl $0x7, %edx
movl $0x4, %ecx
callq 0x1361c
leaq 0x1af51(%rip), %rax     # 0x256e0
movq 0x28(%rax), %rax
testb $0x4, 0x2a(%rax,%rbx)
je 0xa7cb
movq %r15, %rdi
movl $0x30, %esi
movl $0x2, %edx
callq 0x135fc
movq %r15, %rdi
movl $0x34, %esi
callq 0x1359c
movq %r15, %rdi
movl $0x47, %esi
movl $0x7, %edx
callq 0x135fc
movq %r15, %rdi
movl $0xb, %esi
movl $0x2, %edx
movl $0x7, %ecx
callq 0x1361c
movq %r15, %rdi
movl $0x2, %esi
callq 0x13684
movb $0x1, %al
movl %eax, 0xc(%rsp)
movq $0x0, 0x28(%rsp)
movb $0x1, %r12b
movb $0x1, %cl
movb $0x1, %r10b
leaq 0x1aed3(%rip), %r8      # 0x256e0
movq 0x50(%rsp), %rsi
xorl %edi, %edi
movl %r10d, %r9d
testb %cl, %cl
je 0xaa6c
cmpl $0x0, 0x94(%rsp)
je 0xa850
cmpl $0x0, 0x1ae84(%rip)     # 0x256b4
jne 0xa850
movq 0x28(%r8), %rax
movq 0x28(%rax,%rbx), %rcx
btl $0x8, %ecx
jae 0xaa1b
cmpq %r13, 0x60(%rsp)
je 0xaa1b
movq 0x28(%r8), %rax
testb $0x2, 0x28(%rax,%rbx)
je 0xa8cb
cmpl $0x1, (%rsi)
je 0xa8a6
movq 0x58(%rsp), %rax
movl 0x8(%rax), %esi
movl %edi, 0x58(%rsp)
movq %r8, %rdi
movl %r12d, 0x50(%rsp)
movq %rbp, %r12
movl %r14d, %ebp
movl %r9d, %r14d
movl %r10d, %r15d
callq 0x111aa
movl %r15d, %r10d
movl %r14d, %r9d
movl %ebp, %r14d
movq %r12, %rbp
movl 0x50(%rsp), %r12d
movl 0x58(%rsp), %edi
leaq 0x1ae3f(%rip), %r8      # 0x256e0
cmpl $0x7, %eax
je 0xa8cb
movq 0x28(%r8), %rax
testb $0x4, 0x2a(%rax,%rbx)
jne 0xa8cb
addq %rbx, %rax
cmpq $0x0, 0x48(%rax)
setne %al
movzbl %r12b, %r12d
movl $0x1, %ecx
cmovnel %ecx, %r12d
jmp 0xa8cd
xorl %eax, %eax
movq 0x28(%r8), %rdx
movq 0x28(%rdx,%rbx), %rcx
btl $0x8, %ecx
jb 0xa910
addq %rdx, %rbx
movswq 0x30(%rbx), %rsi
imulq $0xb0, %rsi, %rsi
testb $0x4, 0x29(%rdx,%rsi)
je 0xa910
cmpq %r13, 0x60(%rsp)
jne 0xa910
btl $0x12, %ecx
movzbl %r12b, %r12d
movl $0x1, %ecx
cmovael %ecx, %r12d
movzbl %al, %eax
cmovael %ecx, %eax
cmpl $0x0, 0x14(%rsp)
je 0xa942
testb %al, %al
je 0xa942
leaq 0x30(%rsp), %rdi
movq %r8, %rsi
movl %ebp, %edx
callq 0x11fa0
movq 0x30(%rsp), %rsi
leaq 0x10b57(%rip), %rdi     # 0x1b48d
xorl %eax, %eax
callq 0x10418
jmp 0xaa97
movb $0x1, %bl
testb %r10b, %r10b
jne 0xa954
cmpq %r13, 0x60(%rsp)
jne 0xaa6e
movl %r9d, 0x50(%rsp)
movl %edi, 0x58(%rsp)
movq 0x18(%rsp), %r15
movl 0x8d4c(%r15), %eax
movl %eax, 0x8c(%rsp)
testb $0x1, 0xc(%rsp)
je 0xa984
movq %r15, %rdi
movl $0x2, %esi
callq 0x136b2
cmpq %r13, 0x60(%rsp)
sete %al
orb 0x27(%rsp), %al
jne 0xa99f
movq %r15, %rdi
movl $0x3, %esi
callq 0x13684
movzbl %r14b, %r8d
movzbl 0xb(%rsp), %eax
movzbl 0x90(%rsp), %r10d
movzbl 0x10(%rsp), %r11d
andl $0x1, %r11d
movzbl 0x50(%rsp), %r14d
movq %r15, %rdi
movzbl 0xc(%rsp), %r15d
andl $0x1, %r15d
movzbl %r12b, %edx
movzbl 0x58(%rsp), %ecx
movl %ebp, %esi
movl 0x6c(%rsp), %r9d
pushq 0x70(%rsp)
pushq %r10
pushq %r11
pushq 0x90(%rsp)
pushq 0xa0(%rsp)
pushq %r14
pushq %r15
pushq 0x60(%rsp)
pushq %rax
pushq %rdx
callq 0x9aa4
addq $0x50, %rsp
testl %eax, %eax
je 0xaae5
xorl %ebx, %ebx
movl 0x14(%rsp), %r15d
jmp 0xaaba
testb $0x40, %cl
jne 0xaa75
testw %cx, %cx
jns 0xa850
testq %r13, %r13
je 0xaa48
movq 0xa8(%rsp,%r13), %rcx
imulq $0xb0, (%rcx), %rcx
testb $0x8, 0x29(%rax,%rcx)
jne 0xa850
leaq 0x30(%rsp), %rdi
movq %r8, %rsi
movl %ebp, %edx
callq 0x11fa0
movq 0x30(%rsp), %rsi
leaq 0x10a09(%rip), %rdi     # 0x1b46c
xorl %eax, %eax
callq 0x10418
jmp 0xaa97
xorl %ebx, %ebx
movl 0x14(%rsp), %r15d
jmp 0xaac1
leaq 0x30(%rsp), %rdi
movq %r8, %rsi
movl %ebp, %edx
callq 0x11fa0
movq 0x30(%rsp), %rsi
leaq 0x109c1(%rip), %rdi     # 0x1b451
xorl %eax, %eax
callq 0x10418
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
movl 0x14(%rsp), %r15d
je 0xaab8
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x3320
xorl %ebx, %ebx
leaq 0x1ac1f(%rip), %r8      # 0x256e0
testb %bl, %bl
je 0xac49
addq $0x10, %r13
cmpq %r13, 0xa8(%rsp)
movq 0x78(%rsp), %rbx
jne 0xa290
jmp 0xac50
movb $0x0, 0xb(%rsp)
movl $0x1, %eax
movq %rax, 0x78(%rsp)
cmpq %r13, 0x60(%rsp)
movl 0x14(%rsp), %r15d
leaq 0x1abdb(%rip), %r8      # 0x256e0
jne 0xab22
movl $0x0, 0xc(%rsp)
movl $0x0, 0x10(%rsp)
movq $0x0, 0x28(%rsp)
jmp 0xaac1
movl 0x58(%rsp), %eax
orb %r12b, %al
cmpb $0x1, %al
jne 0xab7b
testl %r15d, %r15d
je 0xabdf
movq 0x18(%rsp), %rbx
movl 0x8c(%rsp), %eax
movl %eax, 0x8d4c(%rbx)
movq %rbx, %rdi
movl $0x4, %esi
callq 0x136b2
movq %rbx, %rdi
movl $0x3, %esi
callq 0x13684
movq %rbx, %rdi
movl $0x3, %esi
movl $0x4, %edx
movl $0x3, %ecx
callq 0x1361c
jmp 0xabee
movq 0xc8(%rsp,%r13), %rax
movl (%rax), %edx
leaq 0x30(%rsp), %rdi
movq %r8, %rsi
callq 0x11fa0
movq 0x30(%rsp), %rsi
leaq 0x10905(%rip), %rdi     # 0x1b4a3
xorl %eax, %eax
callq 0x10418
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0xabc1
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x3320
movl $0x0, 0xc(%rsp)
movl $0x0, 0x10(%rsp)
movq $0x0, 0x28(%rsp)
jmp 0xaab8
movq 0x18(%rsp), %rdi
movl $0x3, %esi
callq 0x13684
movb $0x1, %al
movl %eax, 0xc(%rsp)
movl $0x0, 0x10(%rsp)
movq $0x0, 0x28(%rsp)
movb $0x1, %bl
jmp 0xaaba
leaq 0x30(%rsp), %rdi
movq %r8, %rsi
movl %ebp, %edx
callq 0x11fa0
movq 0x30(%rsp), %rsi
leaq 0x107df(%rip), %rdi     # 0x1b406
xorl %eax, %eax
callq 0x10418
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
movl %r12d, %r15d
jne 0xaaab
jmp 0xaab8
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0xac91
cmpl $0x0, 0xa0(%rsp)
jle 0xac8f
movq 0x98(%rsp), %r15
shlq $0x4, %r15
xorl %ebx, %ebx
xorl %r14d, %r14d
movq 0xb8(%rsp,%r14), %rdi
callq 0x33c0
movq $0x0, 0xb8(%rsp,%r14)
addq $0x10, %r14
cmpq %r14, %r15
jne 0xac6b
jmp 0xac91
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xacb1
jmp 0xacb1
jmp 0xacb1
jmp 0xacb1
jmp 0xacb1
jmp 0xacb1
movq %rax, %rbx
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0xacd0
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x3320
movq %rbx, %rdi
callq 0x3560