// File: /workspace/github_c_makefile_star2_O2/nh13[P]ksw/src/main.c
// Function: align_with_ksw2
void align_with_ksw2(char *query, int query_length, char *target, int target_length, main_opt_t *opt, void* library_data, alignment_t *alignment) {
	int i;
	ksw2_data_t *ksw2_data = (ksw2_data_t*)library_data;

	// convert to bases in integer format
	for (i = 0; i < query_length; ++i) query[i] = seq_nt4_table[(int)query[i]];
	for (i = 0; i < target_length; ++i) target[i] = seq_nt4_table[(int)target[i]];

	switch (opt->alignment_mode) {
		case Local: fprintf(stderr, "KSW2 does not support local\n"); exit(1);
		case Glocal: fprintf(stderr, "KSW2 does not support glocal\n"); exit(1);
		case Extension: // extend
			ksw_extz2_sse(0, query_length, (uint8_t*)query, target_length, (uint8_t*)target, 5, ksw2_data->matrix, opt->gap_open, opt->gap_extend, opt->band_width, -1, ksw2_data->ksw2_flags | KSW_EZ_EXTZ_ONLY, &ksw2_data->ez);
			alignment->score   = ksw2_data->ez.mqe; // maximum score when we reach the end of the query
			if (ksw2_data->ez.max_q < 0) {
				alignment->qlb = -1;
				alignment->qle = -1;
				alignment->tlb = -1;
				alignment->tle = -1;
			}
			else {
				alignment->qlb = 0;
				alignment->tlb = 0;
				alignment->qle = ksw2_data->ez.max_q;
				alignment->tle = ksw2_data->ez.max_t;
			}
			break;
		case Global: // global
			ksw_extz2_sse(0, query_length, (uint8_t*)query, target_length, (uint8_t*)target, 5, ksw2_data->matrix, opt->gap_open, opt->gap_extend, opt->band_width, -1, ksw2_data->ksw2_flags, &ksw2_data->ez);
			alignment->score = ksw2_data->ez.score;
			alignment->qlb = 0;
			alignment->tlb = 0;
			alignment->qle   = query_length-1;
			alignment->tle   = target_length-1;
			break;
		default:
			fprintf(stderr, "Unknown alignment mode in %s: %d\n", __func__, opt->alignment_mode); 
			exit(1);
	}

	// copy cigar
	if (opt->add_cigar == 1) {
		if (alignment->m_cigar < ksw2_data->ez.m_cigar) {
			alignment->m_cigar = ksw2_data->ez.m_cigar;
			alignment->cigar = (uint32_t*)realloc(alignment->cigar, alignment->m_cigar*sizeof(uint32_t));
		}
		for (i = 0; i < ksw2_data->ez.n_cigar; i++) {
			alignment->cigar[i] = ksw2_data->ez.cigar[i];
		}
		alignment->n_cigar = ksw2_data->ez.n_cigar;
	}

	// convert back to bases
	for (i = 0; i < query_length; ++i) query[i] = "ACGTN"[(int)query[i]];
	for (i = 0; i < target_length; ++i) target[i] = "ACGTN"[(int)target[i]];
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %r9, %r15
movl %ecx, %r10d
movq %rdx, %rbx
movq %rdi, %r14
movq 0x80(%rsp), %r13
xorl %ecx, %ecx
testl %esi, %esi
movl $0x0, %r12d
cmovgl %esi, %r12d
leaq 0x594951(%rip), %rax    # 0x73b120
cmpq %rcx, %r12
je 0x1a67e5
movsbq (%r14,%rcx), %rdx
movb (%rdx,%rax), %dl
movb %dl, (%r14,%rcx)
incq %rcx
jmp 0x1a67cf
xorl %ecx, %ecx
testl %r10d, %r10d
movl $0x0, %ebp
cmovgl %r10d, %ebp
cmpq %rcx, %rbp
je 0x1a6808
movsbq (%rbx,%rcx), %rdx
movb (%rdx,%rax), %dl
movb %dl, (%rbx,%rcx)
incq %rcx
jmp 0x1a67f3
movl 0x20(%r8), %ecx
cmpq $0x3, %rcx
ja 0x1a6a05
leaq 0x3c1bf3(%rip), %rax    # 0x568410
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
movq %r8, 0x38(%rsp)
jmpq *%rcx
movq (%r15), %rax
movsbl 0x8(%r8), %ecx
movsbl 0xc(%r8), %edx
movl 0x10(%r8), %r9d
movl 0x8(%r15), %edi
orl $0x40, %edi
leaq 0x10(%r15), %r8
movq %r8, 0x30(%rsp)
movl %edi, 0x28(%rsp)
movl %r9d, 0x18(%rsp)
movl %edx, 0x10(%rsp)
movl %ecx, 0x8(%rsp)
orl $-0x1, 0x20(%rsp)
movq %rax, (%rsp)
pushq $0x5
popq %r9
xorl %edi, %edi
movq %r14, %rdx
movl %r10d, %ecx
movq %rbx, %r8
callq 0x1a3578
movl 0x1c(%r15), %eax
movl %eax, (%r13)
movl 0x14(%r15), %eax
testl %eax, %eax
js 0x1a6932
andq $0x0, 0x4(%r13)
movl %eax, 0xc(%r13)
movl 0x18(%r15), %eax
movl %eax, 0x10(%r13)
jmp 0x1a693e
movq (%r15), %rax
movsbl 0x8(%r8), %ecx
movsbl 0xc(%r8), %edx
movl 0x10(%r8), %r9d
movl 0x8(%r15), %edi
leaq 0x10(%r15), %r8
movq %r8, 0x30(%rsp)
movl %edi, 0x28(%rsp)
movl %r9d, 0x18(%rsp)
movl %edx, 0x10(%rsp)
movl %ecx, 0x8(%rsp)
orl $-0x1, 0x20(%rsp)
movq %rax, (%rsp)
pushq $0x5
popq %r9
xorl %edi, %edi
movq %r14, %rdx
movl %r10d, %ecx
movq %rbx, %r8
movl %r10d, 0x44(%rsp)
movl %esi, %r13d
callq 0x1a3578
movq 0x38(%rsp), %rdx
movl 0x2c(%r15), %eax
movq 0x80(%rsp), %rcx
movl %eax, (%rcx)
movq 0x80(%rsp), %rax
andq $0x0, 0x4(%rax)
decl %r13d
movl %r13d, 0xc(%rax)
movl 0x44(%rsp), %ecx
decl %ecx
movl %ecx, 0x10(%rax)
movq 0x80(%rsp), %r13
jmp 0x1a6943
leaq 0x4(%r13), %rax
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, (%rax)
movq 0x38(%rsp), %rdx
cmpl $0x1, 0x24(%rdx)
jne 0x1a698d
movl 0x30(%r15), %eax
cmpl %eax, 0x24(%r13)
jge 0x1a696b
movslq %eax, %rsi
movl %esi, 0x24(%r13)
movq 0x18(%r13), %rdi
shlq $0x2, %rsi
callq 0x19e1e0
movq %rax, 0x18(%r13)
xorl %eax, %eax
movslq 0x34(%r15), %rcx
cmpq %rcx, %rax
jge 0x1a6989
movq 0x38(%r15), %rcx
movl (%rcx,%rax,4), %ecx
movq 0x18(%r13), %rdx
movl %ecx, (%rdx,%rax,4)
incq %rax
jmp 0x1a696d
movl %ecx, 0x20(%r13)
xorl %ecx, %ecx
leaq 0x3c1c04(%rip), %rax    # 0x56859a
cmpq %rcx, %r12
je 0x1a69ac
movsbq (%r14,%rcx), %rdx
movb (%rdx,%rax), %dl
movb %dl, (%r14,%rcx)
incq %rcx
jmp 0x1a6996
xorl %ecx, %ecx
cmpq %rcx, %rbp
je 0x1a69c3
movsbq (%rbx,%rcx), %rdx
movb (%rdx,%rax), %dl
movb %dl, (%rbx,%rcx)
incq %rcx
jmp 0x1a69ae
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x5945ff(%rip), %rax    # 0x73afd8
movq (%rax), %rcx
leaq 0x3c1e51(%rip), %rdi    # 0x568834
pushq $0x1c
jmp 0x1a69fa
movq 0x5945ea(%rip), %rax    # 0x73afd8
movq (%rax), %rcx
leaq 0x3c1e59(%rip), %rdi    # 0x568851
pushq $0x1d
popq %rsi
pushq $0x1
popq %rdx
callq 0x19e200
jmp 0x1a6a24
movq 0x5945cc(%rip), %rax    # 0x73afd8
movq (%rax), %rdi
leaq 0x3c1b8a(%rip), %rsi    # 0x5685a0
leaq 0x3c1e52(%rip), %rdx    # 0x56886f
xorl %eax, %eax
callq 0x19e180
pushq $0x1
popq %rdi
callq 0x19e130