// File: /workspace/github_c_makefile_star2_O2/asford[P]tmalign/./NW.h
// Function: NWDP_TM(int, int, double, int*)
void NWDP_TM(int len1, int len2, double gap_open, int j2i[])
{
	//NW dynamic programming for alignment
	//not a standard implementation of NW algorithm
    //Input: score[1:len1, 1:len2], and gap_open
    //Output: j2i[1:len2] \in {1:len1} U {-1}
	//path[0:len1, 0:len2]=1,2,3, from diagonal, horizontal, vertical

	int i, j;
	double h, v, d;

	//initialization
	val[0][0]=0;
	for(i=0; i<=len1; i++)
	{
		val[i][0]=0;
		path[i][0]=false; //not from diagonal
	}

	for(j=0; j<=len2; j++)
	{
		val[0][j]=0;
		path[0][j]=false; //not from diagonal
		j2i[j]=-1;	//all are not aligned, only use j2i[1:len2]
	}      

	
	//decide matrix and path
	for(i=1; i<=len1; i++)	
	{	
		for(j=1; j<=len2; j++)
		{
			d=val[i-1][j-1]+score[i][j]; //diagonal

			//symbol insertion in horizontal (= a gap in vertical)
			h=val[i-1][j];
			if(path[i-1][j]) //aligned in last position
				h += gap_open;				

			//symbol insertion in vertical
			v=val[i][j-1];
			if(path[i][j-1]) //aligned in last position
				v += gap_open;


			if(d>=h && d>=v)
			{
				path[i][j]=true; //from diagonal
				val[i][j]=d;
			}
			else 
			{
				path[i][j]=false; //from horizontal
				if(v>=h)
					val[i][j]=v;
				else					
					val[i][j]=h;
			}
		} //for i
	} //for j

	//trace back to extract the alignment
	i=len1;
    j=len2;
	while(i>0 && j>0)
	{
		if(path[i][j]) //from diagonal
		{
			j2i[j-1]=i-1;		
			i--;
			j--;
		}
		else 			
		{
			h=val[i-1][j];
			if(path[i-1][j]) h +=gap_open;

			v=val[i][j-1];
			if(path[i][j-1]) v +=gap_open;

			if(v>=h)
				j--;
			else
				i--;
		}
	}	
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq 0x1fcf00(%rip), %rax    # 0x6025a8
movq (%rax), %rcx
andq $0x0, (%rcx)
movq 0x1fceea(%rip), %r8     # 0x6025a0
movslq %edi, %r9
xorl %r10d, %r10d
cmpq %r9, %r10
jg 0x4056d6
movq (%rax,%r10,8), %r11
andq $0x0, (%r11)
movq (%r8,%r10,8), %r11
movb $0x0, (%r11)
incq %r10
jmp 0x4056bc
movq 0x1fcec3(%rip), %r8     # 0x6025a0
movslq %esi, %r9
xorl %r10d, %r10d
cmpq %r9, %r10
jg 0x4056ff
andq $0x0, (%rcx,%r10,8)
movq (%r8), %r11
movb $0x0, (%r11,%r10)
orl $-0x1, (%rdx,%r10,4)
incq %r10
jmp 0x4056e3
xorl %ecx, %ecx
testl %esi, %esi
movl $0x0, %r8d
cmovgl %esi, %r8d
testl %edi, %edi
cmovgl %edi, %ecx
incl %ecx
movabsq $0x1, %r9
cmpq %rcx, %r9
je 0x4057ce
movq 0x1fce6a(%rip), %r10    # 0x602598
movq 0x1fce6b(%rip), %r11    # 0x6025a0
xorl %ebx, %ebx
cmpq %rbx, %r8
je 0x4057c6
movq -0x8(%rax,%r9,8), %r15
movsd 0x8(%r15,%rbx,8), %xmm1
movq -0x8(%r11,%r9,8), %r14
cmpb $0x0, 0x1(%r14,%rbx)
je 0x40575d
addsd %xmm0, %xmm1
movq (%rax,%r9,8), %r14
movq (%r11,%r9,8), %r12
movsd (%r14,%rbx,8), %xmm2
cmpb $0x0, (%r12,%rbx)
je 0x405776
addsd %xmm0, %xmm2
movq (%r10,%r9,8), %r13
movsd 0x8(%r13,%rbx,8), %xmm3
addsd (%r15,%rbx,8), %xmm3
ucomisd %xmm1, %xmm3
jb 0x4057a2
ucomisd %xmm2, %xmm3
jb 0x4057a2
movb $0x1, 0x1(%r12,%rbx)
movsd %xmm3, 0x8(%r14,%rbx,8)
jmp 0x4057be
movb $0x0, 0x1(%r12,%rbx)
ucomisd %xmm1, %xmm2
jae 0x4057b7
movsd %xmm1, 0x8(%r14,%rbx,8)
jmp 0x4057be
movsd %xmm2, 0x8(%r14,%rbx,8)
incq %rbx
jmp 0x405737
incq %r9
jmp 0x40571e
movq 0x1fcdcb(%rip), %rcx    # 0x6025a0
movl %esi, %r8d
decl %esi
movl %edi, %edi
testl %edi, %edi
jle 0x405841
testl %r8d, %r8d
jle 0x405841
movq (%rcx,%rdi,8), %r10
cmpb $0x1, (%r10,%r8)
je 0x405834
leaq -0x1(%rdi), %r9
movl %r9d, %r11d
shlq $0x3, %r11
movq (%rax,%r11), %rbx
movsd (%rbx,%r8,8), %xmm1
movq (%rcx,%r11), %r11
cmpb $0x0, (%r11,%r8)
je 0x405814
addsd %xmm0, %xmm1
movq (%rax,%rdi,8), %r11
movsd (%r11,%rsi,8), %xmm2
cmpb $0x0, (%r10,%rsi)
je 0x405829
addsd %xmm0, %xmm2
ucomisd %xmm1, %xmm2
jae 0x4057d5
movq %r9, %rdi
jmp 0x4057dc
decl %edi
movl %edi, -0x4(%rdx,%r8,4)
leal -0x1(%r8), %esi
jmp 0x4057d5
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq