// File: UTSASRG[P]Guarder/./bibopheap.hh
// Function: BibopHeap::initialize()
void * initialize() {
		unsigned threadNum, bagNum;
		size_t lastUsableBagSize;

		BibopHeap::_cacheSize = BIBOP_CACHE_SIZE;
		BibopHeap::_overProvObjBufSize = OVER_PROV_OBJ_BUF_SZ;

		#ifdef BIBOP_BAG_SIZE
		#pragma message "BIBOP_BAG_SIZE in use: overrides randomized bag size"
		_bibopBagSize = BIBOP_BAG_SIZE;
		#else		// randomized bag size
		unsigned randPower = getRandomNumber() % (LOG2(MAX_RANDOM_BAG_SIZE / MIN_RANDOM_BAG_SIZE) + 1);
		_bibopBagSize = MIN_RANDOM_BAG_SIZE << randPower;
		#endif

		if(_bibopBagSize > LARGE_OBJECT_THRESHOLD) {
				lastUsableBagSize = LARGE_OBJECT_THRESHOLD;
		} else {
				lastUsableBagSize = _bibopBagSize;
		}
		_numUsableBags = LOG2(lastUsableBagSize) - LOG2(BIBOP_MIN_BLOCK_SIZE) + 1;
		if(_numUsableBags > BIBOP_NUM_BAGS) {
				_numUsableBags = BIBOP_NUM_BAGS;
		}
		_lastUsableBag = _numUsableBags - 1;

		assert(BIBOP_HEAP_SIZE > 0);

		BibopHeap::_bagShiftBits = LOG2(_bibopBagSize);
		_threadShiftBits = LOG2((_bibopBagSize * BIBOP_NUM_BAGS));
		BibopHeap::_bagMask = _bibopBagSize - 1;

		PRINF("_bibopBagSize=0x%lx, _bagShiftBits=%ld, sizeof(PerThreadBag)=%zu",
			_bibopBagSize, BibopHeap::_bagShiftBits, sizeof(PerThreadBag));
		PRINF("BIBOP_NUM_BAGS=%u, _numUsableBags=%u", BIBOP_NUM_BAGS, _numUsableBags);
		PRINF("sizeof(PerThreadBag)=%zu, sizeof(BibopObjCache)=%zu, sizeof(BibopFreeCache)=%zu",
				sizeof(PerThreadBag), sizeof(BibopObjCache), sizeof(BibopFreeCache));

		// Bag size cannot be smaller than the large object threshold.
		assert(_bibopBagSize >= LARGE_OBJECT_THRESHOLD);

		// Allocate the heap all at once.
		allocHeap(BIBOP_HEAP_SIZE);

    unsigned long numBagObjects;
    unsigned long numCumObjects = 0;
    size_t unusableHeapSpace = (BIBOP_NUM_BAGS - _numUsableBags) * _bibopBagSize;

    // Initialize each thread bag's free list, and other information
    for(threadNum = 0; threadNum < MAX_ALIVE_THREADS; threadNum++) {
      size_t classSize = BIBOP_MIN_BLOCK_SIZE;

      for(bagNum = 0; bagNum < _numUsableBags; bagNum++) {
        numBagObjects = _bibopBagSize / classSize;

        #ifdef ENABLE_GUARDPAGE
            // We must perform this >1 test or else we will underflow this value
            // for bags which have 0 objects in them. Also, the last usable bag
            // will only contain a single object, but it will not be reduced to
            // make room for a guard page, but rather the next bag (which is
            // unusable) will be converted entirely into a guard page. 
            if(numBagObjects > 1) {
                if(classSize < PageSize) {
                    numBagObjects -= (PageSize / classSize);
                } else {
                    numBagObjects--;
                }
            }
        #endif

        // Update the following values; 
        numCumObjects += numBagObjects;
        classSize <<= 1;
      }
    }

		_shadowObjectInfoSizeShiftBits = LOG2(sizeof(shadowObjectInfo));
    _numBagsPerSubHeapMask = BIBOP_NUM_BAGS - 1;
    size_t numObjectsInHeap = numCumObjects;

		//unsigned freeCacheDivisor = 1;		// no reduction to deallocation buffer size
		unsigned freeCacheDivisor = 16;
		unsigned long numFreeAreaObjects = numObjectsInHeap / freeCacheDivisor;

		allocShadowMem(numObjectsInHeap);
		allocFreeArea(numFreeAreaObjects);
		allocGlobalFreeCache(numObjectsInHeap);

		// Allocate memory for use by each bag's object cache
		size_t objectCacheSize = OVER_PROV_OBJ_BUF_SZ + BIBOP_CACHE_SIZE;
		size_t objectCacheAreaSize = sizeof(uintptr_t) * objectCacheSize * BIBOP_NUM_BAGS * MAX_ALIVE_THREADS;
		uintptr_t * objectCacheStart = (uintptr_t *)MM::mmapAllocatePrivate(objectCacheAreaSize);
		uintptr_t * currentObjectCachePos = objectCacheStart;

		uintptr_t _uHeapStart = (uintptr_t)_heapBegin;
		uintptr_t _uShadowMemStart = (uintptr_t)_shadowMemBegin;
		uintptr_t _uFreeAreaBegin = (uintptr_t)_freeAreaBegin;
		unsigned long offsetShadowMem = 0;
		unsigned long offsetFreeArea = 0;
    unsigned long offsetBag = 0;

		// Initialize each thread bag's free list, and other information
		for(threadNum = 0; threadNum < MAX_ALIVE_THREADS; threadNum++) {
			PerThreadMap& curMap = _threadMap[threadNum];
			curMap.initialize(_bagShiftBits);

			for(bagNum = 0; bagNum < _numUsableBags; bagNum++) {
				unsigned shiftBits = curMap.getClassSize(bagNum);
				size_t classSize = (1U << shiftBits);
				if(threadNum == 0)
						PRDBG("bag %d classSize = %zu, shiftBits = %u", bagNum, classSize, shiftBits);
				PerThreadBag * curBag = &_threadBag[threadNum][bagNum];
				
				curBag->cache = &_bagCache[threadNum][bagNum];
				curBag->freeCache = &_freeCache[threadNum][bagNum];
				curBag->classSize = classSize;
				curBag->classMask = classSize - 1;
				curBag->shiftBits = shiftBits;
				curBag->bagNum = bagNum;
				curBag->threadIndex = threadNum; 

				numBagObjects = _bibopBagSize / classSize;
				uintptr_t bagStart = _uHeapStart + offsetBag;
				uintptr_t bagEnd = bagStart + _bibopBagSize;
				uintptr_t bagShadowMemStart = _uShadowMemStart + offsetShadowMem;
				uintptr_t bagFreeAreaStart = _uFreeAreaBegin + offsetFreeArea;

				//PRDBG("thread %d bag %d: heap start @ 0x%lx, shadow mem @ 0x%lx, free cache @ 0x%lx, Cache=%p, FreeCache=%p",
				//				threadNum, bagNum, bagStart, bagShadowMemStart, bagFreeAreaStart, curBag->cache, curBag->freeCache);

				#ifdef ENABLE_GUARDPAGE
						size_t guardsize = classSize > PAGESIZE ? classSize : PAGESIZE;
						size_t guardoffset = guardsize;
						if(bagNum == _lastUsableBag) {
								// If this bag can only fit one object,
								// forego the use of a guard object at the end of the bag.
								if(_bibopBagSize == lastUsableBagSize) {
										guardoffset = 0;
										guardsize = 0;
								}
								// Add to the guard size the amount of unusable space left on the heap.
								guardsize += (BIBOP_NUM_BAGS - LOG2(lastUsableBagSize) + LOG2(BIBOP_MIN_BLOCK_SIZE) - 1) * _bibopBagSize;

								//PRDBG("last usable bag: lastUsableBagSize=%zu, _bibopBagSize=%zu, guardsize=%zu, guardoffset=%zu",
								//		lastUsableBagSize, _bibopBagSize, guardsize, guardoffset);
						}
						curBag->guardsize = guardsize;
						curBag->guardoffset = guardoffset;
				#else
						size_t guardoffset = 0;
				#endif

				#ifdef ENABLE_GUARDPAGE
						// We must perform this >1 test or else we will underflow this value
						// for bags which have 0 objects in them. Also, the last usable bag
						// will only contain a single object, but it will not be reduced to
						// make room for a guard page, but rather the next bag (which is
						// unusable) will be converted entirely into a guard page. 
						if(numBagObjects > 1) {
								if(classSize < PageSize) {
										numBagObjects -= (PageSize / classSize);
								} else {
										numBagObjects--;
								}
						}
				#endif

				unsigned long bagFreeCacheCapacity = numBagObjects / freeCacheDivisor;

				curBag->startShadowMem = bagShadowMemStart;
				curBag->cache->initialize(bagStart, bagEnd, currentObjectCachePos, curBag->freeCache, shiftBits);
				// In order to prevent false sharing, do not utilize a global
				// free buffer for size classes smaller than the cache line size
				if(classSize >= CACHE_LINE_SIZE) {
						curBag->freeCache->initialize(bagFreeAreaStart, bagFreeCacheCapacity, NULL);
				} else {
						curBag->freeCache->initialize(bagFreeAreaStart, bagFreeCacheCapacity, &_globalFreeCache[shiftBits]);
				}

				currentObjectCachePos += objectCacheSize;

				curBag->startOffset = offsetBag;
				curBag->lastObjectIndex = numBagObjects - 1;

				// Update loop variables
				offsetBag += _bibopBagSize;
				offsetShadowMem += numBagObjects;
				offsetFreeArea += bagFreeCacheCapacity * sizeof(uintptr_t);
				}
			offsetBag += unusableHeapSpace;
		}

		#ifndef NDEBUG
		// DEBUG
		uintptr_t _uFreeAreaEnd = _uFreeAreaBegin + (numFreeAreaObjects * sizeof(uintptr_t));
		assert((_uFreeAreaBegin + offsetFreeArea) <= _uFreeAreaEnd);
		#endif

		_numBagsPerSubHeapMask = BIBOP_NUM_BAGS - 1;

		PRINF("_heapBegin=%p, _heapEnd=%p", _heapBegin, _heapEnd);
		PRINF("_shadowMemBegin=%p, _shadowMemEnd=%p, _freeAreaBegin=%p, _freeAreaEnd=%p",
						_shadowMemBegin, _shadowMemEnd, _freeAreaBegin, _freeAreaEnd);

		return _heapBegin;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $0x188, %rsp            # imm = 0x188
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x110(%rbp)
movq 0xa276(%rip), %rax      # 0x10f18
movl 0x8(%rax), %ecx
movq 0xa2c4(%rip), %rax      # 0x10f70
movl %ecx, (%rax)
movq 0xa263(%rip), %rax      # 0x10f18
movl 0x8(%rax), %ecx
shrl %ecx
movq 0xa2d7(%rip), %rax      # 0x10f98
movl %ecx, (%rax)
callq 0x5520
andl $0x0, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, %ecx
movabsq $0x200000000, %rax      # imm = 0x200000000
shlq %cl, %rax
movq %rax, %rcx
movq 0xa2be(%rip), %rax      # 0x10fa8
movq %rcx, (%rax)
movq 0xa2b4(%rip), %rax      # 0x10fa8
cmpq $0x80000, (%rax)        # imm = 0x80000
jbe 0x6d07
movq $0x80000, -0x20(%rbp)   # imm = 0x80000
jmp 0x6d15
movq 0xa29a(%rip), %rax      # 0x10fa8
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x110(%rbp), %rax
movq -0x20(%rbp), %rcx
bsrq %rcx, %rcx
xorq $0x3f, %rcx
movslq %ecx, %rdx
movl $0x40, %ecx
subq %rdx, %rcx
subq $0x1, %rcx
subl $0x4, %ecx
addl $0x1, %ecx
movl %ecx, 0x30(%rax)
cmpl $0x10, 0x30(%rax)
jbe 0x6d54
movq -0x110(%rbp), %rax
movl $0x10, 0x30(%rax)
movq -0x110(%rbp), %rax
movl 0x30(%rax), %ecx
subl $0x1, %ecx
movl %ecx, 0x34(%rax)
movq 0xa23d(%rip), %rax      # 0x10fa8
movq (%rax), %rax
shlq $0x4, %rax
shlq $0x7, %rax
cmpq $0x0, %rax
jbe 0x6d7e
jmp 0x6d9d
leaq 0x58ab(%rip), %rdi      # 0xc630
leaq 0x57d6(%rip), %rsi      # 0xc562
movl $0x2ef, %edx            # imm = 0x2EF
leaq 0x58ac(%rip), %rcx      # 0xc644
callq 0x5300
movq -0x110(%rbp), %rax
movq 0xa1fd(%rip), %rcx      # 0x10fa8
movq (%rcx), %rcx
bsrq %rcx, %rcx
xorq $0x3f, %rcx
movslq %ecx, %rdx
movl $0x40, %ecx
subq %rdx, %rcx
subq $0x1, %rcx
movl %ecx, %ecx
movl %ecx, %edx
movq 0xa198(%rip), %rcx      # 0x10f68
movq %rdx, (%rcx)
movq 0xa1ce(%rip), %rcx      # 0x10fa8
movq (%rcx), %rcx
shlq $0x4, %rcx
bsrq %rcx, %rcx
xorq $0x3f, %rcx
movslq %ecx, %rdx
movl $0x40, %ecx
subq %rdx, %rcx
subq $0x1, %rcx
movl %ecx, 0x38(%rax)
movq 0xa1a6(%rip), %rax      # 0x10fa8
movq (%rax), %rcx
subq $0x1, %rcx
movq 0xa1d8(%rip), %rax      # 0x10fe8
movq %rcx, (%rax)
callq 0x52d0
movq %rax, -0x140(%rbp)
callq 0x5400
movq -0x140(%rbp), %rdi
movq %rax, %rcx
movq 0xa173(%rip), %rax      # 0x10fa8
movq (%rax), %r10
movq 0xa129(%rip), %rax      # 0x10f68
movq (%rax), %rax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x5814(%rip), %rdx      # 0xc662
leaq 0x570d(%rip), %r8       # 0xc562
movl $0x2f6, %r9d            # imm = 0x2F6
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movq $0x80, 0x10(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x138(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x138(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
callq 0x52d0
movq %rax, -0x130(%rbp)
callq 0x5400
movq -0x130(%rbp), %rdi
movq %rax, %rcx
movq -0x110(%rbp), %rax
movl 0x30(%rax), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x57f2(%rip), %rdx      # 0xc6c4
leaq 0x5689(%rip), %r8       # 0xc562
movl $0x2f7, %r9d            # imm = 0x2F7
movl $0x10, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x128(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x128(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
callq 0x52d0
movq %rax, -0x120(%rbp)
callq 0x5400
movq -0x120(%rbp), %rdi
movq %rax, %rcx
movl $0x1000, %esi           # imm = 0x1000
leaq 0x57c5(%rip), %rdx      # 0xc70a
leaq 0x5616(%rip), %r8       # 0xc562
movl $0x2f9, %r9d            # imm = 0x2F9
movq $0x80, (%rsp)
movq $0x80, 0x8(%rsp)
movq $0x40, 0x10(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x118(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x118(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movq 0xa001(%rip), %rax      # 0x10fa8
cmpq $0x80000, (%rax)        # imm = 0x80000
jb 0x6fb2
jmp 0x6fd1
leaq 0x57c2(%rip), %rdi      # 0xc77b
leaq 0x55a2(%rip), %rsi      # 0xc562
movl $0x2fc, %edx            # imm = 0x2FC
leaq 0x5678(%rip), %rcx      # 0xc644
callq 0x5300
movq -0x110(%rbp), %rdi
movq 0x9fc9(%rip), %rax      # 0x10fa8
movq (%rax), %rsi
shlq $0x4, %rsi
shlq $0x7, %rsi
callq 0x5990
movq -0x110(%rbp), %rcx
movq $0x0, -0x38(%rbp)
movl $0x10, %eax
subl 0x30(%rcx), %eax
movl %eax, %eax
movq 0x9f99(%rip), %rcx      # 0x10fa8
imulq (%rcx), %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x14(%rbp)
cmpl $0x80, -0x14(%rbp)
jae 0x708a
movq $0x10, -0x48(%rbp)
movl $0x0, -0x18(%rbp)
movq -0x110(%rbp), %rcx
movl -0x18(%rbp), %eax
cmpl 0x30(%rcx), %eax
jae 0x707d
movq 0x9f5c(%rip), %rax      # 0x10fa8
movq (%rax), %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x48(%rbp)
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x48(%rbp), %rax
shlq %rax
movq %rax, -0x48(%rbp)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x7036
jmp 0x707f
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x701e
movq -0x110(%rbp), %rdi
movl $0x0, 0x48(%rdi)
movq $0xf, 0x40(%rdi)
movq -0x38(%rbp), %rax
movq %rax, -0x50(%rbp)
movl $0x10, -0x54(%rbp)
movq -0x50(%rbp), %rax
movl -0x54(%rbp), %ecx
xorl %edx, %edx
divq %rcx
movq %rax, -0x60(%rbp)
movq -0x50(%rbp), %rsi
callq 0x5210
movq -0x110(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x5510
movq -0x110(%rbp), %rdi
movq -0x50(%rbp), %rax
movl %eax, %esi
callq 0x57d0
movq 0x9e27(%rip), %rax      # 0x10f18
movl 0x8(%rax), %eax
shrl %eax
movq 0x9e1b(%rip), %rcx      # 0x10f18
addl 0x8(%rcx), %eax
movl %eax, %eax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
shlq $0x3, %rax
shlq $0x4, %rax
shlq $0x7, %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x55d0
movq %rax, %rcx
movq -0x110(%rbp), %rax
movq %rcx, -0x78(%rbp)
movq -0x78(%rbp), %rcx
movq %rcx, -0x80(%rbp)
movq (%rax), %rcx
movq %rcx, -0x88(%rbp)
movq 0x10(%rax), %rcx
movq %rcx, -0x90(%rbp)
movq 0x20(%rax), %rax
movq %rax, -0x98(%rbp)
movq $0x0, -0xa0(%rbp)
movq $0x0, -0xa8(%rbp)
movq $0x0, -0xb0(%rbp)
movl $0x0, -0x14(%rbp)
cmpl $0x80, -0x14(%rbp)
jae 0x754c
movq -0x110(%rbp), %rax
addq $0x4c, %rax
movl -0x14(%rbp), %ecx
imulq $0x32, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rdi
movq 0x9da7(%rip), %rax      # 0x10f68
movq (%rax), %rax
movl %eax, %esi
callq 0x5590
movl $0x0, -0x18(%rbp)
movq -0x110(%rbp), %rcx
movl -0x18(%rbp), %eax
cmpl 0x30(%rcx), %eax
jae 0x752c
movq -0xb8(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x5410
movl %eax, -0xbc(%rbp)
movl -0xbc(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %eax
movq %rax, -0xc8(%rbp)
cmpl $0x0, -0x14(%rbp)
jne 0x72a0
callq 0x52d0
movq %rax, -0x150(%rbp)
callq 0x5400
movq -0x150(%rbp), %rdi
movq %rax, %rcx
movl -0x18(%rbp), %r11d
movq -0xc8(%rbp), %r10
movl -0xbc(%rbp), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x5551(%rip), %rdx      # 0xc7a3
leaq 0x5309(%rip), %r8       # 0xc562
movl $0x343, %r9d            # imm = 0x343
movl %r11d, (%rsp)
movq %r10, 0x8(%rsp)
movl %eax, 0x10(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x148(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x148(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movq -0x110(%rbp), %rcx
movq %rcx, %rax
addq $0x1980, %rax           # imm = 0x1980
movl -0x14(%rbp), %edx
shlq $0xb, %rdx
addq %rdx, %rax
movl -0x18(%rbp), %edx
shlq $0x7, %rdx
addq %rdx, %rax
movq %rax, -0xd0(%rbp)
movq %rcx, %rdx
addq $0x41980, %rdx          # imm = 0x41980
movl -0x14(%rbp), %eax
shlq $0xb, %rax
addq %rax, %rdx
movl -0x18(%rbp), %eax
shlq $0x7, %rax
addq %rax, %rdx
movq -0xd0(%rbp), %rax
movq %rdx, (%rax)
addq $0x81980, %rcx          # imm = 0x81980
movl -0x14(%rbp), %eax
shlq $0xa, %rax
addq %rax, %rcx
movl -0x18(%rbp), %eax
shlq $0x6, %rax
addq %rax, %rcx
movq -0xd0(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0xc8(%rbp), %rcx
movq -0xd0(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0xc8(%rbp), %rcx
subq $0x1, %rcx
movq -0xd0(%rbp), %rax
movq %rcx, 0x28(%rax)
movl -0xbc(%rbp), %ecx
movq -0xd0(%rbp), %rax
movl %ecx, 0x30(%rax)
movl -0x18(%rbp), %ecx
movq -0xd0(%rbp), %rax
movl %ecx, 0x14(%rax)
movl -0x14(%rbp), %ecx
movq -0xd0(%rbp), %rax
movl %ecx, 0x18(%rax)
movq 0x9c36(%rip), %rax      # 0x10fa8
movq (%rax), %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0xc8(%rbp)
movq %rax, -0x30(%rbp)
movq -0x88(%rbp), %rax
addq -0xb0(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
movq 0x9c01(%rip), %rcx      # 0x10fa8
addq (%rcx), %rax
movq %rax, -0xe0(%rbp)
movq -0x90(%rbp), %rax
addq -0xa0(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0x98(%rbp), %rax
addq -0xa8(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq $0x0, -0xf8(%rbp)
movq -0x30(%rbp), %rax
movl -0x54(%rbp), %ecx
xorl %edx, %edx
divq %rcx
movq %rax, -0x100(%rbp)
movq -0xe8(%rbp), %rcx
movq -0xd0(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0xd0(%rbp), %rax
movq (%rax), %rdi
movq -0xd8(%rbp), %rsi
movq -0xe0(%rbp), %rdx
movq -0x80(%rbp), %rcx
movq -0xd0(%rbp), %rax
movq 0x8(%rax), %r8
movl -0xbc(%rbp), %r9d
callq 0x5810
cmpq $0x40, -0xc8(%rbp)
jb 0x746c
movq -0xd0(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0xf0(%rbp), %rsi
movq -0x100(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x53b0
jmp 0x74a5
movq -0x110(%rbp), %rcx
movq -0xd0(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0xf0(%rbp), %rsi
movq -0x100(%rbp), %rdx
addq $0xa1980, %rcx          # imm = 0xA1980
movl -0xbc(%rbp), %eax
shlq $0x7, %rax
addq %rax, %rcx
callq 0x53b0
movq -0x68(%rbp), %rax
shlq $0x3, %rax
addq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0xb0(%rbp), %rcx
movq -0xd0(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x30(%rbp), %rax
subq $0x1, %rax
movl %eax, %ecx
movq -0xd0(%rbp), %rax
movl %ecx, 0x10(%rax)
movq 0x9ac6(%rip), %rax      # 0x10fa8
movq (%rax), %rax
addq -0xb0(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x30(%rbp), %rax
addq -0xa0(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x100(%rbp), %rax
shlq $0x3, %rax
addq -0xa8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x71d2
movq -0x40(%rbp), %rax
addq -0xb0(%rbp), %rax
movq %rax, -0xb0(%rbp)
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x718a
movq -0x98(%rbp), %rax
movq -0x60(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x108(%rbp)
movq -0x98(%rbp), %rax
addq -0xa8(%rbp), %rax
cmpq -0x108(%rbp), %rax
ja 0x757e
jmp 0x759d
leaq 0x5265(%rip), %rdi      # 0xc7ea
leaq 0x4fd6(%rip), %rsi      # 0xc562
movl $0x398, %edx            # imm = 0x398
leaq 0x50ac(%rip), %rcx      # 0xc644
callq 0x5300
movq -0x110(%rbp), %rax
movq $0xf, 0x40(%rax)
callq 0x52d0
movq %rax, -0x170(%rbp)
callq 0x5400
movq -0x170(%rbp), %rdi
movq %rax, %rcx
movq -0x110(%rbp), %rax
movq (%rax), %r10
movq 0x8(%rax), %rax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x523d(%rip), %rdx      # 0xc81e
leaq 0x4f7a(%rip), %r8       # 0xc562
movl $0x39d, %r9d            # imm = 0x39D
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x168(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x168(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
callq 0x52d0
movq %rax, -0x160(%rbp)
callq 0x5400
movq -0x160(%rbp), %rdi
movq %rax, %rcx
movq -0x110(%rbp), %rax
movq 0x10(%rax), %rbx
movq 0x18(%rax), %r11
movq 0x20(%rax), %r10
movq 0x28(%rax), %rax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x51f1(%rip), %rdx      # 0xc85a
leaq 0x4ef2(%rip), %r8       # 0xc562
movl $0x39f, %r9d            # imm = 0x39F
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x158(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x158(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movq -0x110(%rbp), %rax
movq (%rax), %rax
addq $0x188, %rsp            # imm = 0x188
popq %rbx
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)