// File: VanAndelInstitute[P]intent/src/edlib.cpp
// Function: myersCalcEditDistanceSemiGlobal(unsigned long const*, int, int, int, unsigned char const*, int, int, EdlibAlignMode, int*, int**, int*)
static int myersCalcEditDistanceSemiGlobal(
        const Word* const Peq, const int W, const int maxNumBlocks,
        const int queryLength,
        const unsigned char* const target, const int targetLength,
        int k, const EdlibAlignMode mode,
        int* const bestScore_, int** const positions_, int* const numPositions_) {
    *positions_ = NULL;
    *numPositions_ = 0;

    // firstBlock is 0-based index of first block in Ukkonen band.
    // lastBlock is 0-based index of last block in Ukkonen band.
    int firstBlock = 0;
    int lastBlock = min(ceilDiv(k + 1, WORD_SIZE), maxNumBlocks) - 1; // y in Myers
    Block *bl; // Current block

    Block* blocks = new Block[maxNumBlocks];

    // For HW, solution will never be larger then queryLength.
    if (mode == EDLIB_MODE_HW) {
        k = min(queryLength, k);
    }

    // Each STRONG_REDUCE_NUM column is reduced in more expensive way.
    // This gives speed up of about 2 times for small k.
    const int STRONG_REDUCE_NUM = 2048;

    // Initialize P, M and score
    bl = blocks;
    for (int b = 0; b <= lastBlock; b++) {
        bl->score = (b + 1) * WORD_SIZE;
        bl->P = static_cast<Word>(-1); // All 1s
        bl->M = static_cast<Word>(0);
        bl++;
    }

    int bestScore = -1;
    vector<int> positions; // TODO: Maybe put this on heap?
    const int startHout = mode == EDLIB_MODE_HW ? 0 : 1; // If 0 then gap before query is not penalized;
    const unsigned char* targetChar = target;
    for (int c = 0; c < targetLength; c++) { // for each column
        const Word* Peq_c = Peq + (*targetChar) * maxNumBlocks;

        //----------------------- Calculate column -------------------------//
        int hout = startHout;
        bl = blocks + firstBlock;
        Peq_c += firstBlock;
        for (int b = firstBlock; b <= lastBlock; b++) {
            hout = calculateBlock(bl->P, bl->M, *Peq_c, hout, bl->P, bl->M);
            bl->score += hout;
            bl++; Peq_c++;
        }
        bl--; Peq_c--;
        //------------------------------------------------------------------//

        //---------- Adjust number of blocks according to Ukkonen ----------//
        if ((lastBlock < maxNumBlocks - 1) && (bl->score - hout <= k) // bl is pointing to last block
            && ((*(Peq_c + 1) & WORD_1) || hout < 0)) { // Peq_c is pointing to last block
            // If score of left block is not too big, calculate one more block
            lastBlock++; bl++; Peq_c++;
            bl->P = static_cast<Word>(-1); // All 1s
            bl->M = static_cast<Word>(0);
            bl->score = (bl - 1)->score - hout + WORD_SIZE + calculateBlock(bl->P, bl->M, *Peq_c, hout, bl->P, bl->M);
        } else {
            while (lastBlock >= firstBlock && bl->score >= k + WORD_SIZE) {
                lastBlock--; bl--; Peq_c--;
            }
        }

        // Every some columns, do some expensive but also more efficient block reducing.
        // This is important!
        //
        // Reduce the band by decreasing last block if possible.
        if (c % STRONG_REDUCE_NUM == 0) {
            while (lastBlock >= 0 && lastBlock >= firstBlock && allBlockCellsLarger(*bl, k)) {
                lastBlock--; bl--; Peq_c--;
            }
        }
        // For HW, even if all cells are > k, there still may be solution in next
        // column because starting conditions at upper boundary are 0.
        // That means that first block is always candidate for solution,
        // and we can never end calculation before last column.
        if (mode == EDLIB_MODE_HW && lastBlock == -1) {
            lastBlock++; bl++; Peq_c++;
        }

        // Reduce band by increasing first block if possible. Not applicable to HW.
        if (mode != EDLIB_MODE_HW) {
            while (firstBlock <= lastBlock && blocks[firstBlock].score >= k + WORD_SIZE) {
                firstBlock++;
            }
            if (c % STRONG_REDUCE_NUM == 0) { // Do strong reduction every some blocks
                while (firstBlock <= lastBlock && allBlockCellsLarger(blocks[firstBlock], k)) {
                    firstBlock++;
                }
            }
        }

        // If band stops to exist finish
        if (lastBlock < firstBlock) {
            *bestScore_ = bestScore;
            if (bestScore != -1) {
                *positions_ = static_cast<int *>(malloc(sizeof(int) * static_cast<int>(positions.size())));
                *numPositions_ = static_cast<int>(positions.size());
                copy(positions.begin(), positions.end(), *positions_);
            }
            delete[] blocks;
            return EDLIB_STATUS_OK;
        }
        //------------------------------------------------------------------//

        //------------------------- Update best score ----------------------//
        if (lastBlock == maxNumBlocks - 1) {
            int colScore = bl->score;
            if (colScore <= k) { // Scores > k dont have correct values (so we cannot use them), but are certainly > k.
                // NOTE: Score that I find in column c is actually score from column c-W
                if (bestScore == -1 || colScore <= bestScore) {
                    if (colScore != bestScore) {
                        positions.clear();
                        bestScore = colScore;
                        // Change k so we will look only for equal or better
                        // scores then the best found so far.
                        k = bestScore;
                    }
                    positions.push_back(c - W);
                }
            }
        }
        //------------------------------------------------------------------//

        targetChar++;
    }


    // Obtain results for last W columns from last column.
    if (lastBlock == maxNumBlocks - 1) {
        vector<int> blockScores = getBlockCellValues(*bl);
        for (int i = 0; i < W; i++) {
            int colScore = blockScores[i + 1];
            if (colScore <= k && (bestScore == -1 || colScore <= bestScore)) {
                if (colScore != bestScore) {
                    positions.clear();
                    k = bestScore = colScore;
                }
                positions.push_back(targetLength - W + i);
            }
        }
    }

    *bestScore_ = bestScore;
    if (bestScore != -1) {
        *positions_ = static_cast<int *>(malloc(sizeof(int) * static_cast<int>(positions.size())));
        *numPositions_ = static_cast<int>(positions.size());
        copy(positions.begin(), positions.end(), *positions_);
    }

    delete[] blocks;
    return EDLIB_STATUS_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1d0, %rsp            # imm = 0x1D0
movq 0x30(%rbp), %rax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movl 0x18(%rbp), %eax
movl 0x10(%rbp), %eax
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
movq 0x28(%rbp), %rax
movq $0x0, (%rax)
movq 0x30(%rbp), %rax
movl $0x0, (%rax)
movl $0x0, -0x30(%rbp)
movl 0x10(%rbp), %edi
addl $0x1, %edi
movl $0x40, %esi
callq 0x655f0
movl %eax, %edi
movl -0x18(%rbp), %esi
callq 0x67490
subl $0x1, %eax
movl %eax, -0x34(%rbp)
movslq -0x18(%rbp), %rax
movq %rax, -0x160(%rbp)
movl $0x18, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, -0x168(%rbp)
callq 0x8040
movq %rax, %rcx
movq -0x160(%rbp), %rax
movq %rcx, -0x158(%rbp)
cmpq $0x0, %rax
je 0x658c1
movq -0x158(%rbp), %rax
movq -0x160(%rbp), %rcx
imulq $0x18, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, -0x178(%rbp)
movq %rax, -0x170(%rbp)
movq -0x170(%rbp), %rdi
movq %rdi, -0x180(%rbp)
callq 0x69000
jmp 0x658a3
movq -0x178(%rbp), %rcx
movq -0x180(%rbp), %rax
addq $0x18, %rax
cmpq %rcx, %rax
movq %rax, -0x170(%rbp)
jne 0x6588e
movq -0x158(%rbp), %rax
movq %rax, -0x48(%rbp)
cmpl $0x2, 0x18(%rbp)
jne 0x65906
movl -0x1c(%rbp), %edi
movl 0x10(%rbp), %esi
callq 0x67490
movl %eax, 0x10(%rbp)
jmp 0x65906
movq -0x168(%rbp), %rsi
movq -0x158(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
callq 0x8a20
jmp 0x66164
movl $0x800, -0x58(%rbp)     # imm = 0x800
movq -0x48(%rbp), %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jg 0x65962
movl -0x5c(%rbp), %ecx
addl $0x1, %ecx
shll $0x6, %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq $-0x1, (%rax)
movq -0x40(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x40(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x40(%rbp)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x6591c
movl $0xffffffff, -0x60(%rbp) # imm = 0xFFFFFFFF
leaq -0x78(%rbp), %rdi
callq 0x36740
movl 0x18(%rbp), %edx
movl $0x1, %eax
xorl %ecx, %ecx
cmpl $0x2, %edx
cmovel %ecx, %eax
movl %eax, -0x7c(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x88(%rbp)
movl $0x0, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x65f5d
movq -0x10(%rbp), %rax
movq -0x88(%rbp), %rcx
movzbl (%rcx), %ecx
imull -0x18(%rbp), %ecx
movslq %ecx, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x98(%rbp)
movl -0x7c(%rbp), %eax
movl %eax, -0x9c(%rbp)
movq -0x48(%rbp), %rax
movslq -0x30(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movl -0x30(%rbp), %ecx
movq -0x98(%rbp), %rax
movslq %ecx, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x98(%rbp)
movl -0x30(%rbp), %eax
movl %eax, -0xa0(%rbp)
movl -0xa0(%rbp), %eax
cmpl -0x34(%rbp), %eax
jg 0x65aa9
movq -0x40(%rbp), %r8
movq %r8, %r9
addq $0x8, %r9
movq (%r8), %rdi
movq 0x8(%r8), %rsi
movq -0x98(%rbp), %rax
movq (%rax), %rdx
movl -0x9c(%rbp), %ecx
callq 0x674c0
movl %eax, -0x184(%rbp)
jmp 0x65a4a
movl -0x184(%rbp), %eax
movl %eax, -0x9c(%rbp)
movl -0x9c(%rbp), %ecx
movq -0x40(%rbp), %rax
addl 0x10(%rax), %ecx
movl %ecx, 0x10(%rax)
movq -0x40(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x40(%rbp)
movq -0x98(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x98(%rbp)
movl -0xa0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa0(%rbp)
jmp 0x65a0c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x6615b
movq -0x40(%rbp), %rax
addq $-0x18, %rax
movq %rax, -0x40(%rbp)
movq -0x98(%rbp), %rax
addq $-0x8, %rax
movq %rax, -0x98(%rbp)
movl -0x34(%rbp), %eax
movl -0x18(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x65ba2
movq -0x40(%rbp), %rax
movl 0x10(%rax), %eax
subl -0x9c(%rbp), %eax
cmpl 0x10(%rbp), %eax
jg 0x65ba2
movq -0x98(%rbp), %rax
movq 0x8(%rax), %rax
andq $0x1, %rax
cmpq $0x0, %rax
jne 0x65b10
cmpl $0x0, -0x9c(%rbp)
jge 0x65ba2
movl -0x34(%rbp), %eax
incl %eax
movl %eax, -0x34(%rbp)
movq -0x40(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x40(%rbp)
movq -0x98(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x98(%rbp)
movq -0x40(%rbp), %rax
movq $-0x1, (%rax)
movq -0x40(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x40(%rbp), %r8
movl -0x8(%r8), %eax
movl -0x9c(%rbp), %ecx
subl %ecx, %eax
addl $0x40, %eax
movl %eax, -0x18c(%rbp)
movq (%r8), %rdi
movq %r8, %r9
addq $0x8, %r9
movq 0x8(%r8), %rsi
movq -0x98(%rbp), %rax
movq (%rax), %rdx
callq 0x674c0
movl %eax, -0x188(%rbp)
jmp 0x65b8b
movl -0x188(%rbp), %eax
movl -0x18c(%rbp), %ecx
addl %eax, %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0x10(%rax)
jmp 0x65c03
jmp 0x65ba4
movl -0x34(%rbp), %ecx
xorl %eax, %eax
cmpl -0x30(%rbp), %ecx
movb %al, -0x18d(%rbp)
jl 0x65bcc
movq -0x40(%rbp), %rax
movl 0x10(%rax), %eax
movl 0x10(%rbp), %ecx
addl $0x40, %ecx
cmpl %ecx, %eax
setge %al
movb %al, -0x18d(%rbp)
movb -0x18d(%rbp), %al
testb $0x1, %al
jne 0x65bd8
jmp 0x65c01
movl -0x34(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x34(%rbp)
movq -0x40(%rbp), %rax
addq $-0x18, %rax
movq %rax, -0x40(%rbp)
movq -0x98(%rbp), %rax
addq $-0x8, %rax
movq %rax, -0x98(%rbp)
jmp 0x65ba4
jmp 0x65c03
movl -0x8c(%rbp), %eax
movl $0x800, %ecx            # imm = 0x800
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x65cc3
jmp 0x65c1c
xorl %eax, %eax
cmpl $0x0, -0x34(%rbp)
movb %al, -0x18e(%rbp)
jl 0x65c89
movl -0x34(%rbp), %ecx
xorl %eax, %eax
cmpl -0x30(%rbp), %ecx
movb %al, -0x18e(%rbp)
jl 0x65c89
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rcx
movq %rcx, -0xb0(%rbp)
movups (%rax), %xmm0
movaps %xmm0, -0xc0(%rbp)
movl 0x10(%rbp), %edi
movq -0xb0(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movaps -0xc0(%rbp), %xmm0
movups %xmm0, (%rax)
callq 0x675e0
movb %al, -0x18f(%rbp)
jmp 0x65c7b
movb -0x18f(%rbp), %al
movb %al, -0x18e(%rbp)
jmp 0x65c89
movb -0x18e(%rbp), %al
testb $0x1, %al
jne 0x65c95
jmp 0x65cc1
movl -0x34(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x34(%rbp)
movq -0x40(%rbp), %rax
addq $-0x18, %rax
movq %rax, -0x40(%rbp)
movq -0x98(%rbp), %rax
addq $-0x8, %rax
movq %rax, -0x98(%rbp)
jmp 0x65c1c
jmp 0x65cc3
cmpl $0x2, 0x18(%rbp)
jne 0x65cf6
cmpl $-0x1, -0x34(%rbp)
jne 0x65cf6
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
movq -0x40(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x40(%rbp)
movq -0x98(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x98(%rbp)
cmpl $0x2, 0x18(%rbp)
je 0x65de9
jmp 0x65d02
movl -0x30(%rbp), %ecx
xorl %eax, %eax
cmpl -0x34(%rbp), %ecx
movb %al, -0x190(%rbp)
jg 0x65d35
movq -0x48(%rbp), %rax
movslq -0x30(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movl 0x10(%rax), %eax
movl 0x10(%rbp), %ecx
addl $0x40, %ecx
cmpl %ecx, %eax
setge %al
movb %al, -0x190(%rbp)
movb -0x190(%rbp), %al
testb $0x1, %al
jne 0x65d41
jmp 0x65d4c
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x65d02
movl -0x8c(%rbp), %eax
movl $0x800, %ecx            # imm = 0x800
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x65de7
jmp 0x65d65
movl -0x30(%rbp), %ecx
xorl %eax, %eax
cmpl -0x34(%rbp), %ecx
movb %al, -0x191(%rbp)
jg 0x65dce
movq -0x48(%rbp), %rax
movslq -0x30(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
movq 0x10(%rax,%rcx,8), %rdx
movq %rdx, -0xd0(%rbp)
movups (%rax,%rcx,8), %xmm0
movaps %xmm0, -0xe0(%rbp)
movl 0x10(%rbp), %edi
movq -0xd0(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movaps -0xe0(%rbp), %xmm0
movups %xmm0, (%rax)
callq 0x675e0
movb %al, -0x192(%rbp)
jmp 0x65dc0
movb -0x192(%rbp), %al
movb %al, -0x191(%rbp)
jmp 0x65dce
movb -0x191(%rbp), %al
testb $0x1, %al
jne 0x65dda
jmp 0x65de5
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x65d65
jmp 0x65de7
jmp 0x65de9
movl -0x34(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x65eb5
movl -0x60(%rbp), %ecx
movq 0x20(%rbp), %rax
movl %ecx, (%rax)
cmpl $-0x1, -0x60(%rbp)
je 0x65e82
leaq -0x78(%rbp), %rdi
movq %rdi, -0x1a0(%rbp)
callq 0x69010
movslq %eax, %rdi
shlq $0x2, %rdi
callq 0x8770
movq -0x1a0(%rbp), %rdi
movq %rax, %rcx
movq 0x28(%rbp), %rax
movq %rcx, (%rax)
callq 0x69010
movq -0x1a0(%rbp), %rdi
movl %eax, %ecx
movq 0x30(%rbp), %rax
movl %ecx, (%rax)
callq 0x69090
movq -0x1a0(%rbp), %rdi
movq %rax, -0xe8(%rbp)
callq 0x690c0
movq %rax, -0xf0(%rbp)
movq 0x28(%rbp), %rax
movq (%rax), %rdx
movq -0xe8(%rbp), %rdi
movq -0xf0(%rbp), %rsi
callq 0x69030
jmp 0x65e80
jmp 0x65e82
movq -0x48(%rbp), %rax
movq %rax, -0x1a8(%rbp)
cmpq $0x0, %rax
je 0x65e9f
movq -0x1a8(%rbp), %rdi
callq 0x8710
movl $0x0, -0x4(%rbp)
movl $0x1, -0xf4(%rbp)
jmp 0x66146
movl -0x34(%rbp), %eax
movl -0x18(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x65f37
movq -0x40(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0xf8(%rbp)
movl -0xf8(%rbp), %eax
cmpl 0x10(%rbp), %eax
jg 0x65f35
cmpl $-0x1, -0x60(%rbp)
je 0x65eeb
movl -0xf8(%rbp), %eax
cmpl -0x60(%rbp), %eax
jg 0x65f33
movl -0xf8(%rbp), %eax
cmpl -0x60(%rbp), %eax
je 0x65f0e
leaq -0x78(%rbp), %rdi
callq 0x690f0
movl -0xf8(%rbp), %eax
movl %eax, -0x60(%rbp)
movl -0x60(%rbp), %eax
movl %eax, 0x10(%rbp)
movl -0x8c(%rbp), %eax
movl -0x14(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0xfc(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0xfc(%rbp), %rsi
callq 0x69110
jmp 0x65f31
jmp 0x65f33
jmp 0x65f35
jmp 0x65f37
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x6599a
movl -0x34(%rbp), %eax
movl -0x18(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x6608b
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rcx
movq %rcx, -0x120(%rbp)
movups (%rax), %xmm0
movaps %xmm0, -0x130(%rbp)
movq -0x120(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movaps -0x130(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0x118(%rbp), %rdi
callq 0x67690
jmp 0x65fad
movl $0x0, -0x134(%rbp)
movl -0x134(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x6607f
movl -0x134(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
leaq -0x118(%rbp), %rdi
callq 0x69140
movl (%rax), %eax
movl %eax, -0x138(%rbp)
movl -0x138(%rbp), %eax
cmpl 0x10(%rbp), %eax
jg 0x66069
cmpl $-0x1, -0x60(%rbp)
je 0x66002
movl -0x138(%rbp), %eax
cmpl -0x60(%rbp), %eax
jg 0x66069
movl -0x138(%rbp), %eax
cmpl -0x60(%rbp), %eax
je 0x66022
leaq -0x78(%rbp), %rdi
callq 0x690f0
movl -0x138(%rbp), %eax
movl %eax, -0x60(%rbp)
movl %eax, 0x10(%rbp)
movl -0x2c(%rbp), %eax
movl -0x14(%rbp), %ecx
subl %ecx, %eax
movl -0x134(%rbp), %ecx
addl %ecx, %eax
movl %eax, -0x13c(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0x13c(%rbp), %rsi
callq 0x69110
jmp 0x6604a
jmp 0x66069
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x36b20
jmp 0x6615b
jmp 0x6606b
movl -0x134(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x134(%rbp)
jmp 0x65fb7
leaq -0x118(%rbp), %rdi
callq 0x36b20
movl -0x60(%rbp), %ecx
movq 0x20(%rbp), %rax
movl %ecx, (%rax)
cmpl $-0x1, -0x60(%rbp)
je 0x66118
leaq -0x78(%rbp), %rdi
movq %rdi, -0x1b0(%rbp)
callq 0x69010
movslq %eax, %rdi
shlq $0x2, %rdi
callq 0x8770
movq -0x1b0(%rbp), %rdi
movq %rax, %rcx
movq 0x28(%rbp), %rax
movq %rcx, (%rax)
callq 0x69010
movq -0x1b0(%rbp), %rdi
movl %eax, %ecx
movq 0x30(%rbp), %rax
movl %ecx, (%rax)
callq 0x69090
movq -0x1b0(%rbp), %rdi
movq %rax, -0x148(%rbp)
callq 0x690c0
movq %rax, -0x150(%rbp)
movq 0x28(%rbp), %rax
movq (%rax), %rdx
movq -0x148(%rbp), %rdi
movq -0x150(%rbp), %rsi
callq 0x69030
jmp 0x66116
jmp 0x66118
movq -0x48(%rbp), %rax
movq %rax, -0x1b8(%rbp)
cmpq $0x0, %rax
je 0x66135
movq -0x1b8(%rbp), %rdi
callq 0x8710
movl $0x0, -0x4(%rbp)
movl $0x1, -0xf4(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x36b20
movl -0x4(%rbp), %eax
addq $0x1d0, %rsp            # imm = 0x1D0
popq %rbp
retq
leaq -0x78(%rbp), %rdi
callq 0x36b20
movq -0x50(%rbp), %rdi
callq 0x8970
nopl (%rax)