// File: chhylp123[P]hifiasm/./Levenshtein_distance.h
// Function: gen_trace(bit_extz_t*, int, int)
inline void gen_trace(bit_extz_t *ez, int32_t ptrim, int32_t reverse)///ptrim = thre for global and extension; = 0 for semi
{
	if(ez->err > ez->thre) return;
	ez->cigar.n = 0;
	int32_t V, H, D, min, cur, tn = (ez->te+1-ez->ts), pn = tn + (ez->thre<<1), bd = (ez->thre<<1)+1;
	int32_t bs = ez->path.n/tn, bbs = bs/5, poff = ez->pe, sft = bd - (pn - ez->pe - ptrim);
	int32_t i = tn, low = bd-1, wi, wm, d = 0, pd = -1, pdn = 0; cur = ez->err;
	w_sig *D0, *VP, *VN, *HP, *HN;

	// fprintf(stderr, "\n[M::%s::] bs::%d, bbs::%d, cur::%d, poff::%d, sft::%d\n", __func__, bs, bbs, cur, poff, sft);

	while (i > 0 && cur > 0) {
		D0 = ez->path.a + ((i-1)*bs); VP = D0 + bbs; VN = VP + bbs; HP = VN + bbs; HN = HP + bbs;

		wi = (sft>>bitw); wm = sft&bitz;
		D = cur - ((~(D0[wi]>>wm))&(1ULL)); d = 0; min = D;
		H = V = INT32_MAX;
		if(sft!=low) {
            H = cur + ((HN[wi]>> wm)&(1ULL)) - ((HP[wi]>> wm)&(1ULL)); 
            if ((H+1) == cur && H <= min) {//prefer indels
                min = H; d = 3;
            }
		}
		if(sft!=0) {
			wi = ((sft-1)>>bitw); wm = (sft-1)&bitz;
			V = cur + ((VN[wi]>> wm)&(1ULL)) - ((VP[wi]>> wm)&(1ULL)); 
			if ((V+1) == cur && V <= min) {//prefer indels
				min = V; d = 2;
			}
		}
		// fprintf(stderr, "[M::%s::] cur::%d, D::%d, V::%d, H::%d, poff::%d, toff::%d, d::%d\n", __func__, cur, D, V, H, poff, i, d);
		if(d == 0) {
			if(D != cur) d = 1;
			i--; poff--;
		} else if(d == 2) {//more pstr
			sft--; poff--;
		} else if(d == 3) {///more tstr
			i--; sft++;
		}

		if(d == pd) {
			pdn++;
		} else {
			if(pdn > 0) push_trace(&(ez->cigar), pd, pdn);
			pd = d; pdn = 1;
		}
		cur = min;
	}

	if (i > 0) {
        d = 0; poff -= i;
		if(d == pd) {
			pdn += i;
		} else {
			if(pdn > 0) push_trace(&(ez->cigar), pd, pdn);
			pd = d; pdn = i;
		}
    }

	poff++;
	// fprintf(stderr, "[M::%s::] poff::%d, ez->ps::%d\n", __func__, poff, ez->ps);
	if(ez->ps < 0 || ez->ps >= ez->pl) {//ps is unavailable
		ez->ps = poff;
	} else if(poff > ez->ps){
		d = 2; i = poff - ez->ps;
		if(d == pd) {
			pdn += i;
		} else {
			if(pdn > 0) push_trace(&(ez->cigar), pd, pdn);
			pd = d; pdn = i;
		}
	}
	if(pdn > 0) push_trace(&(ez->cigar), pd, pdn);

	if(reverse) {
		uint16_t t; pdn = ez->cigar.n>>1; 
		for (i = 0; i < pdn; i++) {
			t = ez->cigar.a[i]; 
			ez->cigar.a[i] = ez->cigar.a[ez->cigar.n-i-1]; 
			ez->cigar.a[ez->cigar.n-i-1] = t;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq -0x8(%rbp), %rax
movl 0x2c(%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jle 0xc791a
jmp 0xc7e17
movq -0x8(%rbp), %rax
movq $0x0, 0xa8(%rax)
movq -0x8(%rbp), %rax
movl 0x20(%rax), %eax
addl $0x1, %eax
movq -0x8(%rbp), %rcx
subl 0x1c(%rcx), %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movq -0x8(%rbp), %rcx
movl 0x28(%rcx), %ecx
shll %ecx
addl %ecx, %eax
movl %eax, -0x2c(%rbp)
movq -0x8(%rbp), %rax
movl 0x28(%rax), %eax
shll %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0xc0(%rax), %rax
movslq -0x28(%rbp), %rcx
xorl %edx, %edx
divq %rcx
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl $0x5, %ecx
cltd
idivl %ecx
movl %eax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movl 0x14(%rax), %eax
movl %eax, -0x3c(%rbp)
movl -0x30(%rbp), %eax
movl -0x2c(%rbp), %ecx
movq -0x8(%rbp), %rdx
subl 0x14(%rdx), %ecx
subl -0xc(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x40(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x44(%rbp)
movl -0x30(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x48(%rbp)
movl $0x0, -0x54(%rbp)
movl $0xffffffff, -0x58(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x5c(%rbp)
movq -0x8(%rbp), %rax
movl 0x2c(%rax), %eax
movl %eax, -0x24(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x44(%rbp)
movb %al, -0x8b(%rbp)
jle 0xc79ea
cmpl $0x0, -0x24(%rbp)
setg %al
movb %al, -0x8b(%rbp)
movb -0x8b(%rbp), %al
testb $0x1, %al
jne 0xc79f9
jmp 0xc7c53
movq -0x8(%rbp), %rax
movq 0xd0(%rax), %rax
movl -0x44(%rbp), %ecx
subl $0x1, %ecx
imull -0x34(%rbp), %ecx
movslq %ecx, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movslq -0x38(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movslq -0x38(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movslq -0x38(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movslq -0x38(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x88(%rbp)
movl -0x40(%rbp), %eax
sarl $0x6, %eax
movl %eax, -0x4c(%rbp)
movl -0x40(%rbp), %eax
andl $0x3f, %eax
movl %eax, -0x50(%rbp)
movslq -0x24(%rbp), %rax
movq -0x68(%rbp), %rcx
movslq -0x4c(%rbp), %rdx
movq (%rcx,%rdx,8), %rdx
movl -0x50(%rbp), %ecx
shrq %cl, %rdx
movq %rdx, %rcx
xorq $-0x1, %rcx
andq $0x1, %rcx
subq %rcx, %rax
movl %eax, -0x1c(%rbp)
movl $0x0, -0x54(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x20(%rbp)
movl $0x7fffffff, -0x14(%rbp) # imm = 0x7FFFFFFF
movl $0x7fffffff, -0x18(%rbp) # imm = 0x7FFFFFFF
movl -0x40(%rbp), %eax
cmpl -0x48(%rbp), %eax
je 0xc7b2b
movslq -0x24(%rbp), %rax
movq -0x88(%rbp), %rcx
movslq -0x4c(%rbp), %rdx
movq (%rcx,%rdx,8), %rdx
movl -0x50(%rbp), %ecx
shrq %cl, %rdx
movq %rdx, %rcx
andq $0x1, %rcx
addq %rcx, %rax
movq -0x80(%rbp), %rcx
movslq -0x4c(%rbp), %rdx
movq (%rcx,%rdx,8), %rdx
movl -0x50(%rbp), %ecx
shrq %cl, %rdx
movq %rdx, %rcx
andq $0x1, %rcx
subq %rcx, %rax
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %eax
addl $0x1, %eax
cmpl -0x24(%rbp), %eax
jne 0xc7b29
movl -0x18(%rbp), %eax
cmpl -0x20(%rbp), %eax
jg 0xc7b29
movl -0x18(%rbp), %eax
movl %eax, -0x20(%rbp)
movl $0x3, -0x54(%rbp)
jmp 0xc7b2b
cmpl $0x0, -0x40(%rbp)
je 0xc7baa
movl -0x40(%rbp), %eax
subl $0x1, %eax
sarl $0x6, %eax
movl %eax, -0x4c(%rbp)
movl -0x40(%rbp), %eax
subl $0x1, %eax
andl $0x3f, %eax
movl %eax, -0x50(%rbp)
movslq -0x24(%rbp), %rax
movq -0x78(%rbp), %rcx
movslq -0x4c(%rbp), %rdx
movq (%rcx,%rdx,8), %rdx
movl -0x50(%rbp), %ecx
shrq %cl, %rdx
movq %rdx, %rcx
andq $0x1, %rcx
addq %rcx, %rax
movq -0x70(%rbp), %rcx
movslq -0x4c(%rbp), %rdx
movq (%rcx,%rdx,8), %rdx
movl -0x50(%rbp), %ecx
shrq %cl, %rdx
movq %rdx, %rcx
andq $0x1, %rcx
subq %rcx, %rax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
addl $0x1, %eax
cmpl -0x24(%rbp), %eax
jne 0xc7ba8
movl -0x14(%rbp), %eax
cmpl -0x20(%rbp), %eax
jg 0xc7ba8
movl -0x14(%rbp), %eax
movl %eax, -0x20(%rbp)
movl $0x2, -0x54(%rbp)
jmp 0xc7baa
cmpl $0x0, -0x54(%rbp)
jne 0xc7bd3
movl -0x1c(%rbp), %eax
cmpl -0x24(%rbp), %eax
je 0xc7bbf
movl $0x1, -0x54(%rbp)
movl -0x44(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x44(%rbp)
movl -0x3c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0xc7c09
cmpl $0x2, -0x54(%rbp)
jne 0xc7bed
movl -0x40(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x40(%rbp)
movl -0x3c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0xc7c07
cmpl $0x3, -0x54(%rbp)
jne 0xc7c05
movl -0x44(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x44(%rbp)
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0xc7c07
jmp 0xc7c09
movl -0x54(%rbp), %eax
cmpl -0x58(%rbp), %eax
jne 0xc7c1c
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0xc7c48
cmpl $0x0, -0x5c(%rbp)
jle 0xc7c3b
movq -0x8(%rbp), %rdi
addq $0xa8, %rdi
movl -0x58(%rbp), %eax
movl -0x5c(%rbp), %edx
movzwl %ax, %esi
callq 0xc1070
movl -0x54(%rbp), %eax
movl %eax, -0x58(%rbp)
movl $0x1, -0x5c(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0xc79cf
cmpl $0x0, -0x44(%rbp)
jle 0xc7cab
movl $0x0, -0x54(%rbp)
movl -0x44(%rbp), %ecx
movl -0x3c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x3c(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x58(%rbp), %eax
jne 0xc7c7e
movl -0x44(%rbp), %eax
addl -0x5c(%rbp), %eax
movl %eax, -0x5c(%rbp)
jmp 0xc7ca9
cmpl $0x0, -0x5c(%rbp)
jle 0xc7c9d
movq -0x8(%rbp), %rdi
addq $0xa8, %rdi
movl -0x58(%rbp), %eax
movl -0x5c(%rbp), %edx
movzwl %ax, %esi
callq 0xc1070
movl -0x54(%rbp), %eax
movl %eax, -0x58(%rbp)
movl -0x44(%rbp), %eax
movl %eax, -0x5c(%rbp)
jmp 0xc7cab
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x0, 0x10(%rax)
jl 0xc7cce
movq -0x8(%rbp), %rax
movl 0x10(%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x18(%rcx), %eax
jl 0xc7cda
movl -0x3c(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x10(%rax)
jmp 0xc7d3c
movl -0x3c(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jle 0xc7d3a
movl $0x2, -0x54(%rbp)
movl -0x3c(%rbp), %eax
movq -0x8(%rbp), %rcx
subl 0x10(%rcx), %eax
movl %eax, -0x44(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x58(%rbp), %eax
jne 0xc7d0d
movl -0x44(%rbp), %eax
addl -0x5c(%rbp), %eax
movl %eax, -0x5c(%rbp)
jmp 0xc7d38
cmpl $0x0, -0x5c(%rbp)
jle 0xc7d2c
movq -0x8(%rbp), %rdi
addq $0xa8, %rdi
movl -0x58(%rbp), %eax
movl -0x5c(%rbp), %edx
movzwl %ax, %esi
callq 0xc1070
movl -0x54(%rbp), %eax
movl %eax, -0x58(%rbp)
movl -0x44(%rbp), %eax
movl %eax, -0x5c(%rbp)
jmp 0xc7d3a
jmp 0xc7d3c
cmpl $0x0, -0x5c(%rbp)
jle 0xc7d5b
movq -0x8(%rbp), %rdi
addq $0xa8, %rdi
movl -0x58(%rbp), %eax
movl -0x5c(%rbp), %edx
movzwl %ax, %esi
callq 0xc1070
cmpl $0x0, -0x10(%rbp)
je 0xc7e17
movq -0x8(%rbp), %rax
movq 0xa8(%rax), %rax
shrq %rax
movl %eax, -0x5c(%rbp)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x5c(%rbp), %eax
jge 0xc7e15
movq -0x8(%rbp), %rax
movq 0xb8(%rax), %rax
movslq -0x44(%rbp), %rcx
movw (%rax,%rcx,2), %ax
movw %ax, -0x8a(%rbp)
movq -0x8(%rbp), %rax
movq 0xb8(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0xa8(%rcx), %rcx
movslq -0x44(%rbp), %rdx
subq %rdx, %rcx
subq $0x1, %rcx
movw (%rax,%rcx,2), %dx
movq -0x8(%rbp), %rax
movq 0xb8(%rax), %rax
movslq -0x44(%rbp), %rcx
movw %dx, (%rax,%rcx,2)
movw -0x8a(%rbp), %dx
movq -0x8(%rbp), %rax
movq 0xb8(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0xa8(%rcx), %rcx
movslq -0x44(%rbp), %rsi
subq %rsi, %rcx
subq $0x1, %rcx
movw %dx, (%rax,%rcx,2)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xc7d7d
jmp 0xc7e17
addq $0x90, %rsp
popq %rbp
retq