// File: /workspace/github_cpp_makefile_star2_O2/BenLangmead[P]bowtie/./ebwt.h
// Function: Ebwt::countUpToEx(SideLocus const&, unsigned long*) const
inline void Ebwt::countUpToEx(const SideLocus& l, TIndexOffU* arrs) const {
	int i = 0;
	// Count occurrences of c in each 64-bit (using bit trickery);
	// note: this seems does not seem to lend a significant boost to
	// performance.  If you comment out this whole loop (which won't
	// affect correctness - it will just cause the following loop to
	// take up the slack) then runtime does not change noticeably.
	// Someday the countInU64() and pop() functions should be
	// vectorized/SSE-ized in case that helps.
	const uint8_t *side = l.side(this->_ebwt);

#ifdef POPCNT_CAPABILITY
    if (_usePOPCNTinstruction) {
        for(; i+7 < l._by; i += 8) {
            countInU64Ex<USE_POPCNT_INSTRUCTION>(*(uint64_t*)&side[i], arrs);
        }
    }
    else {
        for(; i+7 < l._by; i += 8) {
            countInU64Ex<USE_POPCNT_GENERIC>(*(uint64_t*)&side[i], arrs);
        }
    }
#else
	for(; i+7 < l._by; i += 8) {
		countInU64Ex(*(uint64_t*)&side[i], arrs);
	}
#endif

#ifdef SIXTY4_FORMAT
	// Calculate number of bit pairs to shift off the end
	const int bpShiftoff = 32 - (((l._by & 7) << 2) + l._bp);
	assert_leq(bpShiftoff, 32);
	if(bpShiftoff < 32) {
		const uint64_t sw = (*(uint64_t*)&l.side(this->_ebwt)[i]) << (bpShiftoff << 1);

#ifdef POPCNT_CAPABILITY
        if (_usePOPCNTinstruction) {
            countInU64Ex<USE_POPCNT_INSTRUCTION>(sw, arrs);
        }
        else{
            countInU64Ex<USE_POPCNT_GENERIC>(sw, arrs);
        }
#else
		countInU64Ex(sw, arrs);
#endif

		arrs[0] -= bpShiftoff;
	}
#else
	// Count occurences of c in the rest of the side (using LUT)
	for(; i < l._by; i++) {
		arrs[0] += cCntLUT_4[0][0][side[i]];
		arrs[1] += cCntLUT_4[0][1][side[i]];
		arrs[2] += cCntLUT_4[0][2][side[i]];
		arrs[3] += cCntLUT_4[0][3][side[i]];
	}
	// Count occurences of c in the rest of the byte
	if(l._bp > 0) {
		arrs[0] += cCntLUT_4[(int)l._bp][0][side[i]];
		arrs[1] += cCntLUT_4[(int)l._bp][1][side[i]];
		arrs[2] += cCntLUT_4[(int)l._bp][2][side[i]];
		arrs[3] += cCntLUT_4[(int)l._bp][3][side[i]];
	}
#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %rbx
movabsq $0x5555555555555555, %r10 # imm = 0x5555555555555555
movq 0xc8(%rdi), %r11
addq (%rsi), %r11
cmpb $0x0, (%rdi)
je 0x1a45a
xorl %ebp, %ebp
movdqa 0xdc64(%rip), %xmm0     # 0x28020
leaq 0x7(%rbp), %rax
movswq 0x14(%rsi), %rcx
cmpq %rcx, %rax
jge 0x1a4f0
movq (%r11,%rbp), %rax
movq %rax, %rcx
notq %rcx
movq %rcx, %rdx
shrq %rdx
movq %rcx, %rdi
andq %r10, %rdi
andq %rdx, %rdi
popcntq %rdi, %rdx
movq %rax, %r9
shrq %r9
andq %r10, %r9
movq %r9, %rdi
xorq %r10, %rdi
andq %rax, %rdi
popcntq %rdi, %r8
movq %rdx, %xmm1
movq %r8, %xmm2
punpcklqdq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0]
pand %xmm0, %xmm1
movdqu (%rbx), %xmm2
paddq %xmm1, %xmm2
movdqu 0x10(%rbx), %xmm1
movdqu %xmm2, (%rbx)
andq %r9, %rcx
popcntq %rcx, %rdx
andq %rax, %r9
popcntq %r9, %rax
movq %rax, %xmm2
movq %rdx, %xmm3
punpcklqdq %xmm2, %xmm3    # xmm3 = xmm3[0],xmm2[0]
pand %xmm0, %xmm3
paddq %xmm1, %xmm3
movdqu %xmm3, 0x10(%rbx)
addq $0x8, %rbp
jmp 0x1a3bc
xorl %ebp, %ebp
movq %rsi, 0x10(%rsp)
movq %r11, 0x8(%rsp)
movabsq $0x5555555555555555, %r13 # imm = 0x5555555555555555
leaq 0x7(%rbp), %rax
movswq 0x14(%rsi), %rcx
cmpq %rcx, %rax
jge 0x1a4f0
movq (%r11,%rbp), %r14
movq %r14, %r15
notq %r15
movq %r15, %rax
shrq %rax
movq %r15, %rdi
andq %r13, %rdi
andq %rax, %rdi
callq 0x173ec
movl %eax, %eax
addq %rax, (%rbx)
movq %r14, %r12
shrq %r12
andq %r13, %r12
movq %r12, %rdi
xorq %r13, %rdi
andq %r14, %rdi
callq 0x173ec
movl %eax, %eax
addq %rax, 0x8(%rbx)
andq %r12, %r15
movq %r15, %rdi
callq 0x173ec
movl %eax, %eax
addq %rax, 0x10(%rbx)
andq %r14, %r12
movq %r12, %rdi
callq 0x173ec
movq 0x8(%rsp), %r11
movq 0x10(%rsp), %rsi
movl %eax, %eax
addq %rax, 0x18(%rbx)
addq $0x8, %rbp
jmp 0x1a470
andl $-0x8, %ebp
leaq 0x1a026(%rip), %rax     # 0x34520
movswq %cx, %rcx
cmpq %rcx, %rbp
jge 0x1a54b
movzbl (%r11,%rbp), %ecx
movzbl (%rax,%rcx), %ecx
addq %rcx, (%rbx)
movzbl (%r11,%rbp), %ecx
movzbl 0x100(%rax,%rcx), %ecx
addq %rcx, 0x8(%rbx)
movzbl (%r11,%rbp), %ecx
movzbl 0x200(%rax,%rcx), %ecx
addq %rcx, 0x10(%rbx)
movzbl (%r11,%rbp), %ecx
movzbl 0x300(%rax,%rcx), %ecx
addq %rcx, 0x18(%rbx)
incq %rbp
movzwl 0x14(%rsi), %ecx
jmp 0x1a4fa
movsbq 0x16(%rsi), %rcx
testq %rcx, %rcx
jle 0x1a5bf
shlq $0xa, %rcx
addq %rax, %rcx
movzbl (%r11,%rbp), %edx
movzbl (%rdx,%rcx), %ecx
addq %rcx, (%rbx)
movsbq 0x16(%rsi), %rcx
movzbl (%r11,%rbp), %edx
shlq $0xa, %rcx
addq %rax, %rcx
movzbl 0x100(%rdx,%rcx), %ecx
addq %rcx, 0x8(%rbx)
movsbq 0x16(%rsi), %rcx
movzbl (%r11,%rbp), %edx
shlq $0xa, %rcx
addq %rax, %rcx
movzbl 0x200(%rdx,%rcx), %ecx
addq %rcx, 0x10(%rbx)
movsbq 0x16(%rsi), %rcx
movzbl (%r11,%rbp), %edx
shlq $0xa, %rcx
addq %rax, %rcx
movzbl 0x300(%rdx,%rcx), %eax
addq %rax, 0x18(%rbx)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq