// File: BenLangmead[P]bowtie/./aligner_metrics.h
// Function: AlignerMetrics::entropyDna5(SDnaStringExpandable<25, 2> const&)
inline float entropyDna5(const BTDnaString& read) {
		size_t cs[5] = {0, 0, 0, 0, 0};
		size_t readLen = read.length();
		for(size_t i = 0; i < readLen; i++) {
			int c = (int)read[i];
			assert_lt(c, 5);
			assert_geq(c, 0);
			cs[c]++;
		}
		if(cs[4] > 0) {
			// Charge the Ns to the non-N character with maximal count and
			// then exclude them from the entropy calculation (i.e.,
			// penalize Ns as much as possible)
			if(cs[0] >= cs[1] && cs[0] >= cs[2] && cs[0] >= cs[3]) {
				// Charge Ns to As
				cs[0] += cs[4];
			} else if(cs[1] >= cs[2] && cs[1] >= cs[3]) {
				// Charge Ns to Cs
				cs[1] += cs[4];
			} else if(cs[2] >= cs[3]) {
				// Charge Ns to Gs
				cs[2] += cs[4];
			} else {
				// Charge Ns to Ts
				cs[3] += cs[4];
			}
		}
		float ent = 0.0;
		for(int i = 0; i < 4; i++) {
			if(cs[i] > 0) {
				float frac = (float)cs[i] / (float)readLen;
				ent += (frac * log(frac));
			}
		}
		ent = -ent;
		assert_geq(ent, 0.0);
		return ent;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x28, %edx
callq 0xa2c0
movq -0x10(%rbp), %rdi
callq 0x2ef90
movq %rax, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x48(%rbp), %rax
jae 0x4fcf5
movq -0x10(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x4fea0
movsbl (%rax), %eax
movl %eax, -0x54(%rbp)
movslq -0x54(%rbp), %rax
movq -0x40(%rbp,%rax,8), %rcx
addq $0x1, %rcx
movq %rcx, -0x40(%rbp,%rax,8)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x4fcb8
cmpq $0x0, -0x20(%rbp)
jbe 0x4fd74
movq -0x40(%rbp), %rax
cmpq -0x38(%rbp), %rax
jb 0x4fd28
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
jb 0x4fd28
movq -0x40(%rbp), %rax
cmpq -0x28(%rbp), %rax
jb 0x4fd28
movq -0x20(%rbp), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x4fd72
movq -0x38(%rbp), %rax
cmpq -0x30(%rbp), %rax
jb 0x4fd4a
movq -0x38(%rbp), %rax
cmpq -0x28(%rbp), %rax
jb 0x4fd4a
movq -0x20(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x4fd70
movq -0x30(%rbp), %rax
cmpq -0x28(%rbp), %rax
jb 0x4fd62
movq -0x20(%rbp), %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
jmp 0x4fd6e
movq -0x20(%rbp), %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0x4fd70
jmp 0x4fd72
jmp 0x4fd74
xorps %xmm0, %xmm0
movss %xmm0, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
cmpl $0x4, -0x5c(%rbp)
jge 0x4fe6f
movslq -0x5c(%rbp), %rax
cmpq $0x0, -0x40(%rbp,%rax,8)
jbe 0x4fe5f
movslq -0x5c(%rbp), %rax
movq -0x40(%rbp,%rax,8), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x68(%rbp)
testq %rax, %rax
movss %xmm0, -0x64(%rbp)
js 0x4fddb
movss -0x68(%rbp), %xmm0
movss %xmm0, -0x64(%rbp)
movss -0x64(%rbp), %xmm0
movss %xmm0, -0x74(%rbp)
movq -0x48(%rbp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x70(%rbp)
testq %rax, %rax
movss %xmm0, -0x6c(%rbp)
js 0x4fe1e
movss -0x70(%rbp), %xmm0
movss %xmm0, -0x6c(%rbp)
movss -0x74(%rbp), %xmm0
movss -0x6c(%rbp), %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x60(%rbp)
movss -0x60(%rbp), %xmm0
movss %xmm0, -0x78(%rbp)
movss -0x60(%rbp), %xmm0
callq 0x4ffa0
movaps %xmm0, %xmm2
movss -0x78(%rbp), %xmm0
movss -0x58(%rbp), %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x58(%rbp)
jmp 0x4fe61
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x4fd83
movss -0x58(%rbp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss %xmm0, -0x58(%rbp)
movss -0x58(%rbp), %xmm0
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nop