// File: BenLangmead[P]bowtie/./ebwt_search_util.h
// Function: PartialAlignmentManager::toMutsString(PartialAlignment const&, SDnaStringExpandable<25, 2> const&, SStringExpandable<char, 25, 2, 0> const&, EList<QueryMutation, 128>&, bool)
static uint8_t toMutsString(const PartialAlignment& pal,
	                            const BTDnaString& seq,
	                            const BTString& quals,
	                            EList<QueryMutation>& muts,
	                            bool maqPenalty = true)
	{
		muts.reserveExact(4);
		assert_eq(0, muts.size());
		uint32_t plen = (uint32_t)seq.length();
		assert_gt(plen, 0);
		assert_neq(1, pal.unk.type);
		// Do first mutation
		uint8_t oldQuals = 0;
		uint32_t pos0 = pal.entry.pos0;
		assert_lt(pos0, plen);
		uint16_t tpos0 = plen-1-pos0;
		uint32_t chr0 = pal.entry.char0;
		uint8_t oldChar = (uint8_t)seq[tpos0];
		uint8_t oldQual0 = mmPenalty(maqPenalty, phredCharToPhredQual(quals[tpos0]));
		assert_leq(oldQual0, 99);
		oldQuals += oldQual0; // take quality hit
		muts.push_back(QueryMutation(tpos0, oldChar, chr0));
		if(pal.entry.pos1 != 0xffff) {
			// Do second mutation
			uint32_t pos1 = pal.entry.pos1;
			assert_lt(pos1, plen);
			uint16_t tpos1 = plen-1-pos1;
			uint32_t chr1 = pal.entry.char1;
			oldChar = (uint8_t)seq[tpos1];
			uint8_t oldQual1 = mmPenalty(maqPenalty, phredCharToPhredQual(quals[tpos1]));
			assert_leq(oldQual1, 99);
			oldQuals += oldQual1; // take quality hit
			assert_neq(tpos1, tpos0);
			muts.push_back(QueryMutation(tpos1, oldChar, chr1));
			if(pal.entry.pos2 != 0xffff) {
				// Do second mutation
				uint32_t pos2 = pal.entry.pos2;
				assert_lt(pos2, plen);
				uint16_t tpos2 = plen-1-pos2;
				uint32_t chr2 = pal.entry.char2;
				oldChar = (uint8_t)seq[tpos2];
				uint8_t oldQual2 = mmPenalty(maqPenalty, phredCharToPhredQual(quals[tpos2]));
				assert_leq(oldQual2, 99);
				oldQuals += oldQual2; // take quality hit
				assert_neq(tpos2, tpos0);
				assert_neq(tpos2, tpos1);
				muts.push_back(QueryMutation(tpos2, oldChar, chr2)); // apply mutation
			}
		}
		assert_gt(muts.size(), 0);
		assert_leq(muts.size(), 3);
		return oldQuals;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movb %r8b, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
andb $0x1, %al
movb %al, -0x21(%rbp)
movq -0x20(%rbp), %rdi
movl $0x4, %esi
callq 0x6c020
movq -0x10(%rbp), %rdi
callq 0x2ef90
movl %eax, -0x28(%rbp)
movb $0x0, -0x29(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
andq $0xffff, %rax           # imm = 0xFFFF
movl %eax, -0x30(%rbp)
movl -0x28(%rbp), %eax
subl $0x1, %eax
subl -0x30(%rbp), %eax
movw %ax, -0x32(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
shrq $0x30, %rax
andq $0x3, %rax
movl %eax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movzwl -0x32(%rbp), %eax
movl %eax, %esi
callq 0x4fea0
movb (%rax), %al
movb %al, -0x39(%rbp)
movb -0x21(%rbp), %al
movb %al, -0x71(%rbp)
movq -0x18(%rbp), %rdi
movzwl -0x32(%rbp), %eax
movl %eax, %esi
callq 0x49b90
movsbl (%rax), %edi
callq 0x1fb10
movb -0x71(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %edi
movzbl %al, %esi
callq 0x1fad0
movb %al, -0x3a(%rbp)
movzbl -0x3a(%rbp), %ecx
movzbl -0x29(%rbp), %eax
addl %ecx, %eax
movb %al, -0x29(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x70(%rbp)
movw -0x32(%rbp), %dx
movb -0x39(%rbp), %cl
movl -0x38(%rbp), %eax
leaq -0x3e(%rbp), %rdi
movzwl %dx, %esi
movzbl %cl, %edx
movzbl %al, %ecx
callq 0x6c0d0
movq -0x70(%rbp), %rdi
leaq -0x3e(%rbp), %rsi
callq 0x6c060
movq -0x8(%rbp), %rax
movq (%rax), %rax
shrq $0x10, %rax
andq $0xffff, %rax           # imm = 0xFFFF
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x6688b
movq -0x8(%rbp), %rax
movq (%rax), %rax
shrq $0x10, %rax
andq $0xffff, %rax           # imm = 0xFFFF
movl %eax, -0x44(%rbp)
movl -0x28(%rbp), %eax
subl $0x1, %eax
subl -0x44(%rbp), %eax
movw %ax, -0x46(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
shrq $0x32, %rax
andq $0x3, %rax
movl %eax, -0x4c(%rbp)
movq -0x10(%rbp), %rdi
movzwl -0x46(%rbp), %eax
movl %eax, %esi
callq 0x4fea0
movb (%rax), %al
movb %al, -0x39(%rbp)
movb -0x21(%rbp), %al
movb %al, -0x81(%rbp)
movq -0x18(%rbp), %rdi
movzwl -0x46(%rbp), %eax
movl %eax, %esi
callq 0x49b90
movsbl (%rax), %edi
callq 0x1fb10
movb -0x81(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %edi
movzbl %al, %esi
callq 0x1fad0
movb %al, -0x4d(%rbp)
movzbl -0x4d(%rbp), %ecx
movzbl -0x29(%rbp), %eax
addl %ecx, %eax
movb %al, -0x29(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x80(%rbp)
movw -0x46(%rbp), %dx
movb -0x39(%rbp), %cl
movl -0x4c(%rbp), %eax
leaq -0x52(%rbp), %rdi
movzwl %dx, %esi
movzbl %cl, %edx
movzbl %al, %ecx
callq 0x6c0d0
movq -0x80(%rbp), %rdi
leaq -0x52(%rbp), %rsi
callq 0x6c060
movq -0x8(%rbp), %rax
movq (%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x66889
movq -0x8(%rbp), %rax
movq (%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
movl %eax, -0x58(%rbp)
movl -0x28(%rbp), %eax
subl $0x1, %eax
subl -0x58(%rbp), %eax
movw %ax, -0x5a(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
shrq $0x34, %rax
andq $0x3, %rax
movl %eax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
movzwl -0x5a(%rbp), %eax
movl %eax, %esi
callq 0x4fea0
movb (%rax), %al
movb %al, -0x39(%rbp)
movb -0x21(%rbp), %al
movb %al, -0x91(%rbp)
movq -0x18(%rbp), %rdi
movzwl -0x5a(%rbp), %eax
movl %eax, %esi
callq 0x49b90
movsbl (%rax), %edi
callq 0x1fb10
movb -0x91(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %edi
movzbl %al, %esi
callq 0x1fad0
movb %al, -0x61(%rbp)
movzbl -0x61(%rbp), %ecx
movzbl -0x29(%rbp), %eax
addl %ecx, %eax
movb %al, -0x29(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x90(%rbp)
movw -0x5a(%rbp), %dx
movb -0x39(%rbp), %cl
movl -0x60(%rbp), %eax
leaq -0x66(%rbp), %rdi
movzwl %dx, %esi
movzbl %cl, %edx
movzbl %al, %ecx
callq 0x6c0d0
movq -0x90(%rbp), %rdi
leaq -0x66(%rbp), %rsi
callq 0x6c060
jmp 0x6688b
movb -0x29(%rbp), %al
addq $0xa0, %rsp
popq %rbp
retq
nopw (%rax,%rax)