// File: /workspace/github_c_makefile_star2_O2/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 $0x248, %rsp            # imm = 0x248
movq %r9, 0x28(%rsp)
movl %r8d, 0x1c(%rsp)
movl %ecx, %r15d
movl %edx, %r14d
movq %rsi, %rbx
movq %rdi, %r13
movq 0x10(%rdi), %rax
movq %rax, 0x38(%rsp)
xorl %eax, %eax
callq 0x21578
leaq 0x40(%r13), %r12
movq 0x40(%r13), %rax
testq %rax, %rax
je 0x387e2
movq 0x8(%rax), %rdi
movq %rbx, %rsi
callq 0x6a50
testl %eax, %eax
je 0x38807
movq %r12, %rdi
callq 0x38390
movq %r13, %rdi
movq %rbx, %rsi
callq 0x38660
movq %rax, 0x40(%r13)
movq 0x10(%r13), %rdi
callq *0x60(%r13)
movq %rax, 0x48(%r13)
jmp 0x38813
movq 0x10(%r13), %rdi
movq 0x48(%r13), %rsi
callq *0x50(%r13)
movq (%r12), %rbp
movl 0x18(%rbp), %ecx
testl %r15d, %r15d
je 0x3883a
cmpl %r15d, %ecx
jae 0x3883d
leaq 0x4b030(%rip), %rdi     # 0x8385b
movq %rbx, %rsi
movl %r15d, %edx
xorl %eax, %eax
callq 0x223fb
jmp 0x3883d
movl %ecx, %r15d
movq %r13, 0x8(%rsp)
movl %r15d, %r12d
subl %r14d, %r12d
jg 0x38861
leaq 0x4b03b(%rip), %rdi     # 0x8388c
movq %rbx, %rsi
movl %r14d, %edx
movl %r15d, %ecx
xorl %eax, %eax
callq 0x223fb
pushq $0x28
popq %rdi
callq 0x28bb0
cmpl 0x18(%rbp), %r12d
movq %rax, 0x10(%rsp)
jne 0x3887c
movq %rax, %r13
movq %rbx, %rdi
jmp 0x388a8
leaq 0x4a956(%rip), %rdx     # 0x831d9
leaq 0x40(%rsp), %r13
movq %r13, %rdi
movl $0x200, %esi            # imm = 0x200
movq %rbx, %rcx
movl %r14d, %r8d
movl %r15d, %r9d
xorl %eax, %eax
callq 0x1fab2
movq %r13, %rdi
movq 0x10(%rsp), %r13
callq 0x1c306
movq %rax, 0x8(%r13)
movl %r12d, 0x18(%r13)
leal 0x1(%r12), %eax
movslq %eax, %rdi
callq 0x289b8
movq %r13, %rcx
movq %rax, %r13
movq %rax, 0x10(%rcx)
movslq %r12d, %rax
movb $0x0, (%r13,%rax)
movq %r14, 0x20(%rsp)
sarl $0x2, %r14d
leal 0x3(%r15), %eax
sarl $0x2, %eax
subl %r14d, %eax
movslq %eax, %rdi
movq %rdi, 0x30(%rsp)
callq 0x289b8
movq %rax, %rbx
movq %rax, 0x40(%rsp)
movslq %r14d, %rsi
movq 0x38(%rsp), %r12
movq %r12, %rdi
movq 0x8(%rsp), %r14
callq *0x58(%r14)
movq %r12, %rdi
movq %rbx, %rsi
movq 0x30(%rsp), %r12
movq %r12, %rdx
callq *0x88(%r14)
cmpl $0x1, %r12d
jne 0x3897f
movq 0x20(%rsp), %r14
movl %r14d, %ecx
andl $-0x4, %ecx
movl %r15d, %eax
subl %ecx, %eax
cmpl $0x4, %eax
jg 0x38b7a
movzbl (%rbx), %edx
movl %r14d, %esi
andl $0x3, %esi
leal (%rsi,%rsi), %ecx
xorl $0x6, %ecx
leaq 0x7d735(%rip), %rdi     # 0xb6090
cmpl %eax, %esi
jge 0x38a57
movl %edx, %r8d
shrl %cl, %r8d
andl $0x3, %r8d
movb (%rdi,%r8), %r8b
movb %r8b, (%r13)
incq %r13
incl %esi
addl $-0x2, %ecx
jmp 0x3895b
movq 0x20(%rsp), %r14
movl %r14d, %eax
andl $0x3, %eax
je 0x389ca
movb (%rbx), %cl
movl %eax, %edx
xorl $0x3, %edx
leaq 0x7d6f6(%rip), %rsi     # 0xb6090
testl %edx, %edx
js 0x389b9
movzbl %cl, %ecx
movl %ecx, %edi
andl $0x3, %edi
movb (%rsi,%rdi), %dil
movl %edx, %r8d
movb %dil, (%r13,%r8)
shrb $0x2, %cl
decl %edx
jmp 0x3899a
incq %rbx
pushq $0x4
popq %rdx
subl %eax, %edx
leal (%rdx,%r14), %ecx
addq %rdx, %r13
jmp 0x389cd
movl %r14d, %ecx
movl %r15d, %edx
andl $-0x4, %edx
leaq 0x7d6b6(%rip), %rax     # 0xb6090
cmpl %edx, %ecx
jge 0x38a25
movzbl (%rbx), %esi
incq %rbx
movl %esi, %edi
andl $0x3, %edi
movb (%rax,%rdi), %dil
movb %dil, 0x3(%r13)
movl %esi, %edi
shrl $0x2, %edi
andl $0x3, %edi
movb (%rax,%rdi), %dil
movb %dil, 0x2(%r13)
movl %esi, %edi
shrl $0x4, %edi
andl $0x3, %edi
movb (%rax,%rdi), %dil
movb %dil, 0x1(%r13)
shrl $0x6, %esi
movb (%rax,%rsi), %sil
movb %sil, (%r13)
addq $0x4, %r13
addl $0x4, %ecx
jmp 0x389da
movl %r15d, %edx
andl $0x3, %edx
je 0x38a57
movzbl (%rbx), %esi
leal (%rdx,%rdx), %edi
movb $0x8, %cl
subb %dil, %cl
shrl %cl, %esi
testq %rdx, %rdx
jle 0x38a57
movl %esi, %ecx
andl $0x3, %ecx
movb (%rax,%rcx), %cl
movb %cl, -0x1(%r13,%rdx)
decq %rdx
shrl $0x2, %esi
andl $0x3f, %esi
jmp 0x38a3a
leaq 0x40(%rsp), %rdi
callq 0x28c3d
movl 0x1c(%rbp), %ebx
movslq %r14d, %rax
movq %rax, 0x8(%rsp)
testl %ebx, %ebx
je 0x38ad9
movq 0x20(%rbp), %rsi
movl %ebx, %edi
movl %r14d, %edx
callq 0x38b99
movq 0x8(%rsp), %r13
negq %r13
movslq %eax, %r12
cmpl %r12d, %ebx
jbe 0x38ad9
movq 0x20(%rbp), %rax
movl (%rax,%r12,4), %eax
cmpl %r15d, %eax
jge 0x38ad9
movq 0x28(%rbp), %rcx
movl (%rcx,%r12,4), %ecx
addl %eax, %ecx
cmpl %r14d, %eax
cmovlel %r14d, %eax
cmpl %r15d, %ecx
cmovgel %r15d, %ecx
subl %eax, %ecx
jle 0x38ad4
movslq %eax, %rdi
movq 0x10(%rsp), %rax
addq 0x10(%rax), %rdi
addq %r13, %rdi
movslq %ecx, %rdx
pushq $0x6e
popq %rsi
callq 0x63b0
movl 0x1c(%rbp), %ebx
incq %r12
jmp 0x38a89
cmpl $0x0, 0x1c(%rsp)
movq 0x10(%rsp), %r13
je 0x38b56
movq 0x10(%r13), %rdi
movl 0x18(%r13), %esi
callq 0x1df53
movl 0x30(%rbp), %ebx
testl %ebx, %ebx
je 0x38b56
movq 0x38(%rbp), %rsi
movl %ebx, %edi
movl %r14d, %edx
callq 0x38b99
negq 0x8(%rsp)
movslq %eax, %r12
cmpl %r12d, %ebx
jbe 0x38b56
movq 0x38(%rbp), %rax
movl (%rax,%r12,4), %eax
cmpl %r15d, %eax
jge 0x38b56
movq 0x40(%rbp), %rcx
movl (%rcx,%r12,4), %esi
addl %eax, %esi
cmpl %r14d, %eax
cmovlel %r14d, %eax
cmpl %r15d, %esi
cmovgel %r15d, %esi
subl %eax, %esi
jle 0x38b51
movslq %eax, %rdi
addq 0x10(%r13), %rdi
addq 0x8(%rsp), %rdi
callq 0x1df8a
movl 0x30(%rbp), %ebx
incq %r12
jmp 0x38b0f
movq 0x28(%rsp), %rcx
testq %rcx, %rcx
je 0x38b65
movl 0x18(%rbp), %eax
movl %eax, (%rcx)
movq %r13, %rax
addq $0x248, %rsp            # imm = 0x248
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x4ad3a(%rip), %rdi     # 0x838bb
leaq 0x4ad3d(%rip), %rsi     # 0x838c5
leaq 0x4ad43(%rip), %rcx     # 0x838d2
movl $0x30f, %edx            # imm = 0x30F
callq 0x6460