// File: BenLangmead[P]bowtie/sam.cpp
// Function: SAMHitSink::append(SStringExpandable<char, 25, 2, 0>&, Hit const&, int, int)
void SAMHitSink::append(BTString& o, const Hit& h, int mapq, int xms) {
	// QNAME
	if(h.mate > 0) {
		// truncate final 2 chars
		for(int i = 0; i < (int)h.patName.length()-2; i++) {
			if(!noQnameTrunc_ && isspace((int)h.patName[i])) break;
			o << h.patName[i];
		}
	} else {
		for(int i = 0; i < (int)h.patName.length(); i++) {
			if(!noQnameTrunc_ && isspace((int)h.patName[i])) break;
			o << h.patName[i];
		}
	}
	o << '\t';
	// FLAG
	int flags = 0;
	if(h.mate == 1) {
		flags |= SAM_FLAG_PAIRED | SAM_FLAG_FIRST_IN_PAIR | SAM_FLAG_MAPPED_PAIRED;
	} else if(h.mate == 2) {
		flags |= SAM_FLAG_PAIRED | SAM_FLAG_SECOND_IN_PAIR | SAM_FLAG_MAPPED_PAIRED;
	}
	if(!h.fw) flags |= SAM_FLAG_QUERY_STRAND;
	if(h.mate > 0 && !h.mfw) flags |= SAM_FLAG_MATE_STRAND;
	o << flags << "\t";
	// RNAME
	if(_refnames != NULL && h.h.first < _refnames->size()) {
		printUptoWs(o, (*_refnames)[h.h.first], !fullRef_);
	} else {
		o << h.h.first;
	}
	// POS
	o << '\t' << (h.h.second + 1);
	// MAPQ
	o << '\t' << mapq;
	// CIGAR
	o << '\t' << h.length() << 'M';
	// MRNM
	if(h.mate > 0) {
		o << "\t=";
	} else {
		o << "\t*";
	}
	// MPOS
	if(h.mate > 0) {
		o << '\t' << (h.mh.second + 1);
	} else {
		o << "\t0";
	}
	// ISIZE
	o << '\t';
	if(h.mate > 0) {
		assert_eq(h.h.first, h.mh.first);
		int64_t inslen = 0;
		if(h.h.second > h.mh.second) {
			inslen = (int64_t)h.h.second - (int64_t)h.mh.second + (int64_t)h.length();
			inslen = -inslen;
		} else {
			inslen = (int64_t)h.mh.second - (int64_t)h.h.second + (int64_t)h.mlen;
		}
		o << inslen;
	} else {
		o << '0';
	}
	// SEQ
	o << '\t';
	for(size_t i = 0; i < h.patSeq.length(); i++) {
		o << (char)h.patSeq.toChar(i);
	}
	// QUAL
	o << '\t';
	for(size_t i = 0; i < h.quals.length(); i++) {
		o << (char)h.quals[i];
	}
	//
	// Optional fields
	//
	// Always output stratum
	o << "\tXA:i:" << (int)h.stratum;
	// Always output cost
	//ss << "\tXC:i:" << (int)h.cost;
	// Look for SNP annotations falling within the alignment
	// Output MD field
	size_t len = h.patSeq.length();
	int nm = 0;
	int run = 0;
	o << "\tMD:Z:";
	const FixedBitset<1024> *mms = &h.mms;
	ASSERT_ONLY(const BTDnaString* pat = &h.patSeq);
	const EList<char>* refcs = &h.refcs;
	if(h.fw) {
		for (int i = 0; i < (int)len; ++ i) {
			if(mms->test(i)) {
				nm++;
				// There's a mismatch at this position
				assert_gt((int)refcs->size(), i);
				char refChar = toupper((*refcs)[i]);
				ASSERT_ONLY(char qryChar = (h.fw ? (*pat)[i] : (*pat)[len-i-1]));
				assert_neq(refChar, qryChar);
				o << run << refChar;
				run = 0;
			} else {
				run++;
			}
		}
	} else {
		for (int i = (int)len-1; i >= 0; -- i) {
			if(mms->test(i)) {
				nm++;
				// There's a mismatch at this position
				assert_gt((int)refcs->size(), i);
				char refChar = toupper((*refcs)[i]);
				ASSERT_ONLY(char qryChar = (h.fw ? (*pat)[i] : (*pat)[len-i-1]));
				assert_neq(refChar, qryChar);
				o << run << refChar;
				run = 0;
			} else {
				run++;
			}
		}
	}
	o << run;
	// Add optional edit distance field
	o << "\tNM:i:" << nm;
	if(xms > 0) {
		o << "\tXM:i:" << xms;
	}
	o << '\n';
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x18(%rbp), %rax
movzbl 0x188(%rax), %eax
cmpl $0x0, %eax
jle 0x85668
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x9c(%rbp)
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
callq 0x2ef90
movq %rax, %rcx
movl -0x9c(%rbp), %eax
subl $0x2, %ecx
cmpl %ecx, %eax
jge 0x85663
movq -0x98(%rbp), %rax
testb $0x1, 0x1f2(%rax)
jne 0x8562a
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
movslq -0x24(%rbp), %rsi
callq 0x49b90
movsbl (%rax), %edi
callq 0xa0a0
cmpl $0x0, %eax
je 0x8562a
jmp 0x85663
movq -0x10(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
movslq -0x24(%rbp), %rsi
callq 0x49b90
movq -0xa8(%rbp), %rdi
movsbl (%rax), %esi
callq 0x862e0
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x855d4
jmp 0x856fd
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0xac(%rbp)
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
callq 0x2ef90
movq %rax, %rcx
movl -0xac(%rbp), %eax
cmpl %ecx, %eax
jge 0x856fb
movq -0x98(%rbp), %rax
testb $0x1, 0x1f2(%rax)
jne 0x856c2
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
movslq -0x28(%rbp), %rsi
callq 0x49b90
movsbl (%rax), %edi
callq 0xa0a0
cmpl $0x0, %eax
je 0x856c2
jmp 0x856fb
movq -0x10(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
movslq -0x28(%rbp), %rsi
callq 0x49b90
movq -0xb8(%rbp), %rdi
movsbl (%rax), %esi
callq 0x862e0
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x8566f
jmp 0x856fd
movq -0x10(%rbp), %rdi
movl $0x9, %esi
callq 0x862e0
movl $0x0, -0x2c(%rbp)
movq -0x18(%rbp), %rax
movzbl 0x188(%rax), %eax
cmpl $0x1, %eax
jne 0x8572d
movl -0x2c(%rbp), %eax
orl $0x43, %eax
movl %eax, -0x2c(%rbp)
jmp 0x8574a
movq -0x18(%rbp), %rax
movzbl 0x188(%rax), %eax
cmpl $0x2, %eax
jne 0x85748
movl -0x2c(%rbp), %eax
orl $0x83, %eax
movl %eax, -0x2c(%rbp)
jmp 0x8574a
movq -0x18(%rbp), %rax
testb $0x1, 0x17c(%rax)
jne 0x85760
movl -0x2c(%rbp), %eax
orl $0x10, %eax
movl %eax, -0x2c(%rbp)
movq -0x18(%rbp), %rax
movzbl 0x188(%rax), %eax
cmpl $0x0, %eax
jle 0x85786
movq -0x18(%rbp), %rax
testb $0x1, 0x17d(%rax)
jne 0x85786
movl -0x2c(%rbp), %eax
orl $0x20, %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x86380
movq %rax, %rdi
leaq 0x90fd(%rip), %rsi      # 0x8e89a
callq 0x86190
movq -0x98(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x85825
movq -0x98(%rbp), %rax
movq -0x18(%rbp), %rcx
movl (%rcx), %ecx
movq %rcx, -0xc0(%rbp)
movq 0x10(%rax), %rdi
callq 0x26400
movq %rax, %rcx
movq -0xc0(%rbp), %rax
cmpq %rcx, %rax
jae 0x85825
movq -0x98(%rbp), %rax
movq -0x10(%rbp), %rcx
movq %rcx, -0xc8(%rbp)
movq 0x10(%rax), %rdi
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, %esi
callq 0x27460
movq -0xc8(%rbp), %rdi
movq %rax, %rsi
movq -0x98(%rbp), %rax
movb 0x1f1(%rax), %al
xorb $-0x1, %al
movzbl %al, %edx
andl $0x1, %edx
callq 0x861c0
jmp 0x85832
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x86310
movq -0x10(%rbp), %rdi
movl $0x9, %esi
callq 0x862e0
movq %rax, %rdi
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
leaq -0x30(%rbp), %rsi
callq 0x86310
movq -0x10(%rbp), %rdi
movl $0x9, %esi
callq 0x862e0
movq %rax, %rdi
leaq -0x1c(%rbp), %rsi
callq 0x86380
movq -0x10(%rbp), %rdi
movl $0x9, %esi
callq 0x862e0
movq %rax, -0xd0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x863d0
movq -0xd0(%rbp), %rdi
movq %rax, -0x38(%rbp)
leaq -0x38(%rbp), %rsi
callq 0x86280
movq %rax, %rdi
movl $0x4d, %esi
callq 0x862e0
movq -0x18(%rbp), %rax
movzbl 0x188(%rax), %eax
cmpl $0x0, %eax
jle 0x858d4
movq -0x10(%rbp), %rdi
leaq 0x8fb1(%rip), %rsi      # 0x8e87e
callq 0x86190
jmp 0x858e4
movq -0x10(%rbp), %rdi
leaq 0x8f87(%rip), %rsi      # 0x8e866
callq 0x86190
movq -0x18(%rbp), %rax
movzbl 0x188(%rax), %eax
cmpl $0x0, %eax
jle 0x8591d
movq -0x10(%rbp), %rdi
movl $0x9, %esi
callq 0x862e0
movq %rax, %rdi
movq -0x18(%rbp), %rax
movl 0xc(%rax), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
leaq -0x3c(%rbp), %rsi
callq 0x86310
jmp 0x8592d
movq -0x10(%rbp), %rdi
leaq 0x8f59(%rip), %rsi      # 0x8e881
callq 0x86190
movq -0x10(%rbp), %rdi
movl $0x9, %esi
callq 0x862e0
movq -0x18(%rbp), %rax
movzbl 0x188(%rax), %eax
cmpl $0x0, %eax
jle 0x859d7
movq $0x0, -0x48(%rbp)
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x18(%rbp), %rcx
cmpl 0xc(%rcx), %eax
jbe 0x859a5
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x18(%rbp), %rcx
movl 0xc(%rcx), %ecx
subq %rcx, %rax
movq %rax, -0xd8(%rbp)
movq -0x18(%rbp), %rdi
callq 0x863d0
movq %rax, %rcx
movq -0xd8(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x48(%rbp)
xorl %eax, %eax
subq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x859c8
movq -0x18(%rbp), %rax
movl 0xc(%rax), %eax
movq -0x18(%rbp), %rcx
movl 0x4(%rcx), %ecx
subq %rcx, %rax
movq -0x18(%rbp), %rcx
movzwl 0x17e(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x863f0
jmp 0x859e5
movq -0x10(%rbp), %rdi
movl $0x30, %esi
callq 0x862e0
movq -0x10(%rbp), %rdi
movl $0x9, %esi
callq 0x862e0
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x18(%rbp), %rdi
addq $0x48, %rdi
callq 0x2ef90
movq %rax, %rcx
movq -0xe0(%rbp), %rax
cmpq %rcx, %rax
jae 0x85a5b
movq -0x10(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0x18(%rbp), %rdi
addq $0x48, %rdi
movq -0x50(%rbp), %rsi
callq 0x45080
movq -0xe8(%rbp), %rdi
movsbl %al, %esi
callq 0x862e0
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x859fb
movq -0x10(%rbp), %rdi
movl $0x9, %esi
callq 0x862e0
movq $0x0, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x18(%rbp), %rdi
addq $0x78, %rdi
callq 0x2ef90
movq %rax, %rcx
movq -0xf0(%rbp), %rax
cmpq %rcx, %rax
jae 0x85ad1
movq -0x10(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0x18(%rbp), %rdi
addq $0x78, %rdi
movq -0x58(%rbp), %rsi
callq 0x49b90
movq -0xf8(%rbp), %rdi
movsbl (%rax), %esi
callq 0x862e0
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x85a71
movq -0x10(%rbp), %rdi
leaq 0x8da8(%rip), %rsi      # 0x8e884
callq 0x86190
movq %rax, %rdi
movq -0x18(%rbp), %rax
movsbl 0x180(%rax), %eax
movl %eax, -0x5c(%rbp)
leaq -0x5c(%rbp), %rsi
callq 0x86380
movq -0x18(%rbp), %rdi
addq $0x48, %rdi
callq 0x2ef90
movq %rax, -0x68(%rbp)
movl $0x0, -0x6c(%rbp)
movl $0x0, -0x70(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x8d66(%rip), %rsi      # 0x8e88b
callq 0x86190
movq -0x18(%rbp), %rax
addq $0xa8, %rax
movq %rax, -0x78(%rbp)
movq -0x18(%rbp), %rax
addq $0x138, %rax            # imm = 0x138
movq %rax, -0x80(%rbp)
movq -0x18(%rbp), %rax
testb $0x1, 0x17c(%rax)
je 0x85bf8
movl $0x0, -0x84(%rbp)
movl -0x84(%rbp), %eax
movq -0x68(%rbp), %rcx
cmpl %ecx, %eax
jge 0x85bf3
movq -0x78(%rbp), %rdi
movl -0x84(%rbp), %esi
callq 0x4daa0
testb $0x1, %al
jne 0x85b88
jmp 0x85bd4
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
movq -0x80(%rbp), %rdi
movslq -0x84(%rbp), %rsi
callq 0x86450
movsbl (%rax), %edi
callq 0xabf0
movb %al, -0x85(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x86380
movq %rax, %rdi
movsbl -0x85(%rbp), %esi
callq 0x862e0
movl $0x0, -0x70(%rbp)
jmp 0x85bdd
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x85bdf
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x85b61
jmp 0x85c94
movq -0x68(%rbp), %rax
subl $0x1, %eax
movl %eax, -0x8c(%rbp)
cmpl $0x0, -0x8c(%rbp)
jl 0x85c92
movq -0x78(%rbp), %rdi
movl -0x8c(%rbp), %esi
callq 0x4daa0
testb $0x1, %al
jne 0x85c27
jmp 0x85c73
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
movq -0x80(%rbp), %rdi
movslq -0x8c(%rbp), %rsi
callq 0x86450
movsbl (%rax), %edi
callq 0xabf0
movb %al, -0x8d(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x86380
movq %rax, %rdi
movsbl -0x8d(%rbp), %esi
callq 0x862e0
movl $0x0, -0x70(%rbp)
jmp 0x85c7c
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x85c7e
movl -0x8c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x85c05
jmp 0x85c94
movq -0x10(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x86380
movq -0x10(%rbp), %rdi
leaq 0x8be6(%rip), %rsi      # 0x8e892
callq 0x86190
movq %rax, %rdi
leaq -0x6c(%rbp), %rsi
callq 0x86380
cmpl $0x0, -0x20(%rbp)
jle 0x85cdf
movq -0x10(%rbp), %rdi
leaq 0x8ba9(%rip), %rsi      # 0x8e877
callq 0x86190
movq %rax, %rdi
leaq -0x20(%rbp), %rsi
callq 0x86380
movq -0x10(%rbp), %rdi
movl $0xa, %esi
callq 0x862e0
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopw %cs:(%rax,%rax)