// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/horder.cpp
// Function: gen_mc_clus_backbone_layout(scg_t*, asg64_v*, unsigned int*, unsigned int, unsigned int*)
void gen_mc_clus_backbone_layout(scg_t *sg, asg64_v *res, uint32_t *out, uint32_t out_n, uint32_t *buf)
{
    uint64_t k, l, i, rn, n0, n1, v, z; int64_t m, s, e; osg_arc_t *t = NULL;
    kv_resize(uint64_t, *res, sg->g->n_seq); res->n = sg->g->n_seq;
    memset(res->a, 0, sizeof((*(res->a)))*res->n); rn = res->n;
    // fprintf(stderr, "[M::%s::]******Start******\n",__func__);
    
    for (k = 0; k < sg->g->n_seq; k++) {
        ///I guess this should be (!!(asg_arc_n(lg, k<<1)))^(!!(asg_arc_n(lg, (k<<1)+1)))?
        ///no, since asg_arc_n is at most 1
        n0 = asg_arc_n(sg->g, (k<<1));
        n1 = asg_arc_n(sg->g, ((k<<1)+1));
        assert((n0 <= 1) && (n1 <= 1));
        ///1&&0; 0&&0; 1&&1;
        if((n0^n1) || ((!n0) && (!n1))) {
            v = (n0?(k<<1):((k<<1)+1));
            // if(vis[k<<1] || vis[(k<<1)+1]) continue;
            // if((res->a[k]>>32) || ((uint32_t)res->a[k])) continue;
            if(res->a[k]) continue;

            // kv_pushp(lay_t, *sl, &p);
            // kv_init(*p);
            // kv_push(uint32_t, *p, v^1);
            // kv_push(uint32_t, *p, v);
            // vis[v] = vis[v^1] = 1;
            // kv_push(uint64_t, *res, (((uint64_t)((v^1)<<32))|((uint64_t)(v))|((uint64_t)(0x8000000000000000))));
            kv_push(uint64_t, *res, (((uint64_t)((v^1)<<32))|((uint64_t)(v))));
            // res->a[v>>1] |= ((uint64_t)(1))<<32;
            // res->a[v>>1] |= ((uint64_t)(1));
            res->a[v>>1] = 1;

            while (asg_arc_n(sg->g, v)) {
                v = (arc_first(sg->g, v).v)^1;
                // kv_push(uint32_t, *p, v^1);
                // kv_push(uint32_t, *p, v);
                // vis[v] = vis[v^1] = 1;
                kv_push(uint64_t, *res, ((uint64_t)((v^1)<<32))|((uint64_t)(v)));
                // res->a[v>>1] |= ((uint64_t)(1))<<32;
                // res->a[v>>1] |= ((uint64_t)(1));
                res->a[v>>1] = 1;
            }
        }
    }


    for (k = 0; k < sg->g->n_seq; k++) {
        // if(vis[k<<1] || vis[(k<<1)+1]) continue;
        // if((res->a[k]>>32) || ((uint32_t)res->a[k])) continue;
        if(res->a[k]) continue;
        n0 = asg_arc_n(sg->g, (k<<1));
        n1 = asg_arc_n(sg->g, ((k<<1)+1));
        assert((n0 == 1) && (n1 == 1));///must within a circle


        v = k<<1; t = NULL;
        while (asg_arc_n(sg->g, v)) {
            if((!t) || (t->nw > arc_first(sg->g, v).nw)) {
                t = &(arc_first(sg->g, v));
            } 
            v = (arc_first(sg->g, v).v)^1;
            if(v == (k<<1)) break;
        }

        v = t->v^1;
        // kv_pushp(lay_t, *sl, &p);
        // kv_init(*p);
        // kv_push(uint32_t, *p, v^1);
        // kv_push(uint32_t, *p, v);
        // vis[v] = vis[v^1] = 1;
        // kv_push(uint64_t, *res, (((uint64_t)((v^1)<<32))|((uint64_t)(v))|((uint64_t)(0x8000000000000000))));
        kv_push(uint64_t, *res, ((uint64_t)((v^1)<<32))|((uint64_t)(v)));
        // res->a[v>>1] |= ((uint64_t)(1))<<32;
        // res->a[v>>1] |= ((uint64_t)(1));
        res->a[v>>1] = 1;

        while (1) {
            v = (arc_first(sg->g, v).v)^1;
            // if(vis[v]) break;
            if(res->a[v>>1]) break;
            // kv_push(uint32_t, *p, v^1);
            // kv_push(uint32_t, *p, v);
            // vis[v] = vis[v^1] = 1;
            kv_push(uint64_t, *res, ((uint64_t)((v^1)<<32))|((uint64_t)(v)));
            // res->a[v>>1] |= ((uint64_t)(1))<<32;
            // res->a[v>>1] |= ((uint64_t)(1));
            res->a[v>>1] = 1;
        }
    }

    // uint32_t db_on = 0, db_z = 0;
    assert((res->n-rn) == sg->g->n_seq);
    for (l = 0, k = 1, i = 0; k <= out_n; k++) {
       if(k == out_n || out[k] == (uint32_t)-1) {
            if(k > l) {
                res->a[i++] = ((l<<32)|(k)); ///db_on += k - l;
            } else {
                assert(k == out_n);
            }
            l = k + 1;
       }
    }
    assert(i == sg->g->n_seq && i == rn);
    for (k = rn, z = 0; k < res->n; k++) {
        v = (res->a[k]>>32); 
        s = res->a[v>>1]>>32; e = (uint32_t)res->a[v>>1];
        if(!(v&1)) {
            for (m = s; m < e; m++) buf[z++] = out[m]; 
        } else {
            for (m = e-1; m >= s; m--) buf[z++] = out[m]; 
        }

        // if(e > s) {
        //     fprintf(stderr, "[M::%s::]\t#chain::%ld\tutg%.6ul->utg%.6ul\n", 
        //         __func__, (e-s), buf[z-(e-s)]+1, buf[z-1]+1);
        // }
        
        buf[z++] = (uint32_t)-1; 
        // db_z += e - s;
    }
    // if(!(z == out_n)) {
    //     fprintf(stderr, "[M::%s] sg->g->n_arc::%u, sg->g->n_seq::%u, z::%lu, out_n::%u, db_z::%u, db_on::%u\n", __func__, 
	//         sg->g->n_arc, sg->g->n_seq, z, out_n, db_z, db_on);
    // }
    assert(z == out_n);
    memcpy(out, buf, sizeof((*out))*out_n);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, %rbx
movl %ecx, 0x14(%rsp)
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %r13
movq (%rdi), %rax
movl 0x14(%rax), %edx
andl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
cmpq %rdx, 0x8(%rsi)
jae 0x13b2a4
decq %rdx
movq %rdx, %rax
shrq %rax
orq %rdx, %rax
movq %rax, %rcx
shrq $0x2, %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x4, %rax
orq %rcx, %rax
movq %rax, %rcx
shrq $0x8, %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x10, %rax
orq %rcx, %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x8(%r15)
movq 0x10(%r15), %rdi
leaq 0x8(,%rax,8), %rsi
callq 0x2370
movq %rax, %rdi
movq %rax, 0x10(%r15)
movq (%r13), %rax
movl 0x14(%rax), %edx
andl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
jmp 0x13b2a8
movq 0x10(%r15), %rdi
movabsq $0x100000000, %r12      # imm = 0x100000000
movq %rdx, (%r15)
shlq $0x3, %rdx
xorl %ebp, %ebp
xorl %esi, %esi
callq 0x20e0
movq %r12, %r11
movq (%r15), %rax
movq %rax, 0x18(%rsp)
movq (%r13), %rcx
movq %r13, %rdi
movq %r13, 0x8(%rsp)
movl 0x14(%rcx), %edx
movl %edx, %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %rbp
jae 0x13b42f
movq 0x20(%rcx), %rdx
movq %rbp, %rax
shlq $0x4, %rax
movl (%rdx,%rax), %eax
cmpq $0x1, %rax
ja 0x13b6e9
leaq (,%rbp,2), %r13
movl 0x8(%rdx,%r13,8), %edx
cmpl $0x2, %edx
jae 0x13b6e9
cmpq %rdx, %rax
sete %dl
testq %rax, %rax
setne %sil
testb %sil, %dl
jne 0x13b346
leaq 0x1(,%rbp,2), %rdx
testq %rax, %rax
cmoveq %rdx, %r13
movq 0x10(%r15), %rax
cmpq $0x0, (%rax,%rbp,8)
je 0x13b34b
incq %rbp
jmp 0x13b2d9
movq (%r15), %rcx
cmpq 0x8(%r15), %rcx
jne 0x13b388
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%r15)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movq 0x8(%rsp), %rdi
movabsq $0x100000000, %r11      # imm = 0x100000000
movq %rax, 0x10(%r15)
movq (%r15), %rcx
movq %r13, %rdx
shlq $0x20, %rdx
xorq %r11, %rdx
orq %r13, %rdx
leaq 0x1(%rcx), %rsi
movq %rsi, (%r15)
movq %rdx, (%rax,%rcx,8)
leaq (%rax,%rbp,8), %rcx
movq $0x1, (%rcx)
movq (%rdi), %rcx
movq 0x20(%rcx), %rdx
movq (%rdx,%r13,8), %rdx
testl %edx, %edx
je 0x13b346
movq 0x8(%rcx), %rcx
shrq $0x1b, %rdx
andq $-0x20, %rdx
movl (%rcx,%rdx), %r13d
movq (%r15), %rcx
cmpq 0x8(%r15), %rcx
jne 0x13b407
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%r15)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movq 0x8(%rsp), %rdi
movabsq $0x100000000, %r11      # imm = 0x100000000
movq %rax, 0x10(%r15)
movq (%r15), %rcx
xorq $0x1, %r13
leaq 0x1(%r11), %rdx
imulq %r13, %rdx
xorq %r11, %rdx
leaq 0x1(%rcx), %rsi
movq %rsi, (%r15)
movq %rdx, (%rax,%rcx,8)
movl %r13d, %ecx
shrl %ecx
leaq (%rax,%rcx,8), %rcx
jmp 0x13b3a4
xorl %edi, %edi
leaq 0x1(%r11), %rbp
movl %edx, %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %rdi
jae 0x13b5cd
movq 0x10(%r15), %rax
cmpq $0x0, (%rax,%rdi,8)
jne 0x13b5c5
movq 0x20(%rcx), %rdx
movq %rdi, %rsi
shlq $0x4, %rsi
cmpl $0x1, (%rdx,%rsi)
jne 0x13b708
movl 0x8(%rdx,%rsi), %esi
cmpl $0x1, %esi
jne 0x13b708
movq %rdi, 0x20(%rsp)
leaq (%rdi,%rdi), %rsi
movq %rsi, %r8
xorl %edi, %edi
movq (%rdx,%r8,8), %r8
testl %r8d, %r8d
je 0x13b4d0
movq 0x8(%rcx), %r9
testq %rdi, %rdi
je 0x13b4b1
movsd 0x18(%rdi), %xmm0
shrq $0x20, %r8
movq %r8, %r10
shlq $0x5, %r10
ucomisd 0x18(%r9,%r10), %xmm0
ja 0x13b4b5
jmp 0x13b4bf
shrq $0x20, %r8
movq %r8, %rdi
shlq $0x5, %rdi
addq %r9, %rdi
shlq $0x5, %r8
movl (%r9,%r8), %r8d
xorq $0x1, %r8
cmpq %r8, %rsi
jne 0x13b484
movl (%rdi), %r12d
movq (%r15), %rcx
cmpq 0x8(%r15), %rcx
jne 0x13b50b
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%r15)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movabsq $0x100000000, %r11      # imm = 0x100000000
movq %rax, 0x10(%r15)
movq (%r15), %rcx
movq 0x8(%rsp), %rdi
xorq $0x1, %r12
movq %r12, %rdx
imulq %rbp, %rdx
xorq %r11, %rdx
leaq 0x1(%rcx), %rsi
movq %rsi, (%r15)
movq %rdx, (%rax,%rcx,8)
movl %r12d, %ecx
shrl %ecx
leaq (%rax,%rcx,8), %rcx
movq $0x1, (%rcx)
movq (%rdi), %rcx
movq 0x8(%rcx), %rdx
movq 0x20(%rcx), %rsi
movl 0x4(%rsi,%r12,8), %esi
shlq $0x5, %rsi
movl (%rdx,%rsi), %r12d
movl %r12d, %r13d
shrl %r13d
cmpq $0x0, (%rax,%r13,8)
jne 0x13b5bd
movq (%r15), %rcx
cmpq 0x8(%r15), %rcx
jne 0x13b59b
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%r15)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movq 0x8(%rsp), %rdi
movabsq $0x100000000, %r11      # imm = 0x100000000
movq %rax, 0x10(%r15)
movq (%r15), %rcx
xorq $0x1, %r12
movq %r12, %rdx
imulq %rbp, %rdx
xorq %r11, %rdx
leaq 0x1(%rcx), %rsi
movq %rsi, (%r15)
movq %rdx, (%rax,%rcx,8)
leaq (%rax,%r13,8), %rcx
jmp 0x13b532
movl 0x14(%rcx), %edx
movq 0x20(%rsp), %rdi
incq %rdi
jmp 0x13b435
movq (%r15), %rdx
movq 0x18(%rsp), %r10
subq %r10, %rdx
cmpq %rax, %rdx
jne 0x13b727
movl 0x14(%rsp), %edx
movq %rdx, %rsi
negq %rsi
pushq $0x1
popq %r9
xorl %eax, %eax
xorl %edi, %edi
movq %rdi, %r8
incq %r9
movq %r9, %rdi
leaq (%rsi,%rdi), %r9
cmpq $0x2, %r9
je 0x13b64b
cmpq $0x1, %r9
je 0x13b619
cmpl $-0x1, -0x4(%r14,%rdi,4)
je 0x13b623
incq %rdi
jmp 0x13b5fc
movq %rdi, %r9
cmpq %rdx, %r8
jae 0x13b5f3
jmp 0x13b630
leaq -0x1(%rdi), %r9
cmpq %r8, %r9
jbe 0x13b784
shlq $0x20, %r8
leaq -0x1(%rdi), %r9
orq %r8, %r9
movq 0x10(%r15), %r8
movq %r9, (%r8,%rax,8)
incq %rax
movq %rdi, %r9
jmp 0x13b5f3
movl 0x14(%rcx), %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
cmpq %rcx, %rax
jne 0x13b746
cmpq %r10, %rax
jne 0x13b746
movq (%r15), %rcx
xorl %eax, %eax
cmpq %rcx, %r10
jae 0x13b6c3
movq 0x10(%r15), %rsi
movq (%rsi,%r10,8), %r8
movq %r8, %rdi
shrq $0x21, %rdi
movq (%rsi,%rdi,8), %rdi
movl %edi, %esi
shrq $0x20, %rdi
testq %r11, %r8
je 0x13b6b2
cmpq %rdi, %rsi
jle 0x13b6b7
movl -0x4(%r14,%rsi,4), %r8d
decq %rsi
movl %r8d, (%rbx,%rax,4)
incq %rax
jmp 0x13b68e
movl (%r14,%rdi,4), %r8d
movl %r8d, (%rbx,%rax,4)
incq %rax
incq %rdi
cmpq %rsi, %rdi
jb 0x13b6a4
orl $-0x1, (%rbx,%rax,4)
incq %rax
incq %r10
jmp 0x13b66b
cmpq %rdx, %rax
jne 0x13b765
shlq $0x2, %rdx
movq %r14, %rdi
movq %rbx, %rsi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2160
leaq 0xb453d(%rip), %rdi     # 0x1efc2d
leaq 0xb3ff4(%rip), %rsi     # 0x1ef6eb
leaq 0xb4546(%rip), %rcx     # 0x1efc44
movl $0x101f, %edx           # imm = 0x101F
callq 0x2110
leaq 0xb458c(%rip), %rdi     # 0x1efc9b
leaq 0xb3fd5(%rip), %rsi     # 0x1ef6eb
leaq 0xb4527(%rip), %rcx     # 0x1efc44
movl $0x1046, %edx           # imm = 0x1046
callq 0x2110
leaq 0xb4584(%rip), %rdi     # 0x1efcb2
leaq 0xb3fb6(%rip), %rsi     # 0x1ef6eb
leaq 0xb4508(%rip), %rcx     # 0x1efc44
movl $0x106d, %edx           # imm = 0x106D
callq 0x2110
leaq 0xb458c(%rip), %rdi     # 0x1efcd9
leaq 0xb3f97(%rip), %rsi     # 0x1ef6eb
leaq 0xb44e9(%rip), %rcx     # 0x1efc44
movl $0x1078, %edx           # imm = 0x1078
callq 0x2110
leaq 0xb458a(%rip), %rdi     # 0x1efcf6
leaq 0xb3f78(%rip), %rsi     # 0x1ef6eb
leaq 0xb44ca(%rip), %rcx     # 0x1efc44
movl $0x108e, %edx           # imm = 0x108E
callq 0x2110
leaq 0xb4543(%rip), %rdi     # 0x1efcce
leaq 0xb3f59(%rip), %rsi     # 0x1ef6eb
leaq 0xb44ab(%rip), %rcx     # 0x1efc44
movl $0x1073, %edx           # imm = 0x1073
callq 0x2110