// File: /workspace/github_c_makefile_star2_O3/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, %r12d
movl %edx, %ebp
movq %rsi, %r13
movq %rdi, %r15
movq 0x10(%rdi), %r14
xorl %eax, %eax
callq 0x25e47
leaq 0x40(%r15), %rbx
movq 0x40(%r15), %rax
testq %rax, %rax
je 0x3e7e9
movq 0x8(%rax), %rdi
movq %r13, %rsi
callq 0x6a50
testl %eax, %eax
je 0x3e80e
movq %rbx, %rdi
callq 0x3e363
movq %r15, %rdi
movq %r13, %rsi
callq 0x3e65a
movq %rax, 0x40(%r15)
movq 0x10(%r15), %rdi
callq *0x60(%r15)
movq %rax, 0x48(%r15)
jmp 0x3e81a
movq 0x10(%r15), %rdi
movq 0x48(%r15), %rsi
callq *0x50(%r15)
movq (%rbx), %rax
movq %rax, 0x18(%rsp)
movl 0x18(%rax), %ecx
testl %r12d, %r12d
je 0x3e845
cmpl %r12d, %ecx
jae 0x3e848
leaq 0x56125(%rip), %rdi     # 0x9495b
movq %r13, %rsi
movl %r12d, %edx
xorl %eax, %eax
callq 0x26e94
jmp 0x3e848
movl %ecx, %r12d
movq %r15, 0x28(%rsp)
movq %r12, (%rsp)
subl %ebp, %r12d
jg 0x3e86d
leaq 0x5612f(%rip), %rdi     # 0x9498c
movq %r13, %rsi
movl %ebp, %edx
movq (%rsp), %rcx
xorl %eax, %eax
callq 0x26e94
movl $0x28, %edi
callq 0x2dff4
movq %rax, %r15
movq 0x18(%rsp), %rax
cmpl 0x18(%rax), %r12d
jne 0x3e88a
movq %r13, %rdi
jmp 0x3e8b2
leaq 0x55a48(%rip), %rdx     # 0x942d9
leaq 0x30(%rsp), %rbx
movq %rbx, %rdi
movl $0x200, %esi            # imm = 0x200
movq %r13, %rcx
movl %ebp, %r8d
movq (%rsp), %r9
xorl %eax, %eax
callq 0x23f33
movq %rbx, %rdi
callq 0x1feba
movq %rax, 0x8(%r15)
movl %r12d, 0x18(%r15)
leal 0x1(%r12), %eax
movslq %eax, %rdi
callq 0x2ddfc
movq %rax, %r13
movq %r15, 0x8(%rsp)
movq %rax, 0x10(%r15)
movslq %r12d, %rax
movb $0x0, (%r13,%rax)
movl %ebp, %r15d
sarl $0x2, %ebp
movq (%rsp), %rax
addl $0x3, %eax
sarl $0x2, %eax
subl %ebp, %eax
movslq %eax, %r12
movq %r12, %rdi
callq 0x2ddfc
movq %rax, %rbx
movq %rax, 0x30(%rsp)
movslq %ebp, %rsi
movq %r14, %rdi
movq 0x28(%rsp), %rbp
callq *0x58(%rbp)
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq *0x88(%rbp)
cmpl $0x1, %r12d
jne 0x3e985
movl %r15d, %ecx
andl $-0x4, %ecx
movq (%rsp), %r14
movl %r14d, %eax
subl %ecx, %eax
cmpl $0x4, %eax
jg 0x3eba9
movl %r15d, %ebp
movl %r15d, %edx
andl $0x3, %edx
cmpl %eax, %edx
jge 0x3ea81
movzbl (%rbx), %esi
leal (%rdx,%rdx), %ecx
xorl $0x6, %ecx
leaq 0x8370e(%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 0x3e962
jmp 0x3ea81
movl %r15d, %edx
andl $0x3, %edx
movl %r15d, %ebp
je 0x3e9d6
movq %rbx, %rax
incq %rax
movl $0x4, %ecx
subl %edx, %ecx
movb (%rbx), %dl
movl %ebp, %esi
notl %esi
andl $0x3, %esi
leaq 0x836c3(%rip), %rdi     # 0xc2070
movq (%rsp), %r14
movzbl %dl, %edx
movl %edx, %r8d
andl $0x3, %r8d
movb (%rdi,%r8), %r8b
movb %r8b, (%r13,%rsi)
shrb $0x2, %dl
addq $-0x1, %rsi
jb 0x3e9b1
movl %ecx, %edx
addl %ebp, %ecx
addq %rdx, %r13
jmp 0x3e9df
movq %rbx, %rax
movl %ebp, %ecx
movq (%rsp), %r14
movl %r14d, %edx
andl $0x3, %edx
movl %r14d, %esi
andl $-0x4, %esi
cmpl %esi, %ecx
jge 0x3ea49
leaq 0x8367a(%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 0x3e9f6
testl %edx, %edx
je 0x3ea81
movzbl (%rax), %eax
leal (%rdx,%rdx), %esi
movb $0x8, %cl
subb %sil, %cl
shrl %cl, %eax
incq %rdx
leaq 0x8360c(%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
ja 0x3ea64
leaq 0x30(%rsp), %rdi
callq 0x2e0b0
movq 0x18(%rsp), %r13
movl 0x1c(%r13), %ebx
testl %ebx, %ebx
je 0x3eb01
movq 0x20(%r13), %rsi
movl %ebx, %edi
movl %ebp, %edx
callq 0x3ebc8
cmpl %ebx, %eax
jae 0x3eb01
movslq %ebp, %r15
negq %r15
movslq %eax, %r12
movq 0x20(%r13), %rax
movl (%rax,%r12,4), %eax
cmpl %r14d, %eax
jge 0x3eb01
movq 0x28(%r13), %rcx
movl (%rcx,%r12,4), %ecx
addl %eax, %ecx
cmpl %ebp, %eax
cmovlel %ebp, %eax
cmpl %r14d, %ecx
cmovgel %r14d, %ecx
subl %eax, %ecx
jle 0x3eaf9
movslq %eax, %rdi
movq 0x8(%rsp), %rax
addq 0x10(%rax), %rdi
addq %r15, %rdi
movslq %ecx, %rdx
movl $0x6e, %esi
callq 0x63b0
movl 0x1c(%r13), %ebx
incq %r12
cmpl %r12d, %ebx
ja 0x3eab2
cmpl $0x0, 0x14(%rsp)
je 0x3eb82
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdi
movl 0x18(%rax), %esi
callq 0x21f96
movl 0x30(%r13), %ebx
testl %ebx, %ebx
je 0x3eb82
movq 0x38(%r13), %rsi
movl %ebx, %edi
movl %ebp, %edx
callq 0x3ebc8
cmpl %ebx, %eax
jae 0x3eb82
movslq %ebp, %r15
negq %r15
movslq %eax, %r12
movq 0x38(%r13), %rax
movl (%rax,%r12,4), %eax
cmpl %r14d, %eax
jge 0x3eb82
movq 0x40(%r13), %rcx
movl (%rcx,%r12,4), %esi
addl %eax, %esi
cmpl %ebp, %eax
cmovlel %ebp, %eax
cmpl %r14d, %esi
cmovgel %r14d, %esi
subl %eax, %esi
jle 0x3eb7a
movslq %eax, %rdi
movq 0x8(%rsp), %rax
addq 0x10(%rax), %rdi
addq %r15, %rdi
callq 0x21fca
movl 0x30(%r13), %ebx
incq %r12
cmpl %r12d, %ebx
ja 0x3eb3b
movq 0x20(%rsp), %rcx
testq %rcx, %rcx
je 0x3eb92
movl 0x18(%r13), %eax
movl %eax, (%rcx)
movq 0x8(%rsp), %rax
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x55e0b(%rip), %rdi     # 0x949bb
leaq 0x55e0e(%rip), %rsi     # 0x949c5
leaq 0x55e14(%rip), %rcx     # 0x949d2
movl $0x30f, %edx            # imm = 0x30F
callq 0x6460