// File: /workspace/github_c_makefile_star2_O3/icebert[P]pblat/jkOwnLib/bandExt.c
// Function: bandExt
boolean bandExt(boolean global, struct axtScoreScheme *ss, int maxInsert,
	char *aStart, int aSize, char *bStart, int bSize, int dir,
	int symAlloc, int *retSymCount, char *retSymA, char *retSymB, 
	int *retStartA, int *retStartB)
/* Try to extend an alignment from aStart/bStart onwards.
 * Set maxInsert to the maximum gap size allowed.  3 is often
 * a good choice.  aStart/aSize bStart/bSize describe the
 * sequence to extend through (not including any of the existing
 * alignment. Set dir = 1 for forward extension, dir = -1 for backwards. 
 * retSymA and retSymB should point to arrays of characters of
 * symAlloc size.  symAlloc needs to be aSize*2 or so.  The
 * alignment is returned in the various ret values.  The function
 * overall returns TRUE if an extension occurred, FALSE if not. */
{
int i;			/* A humble index or two. */
int *bOffsets = NULL;	/* Offset of top of band. */
UBYTE **parents = NULL;	/* Array of parent positions. */
struct score *curScores = NULL;	/* Scores for current column. */
struct score *prevScores = NULL;	/* Scores for previous column. */
struct score *swapScores;	/* Helps to swap cur & prev column. */
int bandSize = 2*maxInsert + 1;	 /* Size of band including middle */
int maxIns1 = maxInsert + 1;   	 /* Max insert plus one. */
int bandPlus = bandSize + 2*maxIns1;  /* Band plus sentinels on either end. */
int bestScore = 0;	 	 /* Best score so far. */
int aPos, aBestPos = -1;	 /* Current and best position in a. */
int bPos, bBestPos = -1;	 /* Current and best position in b. */
int bandCenter = 0;	/* b Coordinate of current band center. */
int colShift = 1;	/* Vertical shift between this column and previous. */
int prevScoreOffset;	/* Offset into previous score column. */
int curScoreOffset;	/* Offset into current score column. */
int symCount = 0;	/* Size of alignment and size allocated for it. */
int gapOpen = ss->gapOpen;	 /* First base in gap costs this. */
int gapExtend = ss->gapExtend;	 /* Extra bases in gap cost this. */
int badScore = -gapOpen*100;	 /* A score bad enough no one will want to link with us. */
int maxDrop = gapOpen + gapExtend*maxInsert; /* Max score drop allowed before giving up. */
int midScoreOff;		 /* Offset to middle of scoring array. */
struct lm *lm;			 /* Local memory pool. */
boolean didExt = FALSE;
int initGapScore = -gapOpen;

/* For reverse direction just reverse bytes here and there.  It's
 * a lot easier than the alternative and doesn't cost much time in
 * the global scheme of things. */
if (dir < 0)
    {
    reverseBytes(aStart, aSize);
    reverseBytes(bStart, bSize);
    }
#ifdef DEBUG
uglyf("bandExt: dir %d, aStart %d, aSize %d, symAlloc %d\n", dir,
	aSize, bSize, symAlloc);
mustWrite(uglyOut, aStart, aSize);
uglyf("\n");
mustWrite(uglyOut, bStart, bSize);
uglyf("\n");
#endif /* DEBUG */

/* Make up a local mem structure big enough for everything. 
 * This is just a minor, perhaps misguided speed tweak to
 * avoid multiple mallocs. */
lm = lmInit(
    sizeof(bOffsets[0])*aSize +
    sizeof(parents[0])*bandSize +
    bandSize*(sizeof(parents[0][0])*aSize) +
    sizeof(curScores[0]) * bandPlus +
    sizeof(prevScores[0]) * bandPlus );

/* Allocate data structures out of local memory pool. */
lmAllocArray(lm, bOffsets, aSize);
lmAllocArray(lm, parents, bandSize);
for (i=0; i<bandSize; ++i)
    lmAllocArray(lm, parents[i], aSize);
lmAllocArray(lm, curScores, bandPlus);
lmAllocArray(lm, prevScores, bandPlus);

/* Set up scoring arrays so that stuff outside of the band boundary 
 * looks bad.  There will be maxIns+1 of these sentinel values at
 * the start and at the beginning. */
for (i=0; i<bandPlus; ++i)
    {
    struct score *cs = &curScores[i];
    cs->match = cs->up = cs->left = badScore;
    cs = &prevScores[i];
    cs->match = cs->up = cs->left = badScore;
    }

/* Set up scoring array so that extending without an initial insert
 * looks relatively good. */
midScoreOff = 1 + 2 * maxInsert;
prevScores[midScoreOff].match = 0;

/* Set up scoring array so that initial inserts of up to maxInsert
 * are allowed but penalized appropriately. */
    {
    int score = -gapOpen;
    for (i=0; i<maxInsert; ++i)
	{
	prevScores[midScoreOff+i].up = score;
	score -= gapExtend;
	}
    }

for (aPos=0; aPos < aSize; ++aPos)
    {
    char aBase = aStart[aPos];
    int *matRow = ss->matrix[(int)aBase];
    int bestColScore = badScore;
    int bestColPos = -1;
    int colTop = bandCenter - maxInsert;
    int colBottom = bandCenter + maxIns1;

    if (colTop < 0) colTop = 0;
    if (colBottom > bSize) colBottom = bSize;
    curScoreOffset =  maxIns1 + colTop - (bandCenter - maxInsert);
    prevScoreOffset = curScoreOffset + colShift;
#ifdef DEBUG
    uglyf("curScoreOffset %d, maxIns %d, prevScoreOffset %d\n", curScoreOffset, maxInsert, prevScoreOffset);
#endif /* DEBUG */

    /* At top we deal with possibility of initial insert that
     * comes in at this point, unless the band has wandered off. */
    if (aPos < maxInsert)
	{
	curScores[curScoreOffset-1].up = initGapScore;
	initGapScore -= gapExtend;
	}
    else
	curScores[curScoreOffset-1].up = badScore;

    for (bPos = colTop; bPos < colBottom; ++bPos)
	{
	UBYTE parent;
	struct score *curScore = &curScores[curScoreOffset];

#ifdef DEBUG
	uglyf("aPos %d, bPos %d, %c vs %c\n", aPos, bPos, aBase, bStart[bPos]);
	uglyf("  diag[%d %d %d], left[%d %d %d], up[%d %d %d]\n", 
		prevScores[prevScoreOffset-1].match, 
		prevScores[prevScoreOffset-1].left, 
		prevScores[prevScoreOffset-1].up, 
		prevScores[prevScoreOffset].match, 
		prevScores[prevScoreOffset].left, 
		prevScores[prevScoreOffset].up, 
		curScores[curScoreOffset-1].match, 
		curScores[curScoreOffset-1].left, 
		curScores[curScoreOffset-1].up);
#endif /* DEBUG */

	/* Handle ways into the matching state and record if it's
	 * best score so far. */
	    {
	    int match = matRow[(int)bStart[bPos]];
	    struct score *a = &prevScores[prevScoreOffset-1];
	    int diagScore = a->match;
	    int leftScore = a->left;
	    int upScore = a->up;
	    int score;
	    if (diagScore >= leftScore && diagScore >= upScore)
	        {
		score = diagScore + match;
		parent = mpMatch;
		}
	    else if (leftScore > upScore)
	        {
		score = leftScore + match;
	        parent = mpLeft;
		}
	    else
	        {
	        score = upScore + match;
	        parent = mpUp;
	        }
	    curScore->match = score;
	    if (score > bestColScore)
	        {
		bestColScore = score;
		bestColPos = bPos;
		}
	    }

	/* Handle ways into left gap state. */
	    {
	    struct score *a = &prevScores[prevScoreOffset];
	    int extScore = a->left - gapExtend;
	    int openScore = a->match - gapOpen;
	    if (extScore >= openScore)
	        {
		parent |= lpExt;
		curScore->left = extScore;
		}
	    else
	        {
		curScore->left = openScore;
		}
	    }

	/* Handle ways into up gap state. */
	    {
	    struct score *a = &curScore[-1];
	    int extScore = a->up - gapExtend;
	    int openScore = a->match - gapOpen;
	    if (extScore >= openScore)
	        {
		parent |= upExt;
		curScore->up = extScore;
		}
	    else
	        {
		curScore->up = openScore;
		}
	    }

	parents[curScoreOffset - maxIns1][aPos] = parent;

#ifdef DEBUG
	uglyf(" cur [%d %d %d]\n", 
		curScore->match, 
		curScore->left, 
		curScore->up);
#endif /* DEBUG */
	/* Advance to next row in column. */
	curScoreOffset += 1;
	prevScoreOffset += 1;
	}


    /* If this column's score is best so far make note of
     * it and shift things so that the matching bases at the
     * best score are centered in the band.  This allows the
     * band to wander where appropriate.  Having the band shift
     * to the best column position if it is not the best score
     * so far doesn't work so well though.  */
    if (bestScore < bestColScore)
	{
	bestScore = bestColScore;
	aBestPos = aPos;
	bBestPos = bestColPos;
	colShift = (bestColPos + 1) - bandCenter;
	}
    else if (bestColScore < bestScore - maxDrop)
	{
	if (!global)
	    break;
	}
    else
	{
	colShift = 1;
	}

    /* Keep track of vertical offset of this column, and
     * set up offset of next column. */
    bOffsets[aPos] = bandCenter;
    bandCenter += colShift;

    /* Swap scoring arrays so current becomes next iteration's previous. */
    swapScores = curScores;
    curScores = prevScores;
    prevScores = swapScores;
    }


/* Trace back. */
#ifdef DEBUG
uglyf("traceback: bestScore %d, aBestPos %d, bBestPos %d\n", bestScore, aBestPos, bBestPos);
#endif /* DEBUG */
if (global || bestScore > 0)
    {
    boolean upState = FALSE;
    boolean leftState = FALSE;
    didExt = TRUE;
    if (global)
        {
	aPos = aSize-1;
	bPos = bSize-1;
	}
    else
	{
	aPos = aBestPos;
	bPos = bBestPos;
	}
    for (;;)
	{
	int pOffset;
	UBYTE parent;
	pOffset = bPos - bOffsets[aPos] + maxInsert;
	if (pOffset < 0) pOffset = 0;
	// FIXME: there may be some cases near beginning where
	// pOffset is not right.  Clamping it at 0 prevents a crash
	// and produces correct behavior in many cases.  However
	// I'm thinking a better fix would be to have bOffsets follow
	// colTop rather than bandCenter somehow. Exactly how is
	// beyond me at the moment.
	if (pOffset >= bandSize)
	    {
#ifdef DEBUG
	    uglyf("bPos %d, aPos %d, bOffsets[aPos] %d, maxInsert %d\n", bPos, aPos, bOffsets[aPos], maxInsert);
	    uglyf("pOffset = %d, bandSize = %d\n", pOffset, bandSize);
	    uglyf("aSize %d, bSize %d\n", aSize, bSize);
	    faWriteNext(uglyOut, "uglyA", aStart, aSize);
	    faWriteNext(uglyOut, "uglyB", bStart, bSize);
#endif /* DEBUG */
	    assert(global);
	    return FALSE;
	    }
	parent = parents[pOffset][aPos];
#ifdef DEBUG
	uglyf("aPos %d, bPos %d, parent %d, pMask %d upState %d, leftState %d\n", aPos, bPos, parent, parent & mpMask, upState, leftState);
#endif /* DEBUG */
	if (upState)
	    {
	    retSymA[symCount] = '-';
	    retSymB[symCount] = bStart[bPos];
	    bPos -= 1;
	    upState = (parent&upExt);
	    }
	else if (leftState)
	    {
	    retSymA[symCount] = aStart[aPos];
	    retSymB[symCount] = '-';
	    aPos -= 1;
	    leftState = (parent&lpExt);
	    }
	else
	    {
	    retSymA[symCount] = aStart[aPos];
	    retSymB[symCount] = bStart[bPos];
	    aPos -= 1;
	    bPos -= 1;
	    parent &= mpMask;
	    if (parent == mpUp)
	        upState = TRUE;
	    else if (parent == mpLeft)
	        leftState = TRUE;
	    }
	if (++symCount >= symAlloc)
	    errAbort("unsufficient symAlloc in bandExt");
	if (aPos < 0 || bPos < 0)
	    {
	    while (aPos >= 0)
		{
		retSymA[symCount] = aStart[aPos];
		retSymB[symCount] = '-';
		if (++symCount >= symAlloc)
		    errAbort("unsufficient symAlloc in bandExt");
		--aPos;
		}
	    while (bPos >= 0)
		{
		retSymA[symCount] = '-';
		retSymB[symCount] = bStart[bPos];
		if (++symCount >= symAlloc)
		    errAbort("unsufficient symAlloc in bandExt");
		--bPos;
		}
	    break;
	    }
	}
    if (dir > 0)
	{
	reverseBytes(retSymA, symCount);
	reverseBytes(retSymB, symCount);
	}
    retSymA[symCount] = 0;
    retSymB[symCount] = 0;
    }
else
    {
    retSymA[0] = retSymB[0] = 0;
    }

if (dir < 0)
    {
    reverseBytes(aStart, aSize);
    reverseBytes(bStart, bSize);
    }

/* Clean up, set return values and go home */
lmCleanup(&lm);
if (retStartA != NULL) *retStartA = aBestPos;
if (retStartB != NULL) *retStartB = bBestPos;
*retSymCount = symCount;
return didExt;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %r9, 0x20(%rsp)
movq %rcx, 0x38(%rsp)
movl %edx, %r12d
movl %edi, 0xc(%rsp)
leal 0x1(%r12,%r12), %ebx
leal 0x2(%r12,%r12), %eax
leal 0x1(%rax,%r12,2), %r13d
movl 0x40008(%rsi), %eax
movl %eax, 0x18(%rsp)
movq %rsi, 0x68(%rsp)
movl 0x4000c(%rsi), %eax
movq %rax, 0x58(%rsp)
movslq %r8d, %r14
cmpl $0x0, 0x108(%rsp)
movl %r8d, 0x28(%rsp)
jns 0x1903b
movq 0x38(%rsp), %rdi
movq %r14, %rsi
callq 0x1ffa2
movl 0x100(%rsp), %eax
movslq %eax, %rsi
movq 0x20(%rsp), %rdi
callq 0x1ffa2
movl 0x28(%rsp), %r8d
leal (%r12,%r12), %eax
movl %eax, 0x2c(%rsp)
movq %r14, 0x50(%rsp)
movq 0x50(%rsp), %rax
leaq (,%rax,4), %r15
movslq %ebx, %rdx
leaq (,%rdx,8), %r14
movl %r8d, %ecx
movq %rdx, (%rsp)
imull %edx, %ecx
addl %r14d, %ecx
addl %r15d, %ecx
movl %r13d, 0x30(%rsp)
movslq %r13d, %rax
leaq (,%rax,4), %rdx
leaq (%rdx,%rdx,2), %rbp
leal (%rax,%rax,2), %eax
leal (%rcx,%rax,8), %edi
callq 0x2c220
movq %r12, %rbx
movq %rax, %r12
movq %rax, 0xc0(%rsp)
movq %rax, %rdi
movq %r15, %rsi
movq 0x50(%rsp), %r15
callq 0x2c325
movq %rax, 0x70(%rsp)
movq %r12, %rdi
movq %r14, %rsi
callq 0x2c325
movq %rax, %r13
movq %rbx, 0x48(%rsp)
testl %ebx, %ebx
js 0x190f6
xorl %ebx, %ebx
movl 0x2c(%rsp), %eax
testl %eax, %eax
movl $0x0, %r14d
cmovgl %eax, %r14d
incq %r14
movq %r12, %rdi
movq %r15, %rsi
callq 0x2c325
movq %rax, (%r13,%rbx,8)
incq %rbx
cmpq %rbx, %r14
jne 0x190de
imull $-0x64, 0x18(%rsp), %r14d
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2c325
movq %rax, %r15
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2c325
movq %rax, %rbx
cmpl $0x0, 0x30(%rsp)
movq 0x48(%rsp), %r12
jle 0x1915f
leal (,%r12,4), %eax
leaq (%rax,%rax,2), %rax
leaq 0x24(,%rax,4), %rax
xorl %ecx, %ecx
movl %r14d, 0x8(%r15,%rcx)
movl %r14d, 0x4(%r15,%rcx)
movl %r14d, (%r15,%rcx)
movl %r14d, 0x8(%rbx,%rcx)
movl %r14d, 0x4(%rbx,%rcx)
movl %r14d, (%rbx,%rcx)
addq $0xc, %rcx
cmpq %rcx, %rax
jne 0x1913a
movq (%rsp), %rax
leaq (%rax,%rax,2), %rax
movl $0x0, (%rbx,%rax,4)
testl %r12d, %r12d
jle 0x192ba
movq 0x58(%rsp), %r10
movl %r10d, %ecx
negl %ecx
movl %r12d, %eax
leal 0x3(%r12), %r8d
decq %rax
movq %rax, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
leal (%rcx,%rcx), %edx
leal (%r10,%r10,2), %esi
negl %esi
movl 0x2c(%rsp), %eax
leaq (%rax,%rax,2), %rax
leaq (%rbx,%rax,4), %rdi
addq $0x34, %rdi
shrl $0x2, %r8d
shlq $0x4, %r8
leaq (%r8,%r8,2), %r8
movl 0x18(%rsp), %eax
movl %eax, %r9d
negl %r9d
leal (,%r10,4), %r10d
movdqa 0x754ab(%rip), %xmm1    # 0x8e680
movdqa 0x754b3(%rip), %xmm2    # 0x8e690
xorl %eax, %eax
movdqa 0x747c9(%rip), %xmm3    # 0x8d9b0
pxor %xmm3, %xmm0
pcmpeqd %xmm4, %xmm4
movdqa 0x754a9(%rip), %xmm5    # 0x8e6a0
movdqa %xmm2, %xmm6
pxor %xmm3, %xmm6
movdqa %xmm6, %xmm7
pcmpgtd %xmm0, %xmm7
pcmpeqd %xmm0, %xmm6
pshufd $0xf5, %xmm6, %xmm8     # xmm8 = xmm6[1,1,3,3]
pand %xmm7, %xmm8
pshufd $0xf5, %xmm7, %xmm6     # xmm6 = xmm7[1,1,3,3]
por %xmm8, %xmm6
movd %xmm6, %r11d
notl %r11d
testb $0x1, %r11b
je 0x19233
movl %r9d, -0x24(%rdi,%rax)
pxor %xmm4, %xmm6
pextrw $0x4, %xmm6, %r11d
testb $0x1, %r11b
je 0x1924c
leal (%rcx,%r9), %r11d
movl %r11d, -0x18(%rdi,%rax)
movdqa %xmm1, %xmm6
pxor %xmm3, %xmm6
movdqa %xmm6, %xmm7
pcmpgtd %xmm0, %xmm7
pcmpeqd %xmm0, %xmm6
pshufd $0xf5, %xmm6, %xmm8     # xmm8 = xmm6[1,1,3,3]
pand %xmm7, %xmm8
pshufd $0xf5, %xmm7, %xmm6     # xmm6 = xmm7[1,1,3,3]
por %xmm8, %xmm6
pxor %xmm4, %xmm6
pextrw $0x0, %xmm6, %r11d
testb $0x1, %r11b
je 0x1928e
leal (%rdx,%r9), %r11d
movl %r11d, -0xc(%rdi,%rax)
pextrw $0x4, %xmm6, %r11d
testb $0x1, %r11b
je 0x192a2
leal (%rsi,%r9), %r11d
movl %r11d, (%rdi,%rax)
paddq %xmm5, %xmm2
paddq %xmm5, %xmm1
addq $0x30, %rax
subl %r10d, %r9d
cmpq %rax, %r8
jne 0x191f7
xorl %edi, %edi
movl 0x28(%rsp), %esi
testl %esi, %esi
movq %r13, 0x98(%rsp)
jle 0x195c3
leal 0x1(%r12), %edx
movl 0x18(%rsp), %r8d
movl %r8d, %eax
negl %eax
movl %eax, 0x44(%rsp)
movq 0x58(%rsp), %rcx
movl %ecx, %eax
imull %r12d, %eax
addq $0x8, 0x68(%rsp)
addl %r8d, %eax
movl %eax, 0x64(%rsp)
movq %rdx, 0xb0(%rsp)
movslq %edx, %rax
movslq %r12d, %rdx
movq %rdx, 0xa8(%rsp)
movl %esi, %edx
movq %rdx, 0xa0(%rsp)
shlq $0x3, %rax
movq %r13, %rdx
movq %rcx, %r13
subq %rax, %rdx
movq %rdx, 0x90(%rsp)
movl $0xffffffff, 0x10(%rsp) # imm = 0xFFFFFFFF
xorl %r10d, %r10d
movl $0xffffffff, 0x14(%rsp) # imm = 0xFFFFFFFF
xorl %edx, %edx
movl $0x1, %ecx
movl %r14d, 0x1c(%rsp)
movq %rcx, 0x78(%rsp)
movq %rbx, 0x88(%rsp)
movl %edx, %esi
subl %r12d, %esi
testl %esi, %esi
movl $0x0, %r9d
cmovgl %esi, %r9d
movq 0xb0(%rsp), %r8
movq %rdx, 0x80(%rsp)
leal (%rdx,%r8), %eax
movl 0x100(%rsp), %edx
cmpl %edx, %eax
cmovgel %edx, %eax
movq 0x38(%rsp), %rdx
movsbq (%rdx,%r10), %rcx
movl %r8d, %edx
subl %esi, %edx
leal (%rdx,%r9), %esi
decl %esi
movslq %esi, %rsi
leaq (%rsi,%rsi,2), %rsi
leaq (%r15,%rsi,4), %rsi
addq $0x4, %rsi
cmpq 0xa8(%rsp), %r10
movq %r15, 0x30(%rsp)
movq %rdi, 0xb8(%rsp)
jge 0x193d7
movl 0x44(%rsp), %edi
movl %edi, (%rsi)
subl %r13d, %edi
movl %edi, 0x44(%rsp)
jmp 0x193da
movl %r14d, (%rsi)
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
cmpl %eax, %r9d
movl 0x18(%rsp), %r15d
jge 0x19524
shlq $0xa, %rcx
addq 0x68(%rsp), %rcx
addl %r9d, %edx
movq 0x78(%rsp), %rsi
leal (%rdx,%rsi), %edi
movl %r9d, %esi
movslq %edi, %rdi
movslq %edx, %r8
movl %eax, %eax
movq %rax, (%rsp)
leaq (%r8,%r8,2), %rax
movq 0x30(%rsp), %rdx
leaq (%rdx,%rax,4), %rdx
movq 0x90(%rsp), %rax
leaq (%rax,%r8,8), %r9
leaq (%rdi,%rdi,2), %rax
movq 0x88(%rsp), %rdi
leaq (%rdi,%rax,4), %rdi
addq $-0xc, %rdi
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
movl $0x8, %eax
movl 0x1c(%rsp), %r14d
movl -0x8(%rdi,%rax), %r11d
movl -0x4(%rdi,%rax), %ebx
movq %r10, %r12
movl (%rdi,%rax), %r10d
cmpl %r10d, %r11d
setl %bpl
cmpl %ebx, %r11d
setl %r13b
orb %bpl, %r13b
cmpl %ebx, %r10d
cmovgl %r10d, %ebx
setg %r10b
orb $0x2, %r10b
testb %r13b, %r13b
movq 0x20(%rsp), %r13
movsbq (%r13,%rsi), %r13
cmovel %r11d, %ebx
movzbl %r10b, %r10d
movl $0x1, %r11d
cmovel %r11d, %r10d
addl (%rcx,%r13,4), %ebx
movq 0x58(%rsp), %r13
cmpl %r14d, %ebx
cmovgl %ebx, %r14d
movl %ebx, -0x8(%rdx,%rax)
cmovgl %esi, %r8d
movl 0x4(%rdi,%rax), %r11d
movl 0xc(%rdi,%rax), %ebx
subl %r13d, %ebx
subl %r15d, %r11d
cmpl %r11d, %ebx
cmovgl %ebx, %r11d
leal 0x8(%r10), %ebx
movzbl %bl, %ebx
cmovll %r10d, %ebx
movl %r11d, (%rdx,%rax)
movl -0x14(%rdx,%rax), %r10d
movl -0x10(%rdx,%rax), %r11d
subl %r13d, %r11d
subl %r15d, %r10d
movl %ebx, %ebp
orb $0x4, %bpl
cmpl %r10d, %r11d
cmovgl %r11d, %r10d
movzbl %bpl, %r11d
cmovll %ebx, %r11d
movl %r10d, -0x4(%rdx,%rax)
movq (%r9), %r10
movb %r11b, (%r10,%r12)
movq %r12, %r10
incq %rsi
addq $0xc, %rax
addq $0x8, %r9
cmpq %rsi, (%rsp)
jne 0x1944e
movq 0xb8(%rsp), %rdi
cmpl %r14d, %edi
jge 0x19554
movl %r8d, %ecx
movq 0x80(%rsp), %rdx
subl %edx, %ecx
incl %ecx
movl %r8d, 0x14(%rsp)
movl %r10d, 0x10(%rsp)
movl %r14d, %edi
movq 0x48(%rsp), %r12
jmp 0x19589
movl %edi, %eax
subl 0x64(%rsp), %eax
cmpl %eax, %r14d
movq 0x48(%rsp), %r12
movq 0x80(%rsp), %rdx
jge 0x19584
cmpl $0x0, 0xc(%rsp)
movl 0x1c(%rsp), %r14d
movq 0x30(%rsp), %rbx
movq 0x78(%rsp), %rcx
jne 0x19593
jmp 0x195b7
movl $0x1, %ecx
movl 0x1c(%rsp), %r14d
movq 0x30(%rsp), %rbx
movq 0x70(%rsp), %rax
movl %edx, (%rax,%r10,4)
addl %ecx, %edx
incq %r10
movq 0x88(%rsp), %r15
cmpq 0xa0(%rsp), %r10
jne 0x1934f
testl %edi, %edi
setg %dil
movl 0x28(%rsp), %esi
jmp 0x195d3
movl $0xffffffff, 0x14(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x10(%rsp) # imm = 0xFFFFFFFF
movq 0x128(%rsp), %r15
cmpl $0x0, 0xc(%rsp)
movq 0x20(%rsp), %rdx
jne 0x19602
testb %dil, %dil
jne 0x19602
movb $0x0, (%r15)
xorl %ebp, %ebp
xorl %r14d, %r14d
movq 0x120(%rsp), %r15
jmp 0x19855
movl 0x110(%rsp), %r8d
decl %esi
movl 0x100(%rsp), %eax
leal -0x1(%rax), %r14d
cmpl $0x0, 0xc(%rsp)
cmovel 0x14(%rsp), %r14d
cmovel 0x10(%rsp), %esi
xorl %r9d, %r9d
movl $0x1, %ebp
xorl %r13d, %r13d
xorl %ebx, %ebx
movl $0x0, (%rsp)
movslq %esi, %rcx
leal (%r14,%r12), %eax
movq 0x70(%rsp), %rdi
subl (%rdi,%rcx,4), %eax
testl %eax, %eax
cmovlel %r9d, %eax
cmpl 0x2c(%rsp), %eax
jg 0x19752
movl %eax, %eax
movq 0x98(%rsp), %rdi
movq (%rdi,%rax,8), %rax
movzbl (%rax,%rcx), %eax
testl %ebx, %ebx
je 0x19692
movq 0x120(%rsp), %rcx
movb $0x2d, (%rcx,%r13)
movslq %r14d, %r14
movb (%rdx,%r14), %cl
movb %cl, (%r15,%r13)
decl %r14d
andl $0x4, %eax
movl %eax, %ebx
jmp 0x196bf
movl %esi, %edi
movq 0x38(%rsp), %rsi
movb (%rsi,%rcx), %cl
movq 0x120(%rsp), %rsi
movb %cl, (%rsi,%r13)
cmpl $0x0, (%rsp)
je 0x19705
movb $0x2d, (%r15,%r13)
movl %edi, %esi
decl %esi
andl $0x8, %eax
xorl %ebx, %ebx
movl %eax, (%rsp)
cmpl %r8d, %ebp
jl 0x196ed
leaq 0x75077(%rip), %rdi     # 0x8e742
xorl %eax, %eax
movl %esi, %r12d
callq 0x26e94
xorl %r9d, %r9d
movl 0x110(%rsp), %r8d
movl %r12d, %esi
movq 0x48(%rsp), %r12
movq 0x20(%rsp), %rdx
incl %ebp
incq %r13
testl %esi, %esi
js 0x1977f
testl %r14d, %r14d
jns 0x1963b
jmp 0x1977f
movslq %r14d, %rcx
movb (%rdx,%rcx), %cl
movb %cl, (%r15,%r13)
movl %edi, %esi
decl %esi
decl %r14d
movl %eax, %ecx
andb $0x3, %cl
cmpb $0x2, %cl
je 0x19733
andl $0x3, %eax
cmpl $0x3, %eax
jne 0x19744
movl $0x1, (%rsp)
xorl %ebx, %ebx
jmp 0x196bf
movl $0x0, (%rsp)
movl $0x1, %ebx
jmp 0x196bf
xorl %ebx, %ebx
movl $0x0, (%rsp)
jmp 0x196bf
xorl %r14d, %r14d
cmpl $0x0, 0xc(%rsp)
jne 0x198c5
leaq 0x74f49(%rip), %rdi     # 0x8e6b0
leaq 0x74f49(%rip), %rsi     # 0x8e6b7
leaq 0x74f55(%rip), %rcx     # 0x8e6ca
movl $0x159, %edx            # imm = 0x159
callq 0x6460
testl %esi, %esi
js 0x197cc
movl %esi, %ebx
addl %esi, %ebp
addq 0x38(%rsp), %rbx
movq 0x120(%rsp), %r12
movb (%rbx), %al
movb %al, (%r12,%r13)
movb $0x2d, (%r15,%r13)
incq %r13
cmpl %r8d, %r13d
jl 0x197c2
leaq 0x74f94(%rip), %rdi     # 0x8e742
xorl %eax, %eax
callq 0x26e94
movl 0x110(%rsp), %r8d
movq 0x20(%rsp), %rdx
decq %rbx
cmpq %r13, %rbp
jne 0x19794
jmp 0x197d7
movl %r13d, %ebp
movq 0x120(%rsp), %r12
testl %r14d, %r14d
js 0x1981f
movl %r14d, %ebx
movl %ebp, %ebp
incq %rbx
leaq 0x74f57(%rip), %r14     # 0x8e742
movb $0x2d, (%r12,%rbp)
movb -0x1(%rdx,%rbx), %al
movb %al, (%r15,%rbp)
leal 0x1(%rbp), %eax
cmpl %r8d, %eax
jl 0x19817
movq %r14, %rdi
xorl %eax, %eax
callq 0x26e94
movl 0x110(%rsp), %r8d
movq 0x20(%rsp), %rdx
incq %rbp
decq %rbx
jg 0x197eb
movl %ebp, %r14d
cmpl $0x0, 0x108(%rsp)
jle 0x19847
movq %r12, %rdi
movq %r14, %rsi
callq 0x1ffa2
movq %r15, %rdi
movq %r14, %rsi
callq 0x1ffa2
movq 0x20(%rsp), %rdx
movb $0x0, (%r12,%r14)
addq %r14, %r15
movl $0x1, %r14d
movq 0x130(%rsp), %rbx
movb $0x0, (%r15)
cmpl $0x0, 0x108(%rsp)
movq 0x50(%rsp), %rsi
jns 0x1988f
movq 0x38(%rsp), %rdi
movq %rdx, %r15
callq 0x1ffa2
movl 0x100(%rsp), %eax
movslq %eax, %rsi
movq %r15, %rdi
callq 0x1ffa2
movq 0x138(%rsp), %r15
leaq 0xc0(%rsp), %rdi
callq 0x2c2c7
testq %rbx, %rbx
je 0x198af
movl 0x10(%rsp), %eax
movl %eax, (%rbx)
movq 0x118(%rsp), %rax
testq %r15, %r15
je 0x198c3
movl 0x14(%rsp), %ecx
movl %ecx, (%r15)
movl %ebp, (%rax)
movl %r14d, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq