// File: /workspace/github_c_makefile_star2_O3/ToniWestbrook[P]paladin/bwt.c
// Function: bwt_occ4
void bwt_occ4(const bwt_t *bwt, bwtint_t k, bwtint_t cnt[VALUE_DOMAIN])
{
	uint32_t *p, *end;

	// If K is set to max, set counts to 0
	if (k == (bwtint_t)(-1)) {
		memset(cnt, 0, VALUE_DOMAIN * sizeof(bwtint_t));
		return;
	}

	k -= (k >= bwt->primary); // because $ is not in bwt

	// Copy current occurrence interval
	p = getOccInterval(bwt, k);
	memcpy(cnt, p, VALUE_DOMAIN * sizeof(bwtint_t));

	// Loop from end of interval to K in unpacked space
	p += sizeof(bwtint_t) / sizeof(uint32_t) * VALUE_DOMAIN;
	end = p + (((k / 16) - ((k&~OCC_INTV_MASK) / 16)) * 4) + ((k % 16) - (k % 4))/4;
	int supercount = 0;

	for (; p < end; ++p) {
		cnt[unpackBWTValue(bwt, k/128*128 + supercount)]++;
		cnt[unpackBWTValue(bwt, k/128*128 + supercount+1)]++;
		cnt[unpackBWTValue(bwt, k/128*128 + supercount+2)]++;
		cnt[unpackBWTValue(bwt, k/128*128 + supercount+3)]++;
		supercount+=4;
	}

	int testIdx;

	for (testIdx = 0 ; testIdx < (k % 4) + 1 ; testIdx++) {
		cnt[unpackBWTValue(bwt, k/128*128 + supercount++)]++;
	}
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rdx, %rbx
cmpq $-0x1, %rsi
je 0xf1ef
movq %rsi, %r14
movq %rdi, %r12
cmpq (%rdi), %rsi
adcq $-0x1, %r14
leaq 0x7f(%r14), %rax
testq %r14, %r14
cmovnsq %r14, %rax
andq $-0x80, %rax
leaq (%rax,%rax), %r15
addq 0x120(%rdi), %r15
addq %rax, %r15
movl $0x100, %r13d           # imm = 0x100
movl $0x100, %edx            # imm = 0x100
movq %rbx, %rdi
movq %r15, %rsi
callq 0x3260
movl %r14d, %ecx
andl $0x70, %ecx
movl %r14d, %edx
andl $0xf, %edx
movl %r14d, %eax
andl $0x3, %eax
subq %rax, %rdx
andq $-0x4, %rdx
addq %r13, %rcx
addq %rdx, %rcx
movq 0x120(%r12), %rdx
cmpq %r13, %rcx
jbe 0xf207
addq %r15, %rcx
addq $0x100, %r15            # imm = 0x100
andq $-0x80, %r14
xorl %esi, %esi
movq %r14, %rdi
leaq 0x7f(%rdi), %r8
testq %rdi, %rdi
cmovnsq %rdi, %r8
andq $-0x80, %r8
leaq (%rdx,%r8,2), %r9
addq %r8, %r9
movq %rdi, %r10
subq %r8, %r10
movzbl 0x103(%r10,%r9), %r8d
incq (%rbx,%r8,8)
leaq 0x1(%rdi), %r8
leaq 0x80(%rdi), %r9
testq %r8, %r8
cmovnsq %r8, %r9
andq $-0x80, %r9
leaq (%rdx,%r9,2), %r10
addq %r9, %r10
subq %r9, %r8
andq $-0x4, %r8
movzbl 0x102(%r8,%r10), %r8d
incq (%rbx,%r8,8)
leaq 0x2(%rdi), %r8
leaq 0x81(%rdi), %r9
testq %r8, %r8
cmovnsq %r8, %r9
andq $-0x80, %r9
leaq (%rdx,%r9,2), %r10
addq %r9, %r10
subq %r9, %r8
andq $-0x4, %r8
movzbl 0x101(%r8,%r10), %r8d
incq (%rbx,%r8,8)
leaq 0x3(%rdi), %r8
leaq 0x82(%rdi), %r9
testq %r8, %r8
cmovnsq %r8, %r9
andq $-0x80, %r9
leaq (%rdx,%r9,2), %r10
addq %r9, %r10
subq %r9, %r8
andq $-0x4, %r8
movzbl 0x100(%r8,%r10), %r8d
incq (%rbx,%r8,8)
addq $0x4, %rdi
leaq (%r15,%rsi), %r8
addq $0x4, %r8
addq $0x4, %rsi
cmpq %rcx, %r8
jb 0xf115
andl $-0x4, %esi
jmp 0xf20d
movl $0x100, %edx            # imm = 0x100
movq %rbx, %rdi
xorl %esi, %esi
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x3140
andq $-0x80, %r14
xorl %esi, %esi
addq %rsi, %r14
shll $0x3, %esi
incq %rax
leaq 0x7f(%r14), %rcx
testq %r14, %r14
cmovnsq %r14, %rcx
andq $-0x80, %rcx
leaq (%rdx,%rcx,2), %rdi
addq %rcx, %rdi
movq %r14, %r8
subq %rcx, %r8
andq $-0x4, %r8
movl 0x100(%r8,%rdi), %edi
movl %esi, %ecx
notb %cl
andb $0x18, %cl
shrl %cl, %edi
movzbl %dil, %ecx
incq (%rbx,%rcx,8)
incq %r14
addl $0x8, %esi
decq %rax
jne 0xf216
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq