// File: BenLangmead[P]bowtie/./ebwt.h
// Function: EbwtSearchParams::reportHit(SDnaStringExpandable<25, 2> const&, SStringExpandable<char, 25, 2, 0>*, SStringExpandable<char, 25, 2, 0>*, bool, EList<unsigned int, 128> const&, EList<unsigned char, 128> const&, unsigned long, std::pair<unsigned int, unsigned int>, std::pair<unsigned int, unsigned int>, bool, unsigned short, std::pair<unsigned int, unsigned int>, unsigned int, unsigned int, int, unsigned short, unsigned int, unsigned int, unsigned int, unsigned char) const
bool reportHit(const BTDnaString& query, // read sequence
	               BTString* quals, // read quality values
	               BTString* name,  // read name
	               bool ebwtFw,         // whether index is forward (true) or mirror (false)
	               const EList<TIndexOffU>& mmui32, // mismatch list
	               const EList<uint8_t>& refcs,  // reference characters
	               size_t numMms,      // # mismatches
	               UPair h,          // ref coords
	               UPair mh,         // mate's ref coords
	               bool mfw,           // mate's orientation
	               uint16_t mlen,      // mate length
	               UPair a,          // arrow pair
	               uint32_t tlen,      // length of text
	               uint32_t qlen,      // length of query
	               int stratum,        // alignment stratum
	               uint16_t cost,      // cost of alignment
	               uint32_t oms,       // approx. # other valid alignments
	               uint32_t patid,
	               uint32_t seed,
	               uint8_t mate) const
	{
#ifndef NDEBUG
		// Check that no two elements of the mms array are the same
		for(size_t i = 0; i < numMms; i++) {
			for(size_t j = i+1; j < numMms; j++) {
				assert_neq(mmui32[i], mmui32[j]);
			}
		}
#endif
		// If ebwtFw is true, then 'query' and 'quals' are reversed
		// If _fw is false, then 'query' and 'quals' are reverse complemented
		assert(quals != NULL);
		assert(name != NULL);
		assert_eq(mmui32.size(), refcs.size());
		assert_leq(numMms, mmui32.size());
		assert_gt(qlen, 0);
		Hit hit;
		hit.stratum = stratum;
		hit.cost = cost;
		hit.patSeq = query;
		hit.quals = *quals;
		if(!ebwtFw) {
			// Re-reverse the pattern and the quals back to how they
			// appeared in the read file
			hit.patSeq.reverse();
			hit.quals.reverse();
		}
		// Turn the mmui32 and refcs arrays into the mm FixedBitset and
		// the refc vector
		hit.refcs.resize(qlen);
		hit.refcs.fillZero();
		for(size_t i = 0; i < numMms; i++) {
			if (ebwtFw != _fw) {
				// The 3' end is on the left but the mm vector encodes
				// mismatches w/r/t the 5' end, so we flip
				uint32_t off = qlen - mmui32[i] - 1;
				hit.mms.set(off);
				hit.refcs[off] = refcs[i];
			} else {
				hit.mms.set(mmui32[i]);
				hit.refcs[mmui32[i]] = refcs[i];
			}
		}
		// Check the hit against the original text, if it's available
		if(_texts.size() > 0) {
			assert_lt(h.first, _texts.size());
			FixedBitset<1024> diffs;
			// This type of check assumes that only mismatches are
			// possible.  If indels are possible, then we either need
			// the caller to provide information about indel locations,
			// or we need to extend this to a more complicated check.
			assert_leq(h.second + qlen, _texts[h.first].length());
			for(size_t i = 0; i < qlen; i++) {
				assert_neq(4, (int)_texts[h.first][h.second + i]);
				// Forward pattern appears at h
				if((int)hit.patSeq[i] != (int)_texts[h.first][h.second + i]) {
					uint32_t qoff = (uint32_t)i;
					// if ebwtFw != _fw the 3' end is on on the
					// left end of the pattern, but the diff vector
					// should encode mismatches w/r/t the 5' end,
					// so we flip
					if (_fw) diffs.set(qoff);
					else     diffs.set(qlen - qoff - 1);
				}
			}
			if(diffs != hit.mms) {
				// Oops, mismatches were not where we expected them;
				// print a diagnostic message before asserting
				cerr << "Expected " << hit.mms.str() << " mismatches, got " << diffs.str() << endl;
				cerr << "  Pat:  " << hit.patSeq << endl;
				cerr << "  Tseg: ";
				for(size_t i = 0; i < qlen; i++) {
					cerr << _texts[h.first][h.second + i];
				}
				cerr << endl;
				cerr << "  mmui32: ";
				for(size_t i = 0; i < numMms; i++) {
					cerr << mmui32[i] << " ";
				}
				cerr << endl;
				cerr << "  FW: " << _fw << endl;
				cerr << "  Ebwt FW: " << ebwtFw << endl;
			}
			if(diffs != hit.mms) assert(false);
		}
		hit.h = h;
		hit.patId = ((patid == 0xffffffff) ? _patid : patid);
		hit.patName = *name;
		hit.mh = mh;
		hit.fw = _fw;
		hit.mfw = mfw;
		hit.mlen = mlen;
		hit.oms = oms;
		hit.mate = mate;
		hit.seed = seed;
		assert(hit.repOk());
		return sink().reportHit(hit, stratum);
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x410, %rsp            # imm = 0x410
movl %r8d, %eax
movq %rcx, -0x2f0(%rbp)
movq %rdx, %rcx
movq -0x2f0(%rbp), %rdx
movq %rcx, -0x2e8(%rbp)
movq %rsi, %rcx
movq -0x2e8(%rbp), %rsi
movq %rcx, -0x2e0(%rbp)
movq %rdi, %r8
movq -0x2e0(%rbp), %rdi
movb %al, %cl
movb 0x80(%rbp), %al
movl 0x78(%rbp), %eax
movl 0x70(%rbp), %eax
movl 0x68(%rbp), %eax
movw 0x60(%rbp), %ax
movl 0x58(%rbp), %eax
movl 0x50(%rbp), %eax
movl 0x48(%rbp), %eax
movq 0x40(%rbp), %rax
movw 0x38(%rbp), %ax
movb 0x30(%rbp), %al
movq 0x28(%rbp), %r10
movq 0x20(%rbp), %r10
movq 0x18(%rbp), %r10
movq 0x10(%rbp), %r10
movq %r8, -0x8(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
andb $0x1, %cl
movb %cl, -0x21(%rbp)
movq %r9, -0x30(%rbp)
andb $0x1, %al
movb %al, -0x31(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x2d8(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x38b80
movb 0x58(%rbp), %al
movb %al, -0x48(%rbp)
movzwl 0x60(%rbp), %eax
movl %eax, -0x44(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x180(%rbp), %rdi
callq 0x35e50
jmp 0x4ccaf
movq -0x18(%rbp), %rsi
leaq -0x150(%rbp), %rdi
callq 0x2e7e0
jmp 0x4ccc1
testb $0x1, -0x21(%rbp)
jne 0x4ccfc
leaq -0x180(%rbp), %rdi
callq 0x4d520
jmp 0x4ccd5
leaq -0x150(%rbp), %rdi
callq 0x4d520
jmp 0x4cce3
jmp 0x4ccfc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d0(%rbp)
movl %eax, -0x1d4(%rbp)
jmp 0x4d4a4
leaq -0x90(%rbp), %rdi
movl 0x50(%rbp), %eax
movl %eax, %esi
callq 0x4d5c0
jmp 0x4cd0f
leaq -0x90(%rbp), %rdi
callq 0x4d640
jmp 0x4cd1d
movq $0x0, -0x1e0(%rbp)
movq -0x1e0(%rbp), %rax
cmpq 0x18(%rbp), %rax
jae 0x4ced6
movq -0x2d8(%rbp), %rcx
movb -0x21(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movb 0x14(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
cmpl %ecx, %eax
je 0x4ce01
movl 0x50(%rbp), %eax
movl %eax, -0x2fc(%rbp)
movq -0x30(%rbp), %rdi
movq -0x1e0(%rbp), %rsi
callq 0x4d670
movq %rax, -0x2f8(%rbp)
jmp 0x4cd7b
movl -0x2fc(%rbp), %ecx
movq -0x2f8(%rbp), %rax
movl (%rax), %eax
notl %eax
addl %ecx, %eax
movl %eax, -0x1e4(%rbp)
leaq -0x120(%rbp), %rdi
movl -0x1e4(%rbp), %esi
callq 0x4d6a0
jmp 0x4cda8
movq 0x10(%rbp), %rdi
movq -0x1e0(%rbp), %rsi
callq 0x4d700
movq %rax, -0x308(%rbp)
jmp 0x4cdc1
movq -0x308(%rbp), %rax
movb (%rax), %al
movb %al, -0x311(%rbp)
leaq -0x90(%rbp), %rdi
movl -0x1e4(%rbp), %eax
movl %eax, %esi
callq 0x4d720
movq %rax, -0x310(%rbp)
jmp 0x4cded
movq -0x310(%rbp), %rax
movb -0x311(%rbp), %cl
movb %cl, (%rax)
jmp 0x4cebd
leaq -0x120(%rbp), %rax
movq %rax, -0x328(%rbp)
movq -0x30(%rbp), %rdi
movq -0x1e0(%rbp), %rsi
callq 0x4d670
movq %rax, -0x320(%rbp)
jmp 0x4ce28
movq -0x328(%rbp), %rdi
movq -0x320(%rbp), %rax
movl (%rax), %esi
callq 0x4d6a0
jmp 0x4ce3f
movq 0x10(%rbp), %rdi
movq -0x1e0(%rbp), %rsi
callq 0x4d700
movq %rax, -0x330(%rbp)
jmp 0x4ce58
movq -0x330(%rbp), %rax
movb (%rax), %al
movb %al, -0x341(%rbp)
leaq -0x90(%rbp), %rax
movq %rax, -0x340(%rbp)
movq -0x30(%rbp), %rdi
movq -0x1e0(%rbp), %rsi
callq 0x4d670
movq %rax, -0x338(%rbp)
jmp 0x4ce8e
movq -0x340(%rbp), %rdi
movq -0x338(%rbp), %rax
movl (%rax), %eax
movl %eax, %esi
callq 0x4d720
movq %rax, -0x350(%rbp)
jmp 0x4ceae
movq -0x350(%rbp), %rax
movb -0x341(%rbp), %cl
movb %cl, (%rax)
jmp 0x4cebf
movq -0x1e0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x1e0(%rbp)
jmp 0x4cd28
movq -0x2d8(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x250e0
movq %rax, -0x358(%rbp)
jmp 0x4ceef
movq -0x358(%rbp), %rax
cmpq $0x0, %rax
jbe 0x4d3c4
leaq -0x270(%rbp), %rdi
callq 0x38c90
jmp 0x4cf0e
movq $0x0, -0x278(%rbp)
movq -0x278(%rbp), %rax
movl 0x50(%rbp), %ecx
cmpq %rcx, %rax
jae 0x4d016
leaq -0x180(%rbp), %rdi
movq -0x278(%rbp), %rsi
callq 0x403a0
movq %rax, -0x360(%rbp)
jmp 0x4cf48
movq -0x2d8(%rbp), %rax
movq -0x360(%rbp), %rcx
movsbl (%rcx), %ecx
movl %ecx, -0x36c(%rbp)
movq 0x8(%rax), %rdi
movl 0x20(%rbp), %eax
movl %eax, %esi
callq 0x25100
movq %rax, -0x368(%rbp)
jmp 0x4cf76
movq -0x368(%rbp), %rdi
movl 0x24(%rbp), %eax
movl %eax, %esi
movq -0x278(%rbp), %rax
addq %rax, %rsi
callq 0x25150
movq %rax, -0x378(%rbp)
jmp 0x4cf9a
movl -0x36c(%rbp), %eax
movq -0x378(%rbp), %rcx
movsbl (%rcx), %ecx
cmpl %ecx, %eax
je 0x4cffd
movq -0x2d8(%rbp), %rax
movq -0x278(%rbp), %rcx
movl %ecx, -0x27c(%rbp)
testb $0x1, 0x14(%rax)
je 0x4cfde
movl -0x27c(%rbp), %esi
leaq -0x270(%rbp), %rdi
callq 0x4d6a0
jmp 0x4cfdc
jmp 0x4cffb
movl 0x50(%rbp), %eax
movl -0x27c(%rbp), %esi
notl %esi
addl %eax, %esi
leaq -0x270(%rbp), %rdi
callq 0x4d6a0
jmp 0x4cff9
jmp 0x4cffb
jmp 0x4cffd
jmp 0x4cfff
movq -0x278(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x278(%rbp)
jmp 0x4cf19
leaq -0x120(%rbp), %rsi
leaq -0x270(%rbp), %rdi
callq 0x4d740
movb %al, -0x379(%rbp)
jmp 0x4d031
movb -0x379(%rbp), %al
testb $0x1, %al
jne 0x4d040
jmp 0x4d399
movq 0x5afa9(%rip), %rdi     # 0xa7ff0
leaq 0x3fe05(%rip), %rsi     # 0x8ce53
callq 0xa5d0
movq %rax, -0x388(%rbp)
jmp 0x4d05c
leaq -0x120(%rbp), %rsi
leaq -0x2a0(%rbp), %rdi
callq 0x4d7a0
jmp 0x4d071
movq -0x388(%rbp), %rdi
leaq -0x2a0(%rbp), %rsi
callq 0xa540
movq %rax, -0x390(%rbp)
jmp 0x4d08d
movq -0x390(%rbp), %rdi
leaq 0x3fdc2(%rip), %rsi     # 0x8ce5d
callq 0xa5d0
movq %rax, -0x398(%rbp)
jmp 0x4d0a9
leaq -0x2c0(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x4d7a0
jmp 0x4d0be
movq -0x398(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0xa540
movq %rax, -0x3a0(%rbp)
jmp 0x4d0da
movq -0x3a0(%rbp), %rdi
movq 0x5ae80(%rip), %rsi     # 0xa7f68
callq 0xa640
jmp 0x4d0ef
leaq -0x2c0(%rbp), %rdi
callq 0xacd8
leaq -0x2a0(%rbp), %rdi
callq 0xacd8
movq 0x5aee2(%rip), %rdi     # 0xa7ff0
leaq 0x3fd5a(%rip), %rsi     # 0x8ce6f
callq 0xa5d0
movq %rax, -0x3a8(%rbp)
jmp 0x4d123
movq -0x3a8(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x2c0d0
movq %rax, -0x3b0(%rbp)
jmp 0x4d13f
movq -0x3b0(%rbp), %rdi
movq 0x5ae1b(%rip), %rsi     # 0xa7f68
callq 0xa640
jmp 0x4d154
movq 0x5ae95(%rip), %rdi     # 0xa7ff0
leaq 0x3fd16(%rip), %rsi     # 0x8ce78
callq 0xa5d0
jmp 0x4d169
movq $0x0, -0x2c8(%rbp)
movq -0x2c8(%rbp), %rax
movl 0x50(%rbp), %ecx
cmpq %rcx, %rax
jae 0x4d23d
movq -0x2d8(%rbp), %rax
movq 0x8(%rax), %rdi
movl 0x20(%rbp), %eax
movl %eax, %esi
callq 0x25100
movq %rax, -0x3b8(%rbp)
jmp 0x4d1a5
movq -0x3b8(%rbp), %rdi
movl 0x24(%rbp), %eax
movl %eax, %esi
movq -0x2c8(%rbp), %rax
addq %rax, %rsi
callq 0x25150
movq %rax, -0x3c0(%rbp)
jmp 0x4d1c9
movq -0x3c0(%rbp), %rax
movsbl (%rax), %esi
movq 0x5ae16(%rip), %rdi     # 0xa7ff0
callq 0xa720
jmp 0x4d1e1
jmp 0x4d1e3
movq -0x2c8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x2c8(%rbp)
jmp 0x4d174
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d0(%rbp)
movl %eax, -0x1d4(%rbp)
jmp 0x4d22c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1d0(%rbp)
movl %eax, -0x1d4(%rbp)
leaq -0x2c0(%rbp), %rdi
callq 0xacd8
leaq -0x2a0(%rbp), %rdi
callq 0xacd8
jmp 0x4d4a4
movq 0x5adac(%rip), %rdi     # 0xa7ff0
movq 0x5ad1d(%rip), %rsi     # 0xa7f68
callq 0xa640
jmp 0x4d252
movq 0x5ad97(%rip), %rdi     # 0xa7ff0
leaq 0x3fc21(%rip), %rsi     # 0x8ce81
callq 0xa5d0
jmp 0x4d267
movq $0x0, -0x2d0(%rbp)
movq -0x2d0(%rbp), %rax
cmpq 0x18(%rbp), %rax
jae 0x4d2e1
movq -0x30(%rbp), %rdi
movq -0x2d0(%rbp), %rsi
callq 0x4d670
movq %rax, -0x3c8(%rbp)
jmp 0x4d298
movq -0x3c8(%rbp), %rax
movl (%rax), %esi
movq 0x5ad48(%rip), %rdi     # 0xa7ff0
callq 0xa810
movq %rax, -0x3d0(%rbp)
jmp 0x4d2b6
movq -0x3d0(%rbp), %rdi
leaq 0x3fe40(%rip), %rsi     # 0x8d104
callq 0xa5d0
jmp 0x4d2cb
jmp 0x4d2cd
movq -0x2d0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x2d0(%rbp)
jmp 0x4d272
movq 0x5ad08(%rip), %rdi     # 0xa7ff0
movq 0x5ac79(%rip), %rsi     # 0xa7f68
callq 0xa640
jmp 0x4d2f6
movq 0x5acf3(%rip), %rdi     # 0xa7ff0
leaq 0x3fb88(%rip), %rsi     # 0x8ce8c
callq 0xa5d0
movq %rax, -0x3d8(%rbp)
jmp 0x4d312
movq -0x3d8(%rbp), %rdi
movq -0x2d8(%rbp), %rax
movzbl 0x14(%rax), %esi
andl $0x1, %esi
callq 0xab80
movq %rax, -0x3e0(%rbp)
jmp 0x4d335
movq -0x3e0(%rbp), %rdi
movq 0x5ac25(%rip), %rsi     # 0xa7f68
callq 0xa640
jmp 0x4d34a
movq 0x5ac9f(%rip), %rdi     # 0xa7ff0
leaq 0x3fb3b(%rip), %rsi     # 0x8ce93
callq 0xa5d0
movq %rax, -0x3e8(%rbp)
jmp 0x4d366
movq -0x3e8(%rbp), %rdi
movzbl -0x21(%rbp), %esi
andl $0x1, %esi
callq 0xab80
movq %rax, -0x3f0(%rbp)
jmp 0x4d382
movq -0x3f0(%rbp), %rdi
movq 0x5abd8(%rip), %rsi     # 0xa7f68
callq 0xa640
jmp 0x4d397
jmp 0x4d399
leaq -0x120(%rbp), %rsi
leaq -0x270(%rbp), %rdi
callq 0x4d740
movb %al, -0x3f1(%rbp)
jmp 0x4d3b4
movb -0x3f1(%rbp), %al
testb $0x1, %al
jne 0x4d3c0
jmp 0x4d3c2
jmp 0x4d3c2
jmp 0x4d3c4
leaq -0x1c8(%rbp), %rdi
leaq 0x20(%rbp), %rsi
callq 0x36310
cmpl $-0x1, 0x70(%rbp)
jne 0x4d3ec
movq -0x2d8(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x3f8(%rbp)
jmp 0x4d3f5
movl 0x70(%rbp), %eax
movl %eax, -0x3f8(%rbp)
movl -0x3f8(%rbp), %eax
movl %eax, -0x1b8(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x1b0(%rbp), %rdi
callq 0x2e7e0
jmp 0x4d413
leaq -0x1c0(%rbp), %rdi
leaq 0x28(%rbp), %rsi
callq 0x36310
movq -0x2d8(%rbp), %rdi
movb 0x14(%rdi), %al
andb $0x1, %al
movb %al, -0x4c(%rbp)
movb -0x31(%rbp), %al
andb $0x1, %al
movb %al, -0x4b(%rbp)
movw 0x38(%rbp), %ax
movw %ax, -0x4a(%rbp)
movl 0x68(%rbp), %eax
movl %eax, -0x50(%rbp)
movb 0x80(%rbp), %al
movb %al, -0x40(%rbp)
movl 0x78(%rbp), %eax
movl %eax, -0x3c(%rbp)
callq 0x4d8e0
movq %rax, -0x400(%rbp)
jmp 0x4d465
movq -0x400(%rbp), %rdi
movl 0x58(%rbp), %edx
movq (%rdi), %rax
movq 0x28(%rax), %rax
leaq -0x1c8(%rbp), %rsi
callq *%rax
movb %al, -0x401(%rbp)
jmp 0x4d487
leaq -0x1c8(%rbp), %rdi
callq 0x37450
movb -0x401(%rbp), %al
andb $0x1, %al
addq $0x410, %rsp            # imm = 0x410
popq %rbp
retq
leaq -0x1c8(%rbp), %rdi
callq 0x37450
movq -0x1d0(%rbp), %rdi
callq 0xab60
nopl (%rax)