// File: /workspace/github_c_makefile_star2_O1/icebert[P]pblat/lib/twoBit.c
// Function: twoBitReadSeqFragExt
struct dnaSeq *twoBitReadSeqFragExt(struct twoBitFile *tbf, char *name,
	int fragStart, int fragEnd, boolean doMask, int *retFullSize)
/* Read part of sequence from .2bit file.  To read full
 * sequence call with start=end=0.  Sequence will be lower
 * case if doMask is false, mixed case (repeats in lower)
 * if doMask is true. */
{
struct dnaSeq *seq;
void *f = tbf->f;
int i;
int packByteCount, packedStart, packedEnd, remainder, midStart, midEnd;
int outSize;
UBYTE *packed, *packedAlloc;
DNA *dna;

/* get sequence header information, which is cached */
dnaUtilOpen();
struct twoBit *twoBit = getTwoBitSeqHeader(tbf, name);

/* validate range. */
if (fragEnd == 0)
    fragEnd = twoBit->size;
if (fragEnd > twoBit->size)
    errAbort("twoBitReadSeqFrag in %s end (%d) >= seqSize (%d)", name, fragEnd, twoBit->size);
outSize = fragEnd - fragStart;
if (outSize < 1)
    errAbort("twoBitReadSeqFrag in %s start (%d) >= end (%d)", name, fragStart, fragEnd);

/* Allocate dnaSeq, and fill in zero tag at end of sequence. */
AllocVar(seq);
if (outSize == twoBit->size)
    seq->name = cloneString(name);
else
    {
    char buf[256*2];
    safef(buf, sizeof(buf), "%s:%d-%d", name, fragStart, fragEnd);
    seq->name = cloneString(buf);
    }
seq->size = outSize;
dna = seq->dna = needLargeMem(outSize+1);
seq->dna[outSize] = 0;


/* Skip to bits we need and read them in. */
packedStart = (fragStart>>2);
packedEnd = ((fragEnd+3)>>2);
packByteCount = packedEnd - packedStart;
packed = packedAlloc = needLargeMem(packByteCount);
(*tbf->ourSeekCur)(f, packedStart);
(*tbf->ourMustRead)(f, packed, packByteCount);

/* Handle case where everything is in one packed byte */
if (packByteCount == 1)
    {
    int pOff = (packedStart<<2);
    int pStart = fragStart - pOff;
    int pEnd = fragEnd - pOff;
    UBYTE partial = *packed;
    assert(pEnd <= 4);
    assert(pStart >= 0);
    for (i=pStart; i<pEnd; ++i)
	*dna++ = valToNt[(partial >> (6-i-i)) & 3];
    }
else
    {
    /* Handle partial first packed byte. */
    midStart = fragStart;
    remainder = (fragStart&3);
    if (remainder > 0)
	{
	UBYTE partial = *packed++;
	int partCount = 4 - remainder;
	for (i=partCount-1; i>=0; --i)
	    {
	    dna[i] = valToNt[partial&3];
	    partial >>= 2;
	    }
	midStart += partCount;
	dna += partCount;
	}

    /* Handle middle bytes. */
    remainder = fragEnd&3;
    midEnd = fragEnd - remainder;
    for (i=midStart; i<midEnd; i += 4)
        {
	UBYTE b = *packed++;
	dna[3] = valToNt[b&3];
	b >>= 2;
	dna[2] = valToNt[b&3];
	b >>= 2;
	dna[1] = valToNt[b&3];
	b >>= 2;
	dna[0] = valToNt[b&3];
	dna += 4;
	}

    if (remainder >0)
	{
	UBYTE part = *packed;
	part >>= (8-remainder-remainder);
	for (i=remainder-1; i>=0; --i)
	    {
	    dna[i] = valToNt[part&3];
	    part >>= 2;
	    }
	}
    }
freez(&packedAlloc);

if (twoBit->nBlockCount > 0)
    {
    int startIx = findGreatestLowerBound(twoBit->nBlockCount, twoBit->nStarts, fragStart);
    for (i=startIx; i<twoBit->nBlockCount; ++i)
        {
	int s = twoBit->nStarts[i];
	int e = s + twoBit->nSizes[i];
	if (s >= fragEnd)
	    break;
	if (s < fragStart)
	   s = fragStart;
	if (e > fragEnd)
	   e = fragEnd;
	if (s < e)
	    memset(seq->dna + s - fragStart, 'n', e - s);
	}
    }

if (doMask)
    {
    toUpperN(seq->dna, seq->size);
    if (twoBit->maskBlockCount > 0)
	{
	int startIx = findGreatestLowerBound(twoBit->maskBlockCount, twoBit->maskStarts,
		fragStart);
	for (i=startIx; i<twoBit->maskBlockCount; ++i)
	    {
	    int s = twoBit->maskStarts[i];
	    int e = s + twoBit->maskSizes[i];
	    if (s >= fragEnd)
		break;
	    if (s < fragStart)
		s = fragStart;
	    if (e > fragEnd)
		e = fragEnd;
	    if (s < e)
		toLowerN(seq->dna + s - fragStart, e - s);
	    }
	}
    }
if (retFullSize != NULL)
    *retFullSize = twoBit->size;
return seq;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
movq %r9, 0x20(%rsp)
movl %r8d, 0x14(%rsp)
movl %ecx, %r14d
movl %edx, %ebp
movq %rsi, %r13
movq %rdi, %r15
movq 0x10(%rdi), %rax
movq %rax, 0x28(%rsp)
xorl %eax, %eax
callq 0x25b5c
leaq 0x40(%r15), %rbx
movq 0x40(%r15), %rax
testq %rax, %rax
je 0x3e470
movq 0x8(%rax), %rdi
movq %r13, %rsi
callq 0x6a50
testl %eax, %eax
je 0x3e495
movq %rbx, %rdi
callq 0x3dfeb
movq %r15, %rdi
movq %r13, %rsi
callq 0x3e2ea
movq %rax, 0x40(%r15)
movq 0x10(%r15), %rdi
callq *0x60(%r15)
movq %rax, 0x48(%r15)
jmp 0x3e4a1
movq 0x10(%r15), %rdi
movq 0x48(%r15), %rsi
callq *0x50(%r15)
movq (%rbx), %rax
testl %r14d, %r14d
jne 0x3e4ad
movl 0x18(%rax), %r14d
movq %rax, 0x18(%rsp)
movl 0x18(%rax), %ecx
cmpl %ecx, %r14d
jbe 0x3e4ce
leaq 0x563c7(%rip), %rdi     # 0x94888
movq %r13, %rsi
movl %r14d, %edx
xorl %eax, %eax
callq 0x26b6f
movl %r14d, %r12d
subl %ebp, %r12d
jg 0x3e4ec
leaq 0x563dc(%rip), %rdi     # 0x948b9
movq %r13, %rsi
movl %ebp, %edx
movl %r14d, %ecx
xorl %eax, %eax
callq 0x26b6f
movl $0x28, %edi
callq 0x2dc95
movq %rax, %rbx
movq 0x18(%rsp), %rax
cmpl 0x18(%rax), %r12d
movq %rbx, (%rsp)
movq %r14, 0x8(%rsp)
jne 0x3e512
movq %r13, %rdi
jmp 0x3e53d
leaq 0x55ced(%rip), %rdx     # 0x94206
leaq 0x30(%rsp), %rbx
movq %rbx, %rdi
movl $0x200, %esi            # imm = 0x200
movq %r13, %rcx
movl %ebp, %r8d
movl %r14d, %r9d
xorl %eax, %eax
callq 0x23c18
movq %rbx, %rdi
movq (%rsp), %rbx
callq 0x1f9f6
movq %rax, 0x8(%rbx)
movl %r12d, 0x18(%rbx)
leal 0x1(%r12), %eax
movslq %eax, %rdi
callq 0x2da9d
movq %rax, %r13
movq %rax, 0x10(%rbx)
movslq %r12d, %rax
movb $0x0, (%r13,%rax)
movl %ebp, %r14d
sarl $0x2, %ebp
movq 0x8(%rsp), %rax
addl $0x3, %eax
sarl $0x2, %eax
subl %ebp, %eax
movslq %eax, %r12
movq %r12, %rdi
callq 0x2da9d
movq %rax, %rbx
movq %rax, 0x30(%rsp)
movslq %ebp, %rsi
movq 0x28(%rsp), %rbp
movq %rbp, %rdi
callq *0x58(%r15)
movq %rbp, %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq *0x88(%r15)
cmpl $0x1, %r12d
jne 0x3e612
movl %r14d, %ecx
andl $-0x4, %ecx
movq 0x8(%rsp), %rax
movq %rax, %rsi
subl %ecx, %eax
cmpl $0x4, %eax
jg 0x3e845
movl %r14d, %ebp
movl %r14d, %edx
andl $0x3, %edx
cmpl %eax, %edx
movq %rsi, %r14
jge 0x3e713
movzbl (%rbx), %esi
leal (%rdx,%rdx), %ecx
xorl $0x6, %ecx
leaq 0x83a81(%rip), %rdi     # 0xc2070
movl %esi, %r8d
shrl %cl, %r8d
andl $0x3, %r8d
movb (%rdi,%r8), %r8b
movb %r8b, (%r13)
incq %r13
incl %edx
addl $-0x2, %ecx
cmpl %eax, %edx
jl 0x3e5ef
jmp 0x3e713
movq 0x8(%rsp), %r8
movl %r14d, %edx
andl $0x3, %edx
movl %r14d, %ebp
je 0x3e669
movq %rbx, %rax
incq %rax
movl $0x4, %ecx
subl %edx, %ecx
movb (%rbx), %dl
movl %ebp, %esi
notl %esi
andl $0x3, %esi
incq %rsi
leaq 0x83a2e(%rip), %rdi     # 0xc2070
movq %r8, %r14
movzbl %dl, %edx
movl %edx, %r8d
andl $0x3, %r8d
movb (%rdi,%r8), %r8b
movb %r8b, -0x1(%r13,%rsi)
shrb $0x2, %dl
decq %rsi
jg 0x3e645
movl %ecx, %edx
addl %ebp, %ecx
addq %rdx, %r13
jmp 0x3e671
movq %rbx, %rax
movl %ebp, %ecx
movq %r8, %r14
movl %r14d, %edx
andl $0x3, %edx
movl %r14d, %esi
andl $-0x4, %esi
cmpl %esi, %ecx
jge 0x3e6db
leaq 0x839e8(%rip), %rdi     # 0xc2070
movzbl (%rax), %r8d
incq %rax
movl %r8d, %r9d
andl $0x3, %r9d
movb (%rdi,%r9), %r9b
movb %r9b, 0x3(%r13)
movl %r8d, %r9d
shrl $0x2, %r9d
andl $0x3, %r9d
movb (%rdi,%r9), %r9b
movb %r9b, 0x2(%r13)
movl %r8d, %r9d
shrl $0x4, %r9d
andl $0x3, %r9d
movb (%rdi,%r9), %r9b
movb %r9b, 0x1(%r13)
shrl $0x6, %r8d
movb (%rdi,%r8), %r8b
movb %r8b, (%r13)
addq $0x4, %r13
addl $0x4, %ecx
cmpl %esi, %ecx
jl 0x3e688
testl %edx, %edx
je 0x3e713
movzbl (%rax), %eax
leal (%rdx,%rdx), %esi
movb $0x8, %cl
subb %sil, %cl
shrl %cl, %eax
incq %rdx
leaq 0x8397a(%rip), %rcx     # 0xc2070
movl %eax, %esi
andl $0x3, %esi
movb (%rcx,%rsi), %sil
movb %sil, -0x2(%r13,%rdx)
shrl $0x2, %eax
andl $0x3f, %eax
decq %rdx
cmpq $0x1, %rdx
jg 0x3e6f6
leaq 0x30(%rsp), %rdi
callq 0x2dd51
movq 0x18(%rsp), %r13
movl 0x1c(%r13), %edi
testl %edi, %edi
je 0x3e799
movq 0x20(%r13), %rsi
movl %ebp, %edx
callq 0x3e864
cmpl 0x1c(%r13), %eax
jae 0x3e799
movslq %ebp, %rbx
negq %rbx
movslq %eax, %r15
movq 0x20(%r13), %rax
movl (%rax,%r15,4), %r12d
cmpl %r14d, %r12d
jge 0x3e799
movq 0x28(%r13), %rax
movl (%rax,%r15,4), %eax
addl %r12d, %eax
cmpl %ebp, %r12d
movl %ebp, %ecx
cmovgl %r12d, %ecx
cmpl %r14d, %eax
cmovgel %r14d, %eax
subl %ecx, %eax
jle 0x3e78b
movslq %ecx, %rdi
movq (%rsp), %rcx
addq 0x10(%rcx), %rdi
addq %rbx, %rdi
movslq %eax, %rdx
movl $0x6e, %esi
callq 0x63b0
cmpl %r14d, %r12d
jge 0x3e799
incq %r15
cmpl %r15d, 0x1c(%r13)
ja 0x3e744
cmpl $0x0, 0x14(%rsp)
je 0x3e81f
movq (%rsp), %rax
movq 0x10(%rax), %rdi
movl 0x18(%rax), %esi
callq 0x21c37
movl 0x30(%r13), %edi
testl %edi, %edi
je 0x3e81f
movq 0x38(%r13), %rsi
movl %ebp, %edx
callq 0x3e864
cmpl 0x30(%r13), %eax
jae 0x3e81f
movslq %ebp, %rbx
negq %rbx
movslq %eax, %r15
movq 0x38(%r13), %rax
movl (%rax,%r15,4), %r12d
cmpl %r14d, %r12d
jge 0x3e81f
movq 0x40(%r13), %rax
movl (%rax,%r15,4), %esi
addl %r12d, %esi
cmpl %ebp, %r12d
movl %ebp, %eax
cmovgl %r12d, %eax
cmpl %r14d, %esi
cmovgel %r14d, %esi
subl %eax, %esi
jle 0x3e811
movslq %eax, %rdi
movq (%rsp), %rax
addq 0x10(%rax), %rdi
addq %rbx, %rdi
callq 0x21c6b
cmpl %r14d, %r12d
jge 0x3e81f
incq %r15
cmpl %r15d, 0x30(%r13)
ja 0x3e7d2
movq 0x20(%rsp), %rcx
testq %rcx, %rcx
je 0x3e82f
movl 0x18(%r13), %eax
movl %eax, (%rcx)
movq (%rsp), %rax
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x5609c(%rip), %rdi     # 0x948e8
leaq 0x5609f(%rip), %rsi     # 0x948f2
leaq 0x560a5(%rip), %rcx     # 0x948ff
movl $0x30f, %edx            # imm = 0x30F
callq 0x6460