// File: /workspace/github_c_makefile_star2_O1/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 %r12
pushq %rbx
pushq %rax
movq %rdx, %rbx
cmpq $-0x1, %rsi
je 0xef44
movq %rsi, %r14
movq %rdi, %r15
cmpq (%rdi), %rsi
adcq $-0x1, %r14
leaq 0x7f(%r14), %rax
testq %r14, %r14
cmovnsq %r14, %rax
andq $-0x80, %rax
leaq (%rax,%rax), %r12
addq 0x120(%rdi), %r12
addq %rax, %r12
movl $0x100, %edx            # imm = 0x100
movq %rbx, %rdi
movq %r12, %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 %rdx, %rcx
addq $0x100, %rcx            # imm = 0x100
cmpq $0x101, %rcx            # imm = 0x101
jb 0xef5e
addq %r12, %rcx
addq $0x100, %r12            # imm = 0x100
movq %r14, %rsi
andq $-0x80, %rsi
movq 0x120(%r15), %rdi
xorl %edx, %edx
leaq 0x7f(%rsi), %r8
testq %rsi, %rsi
cmovnsq %rsi, %r8
andq $-0x80, %r8
leaq (%rdi,%r8,2), %r9
addq %r8, %r9
movq %rsi, %r10
subq %r8, %r10
movzbl 0x103(%r10,%r9), %r8d
incq (%rbx,%r8,8)
leaq 0x1(%rsi), %r8
leaq 0x80(%rsi), %r9
testq %r8, %r8
cmovnsq %r8, %r9
andq $-0x80, %r9
leaq (%rdi,%r9,2), %r10
addq %r9, %r10
subq %r9, %r8
andq $-0x4, %r8
movzbl 0x102(%r8,%r10), %r8d
incq (%rbx,%r8,8)
leaq 0x2(%rsi), %r8
leaq 0x81(%rsi), %r9
testq %r8, %r8
cmovnsq %r8, %r9
andq $-0x80, %r9
leaq (%rdi,%r9,2), %r10
addq %r9, %r10
subq %r9, %r8
andq $-0x4, %r8
movzbl 0x101(%r8,%r10), %r8d
incq (%rbx,%r8,8)
leaq 0x3(%rsi), %r8
leaq 0x82(%rsi), %r9
testq %r8, %r8
cmovnsq %r8, %r9
andq $-0x80, %r9
leaq (%rdi,%r9,2), %r10
addq %r9, %r10
subq %r9, %r8
andq $-0x4, %r8
movzbl 0x100(%r8,%r10), %r8d
incq (%rbx,%r8,8)
addq $0x4, %rsi
leaq (%r12,%rdx), %r8
addq $0x4, %r8
addq $0x4, %rdx
cmpq %rcx, %r8
jb 0xee6a
andl $-0x4, %edx
jmp 0xef60
movl $0x100, %edx            # imm = 0x100
movq %rbx, %rdi
xorl %esi, %esi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x3140
xorl %edx, %edx
andq $-0x80, %r14
movq 0x120(%r15), %rsi
addq %rdx, %r14
shll $0x3, %edx
incq %rax
leaq 0x7f(%r14), %rcx
testq %r14, %r14
cmovnsq %r14, %rcx
andq $-0x80, %rcx
leaq (%rsi,%rcx,2), %rdi
addq %rcx, %rdi
movq %r14, %r8
subq %rcx, %r8
andq $-0x4, %r8
movl 0x100(%r8,%rdi), %edi
movl %edx, %ecx
notb %cl
andb $0x18, %cl
shrl %cl, %edi
movzbl %dil, %ecx
incq (%rbx,%rcx,8)
incq %r14
addl $0x8, %edx
decq %rax
jne 0xef74
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq