// File: /workspace/github_cpp_makefile_star2_O3/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, %rcx
movq %rsi, %r15
movq %rdi, %r12
movq (%rdi), %rax
movl 0x14(%rax), %edx
andl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
cmpq %rdx, 0x8(%rsi)
movq %rcx, 0x18(%rsp)
jae 0x17def8
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 (%r12), %rax
movl 0x14(%rax), %edx
andl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
jmp 0x17defc
movq 0x10(%r15), %rdi
movabsq $0x100000000, %rbp      # imm = 0x100000000
movq %rdx, (%r15)
shlq $0x3, %rdx
xorl %r14d, %r14d
xorl %esi, %esi
callq 0x20e0
movq (%r15), %rax
movq %rax, 0x20(%rsp)
movq (%r12), %rcx
movl 0x14(%rcx), %esi
testl $0x7fffffff, %esi       # imm = 0x7FFFFFFF
je 0x17e24c
movq %r12, 0x8(%rsp)
xorl %r12d, %r12d
movl $0x2, %r13d
movq 0x20(%rcx), %rdx
movq %r12, %rax
shlq $0x4, %rax
movl (%rdx,%rax), %eax
cmpq $0x1, %rax
ja 0x17e37e
leaq (%r12,%r12), %r14
movl 0x8(%rdx,%r14,8), %esi
cmpl $0x2, %esi
jae 0x17e37e
cmpq %rsi, %rax
sete %sil
testq %rax, %rax
setne %dil
testb %dil, %sil
jne 0x17df97
leaq 0x1(,%r12,2), %rsi
testq %rax, %rax
cmoveq %rsi, %r14
movq 0x10(%r15), %rax
cmpq $0x0, (%rax,%r12,8)
je 0x17dfae
incq %r12
movl 0x14(%rcx), %esi
movl %esi, %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %r12
jb 0x17df40
jmp 0x17e07d
movq (%r15), %rdi
cmpq 0x8(%r15), %rdi
jne 0x17dfe5
leaq (%rdi,%rdi), %rsi
testq %rdi, %rdi
cmoveq %r13, %rsi
movq %rsi, 0x8(%r15)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movq %rax, 0x10(%r15)
movq (%r15), %rdi
movq 0x8(%rsp), %rcx
movq (%rcx), %rcx
movq 0x20(%rcx), %rdx
movq %r14, %rsi
shlq $0x20, %rsi
xorq %rbp, %rsi
orq %r14, %rsi
leaq 0x1(%rdi), %r8
movq %r8, (%r15)
movq %rsi, (%rax,%rdi,8)
movq $0x1, (%rax,%r12,8)
movq (%rdx,%r14,8), %rdx
testl %edx, %edx
je 0x17df97
movq 0x8(%rcx), %rsi
shrq $0x1b, %rdx
andq $-0x20, %rdx
movl (%rsi,%rdx), %r14d
movq (%r15), %rdx
cmpq 0x8(%r15), %rdx
jne 0x17e050
leaq (%rdx,%rdx), %rsi
testq %rdx, %rdx
cmoveq %r13, %rsi
movq %rsi, 0x8(%r15)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movq %rax, 0x10(%r15)
movq (%r15), %rdx
movq 0x8(%rsp), %rcx
movq (%rcx), %rcx
xorq $0x1, %r14
leaq 0x1(%rbp), %rsi
imulq %r14, %rsi
xorq %rbp, %rsi
leaq 0x1(%rdx), %rdi
movq %rdi, (%r15)
movq %rsi, (%rax,%rdx,8)
movl %r14d, %edx
shrl %edx
movq $0x1, (%rax,%rdx,8)
movq 0x20(%rcx), %rdx
jmp 0x17e005
testl %eax, %eax
je 0x17e249
movq 0x10(%r15), %rax
xorl %r12d, %r12d
leaq 0x1(%rbp), %r13
cmpq $0x0, (%rax,%r12,8)
jne 0x17e224
movq 0x20(%rcx), %rdx
movq %r12, %rsi
shlq $0x4, %rsi
cmpl $0x1, (%rdx,%rsi)
jne 0x17e39d
movl 0x8(%rdx,%rsi), %esi
cmpl $0x1, %esi
jne 0x17e39d
leaq (%r12,%r12), %rsi
movq %rsi, %r8
xorl %edi, %edi
movq (%rdx,%r8,8), %r8
testl %r8d, %r8d
je 0x17e112
movq 0x8(%rcx), %r9
testq %rdi, %rdi
je 0x17e0f3
movsd 0x18(%rdi), %xmm0
shrq $0x20, %r8
movq %r8, %r10
shlq $0x5, %r10
ucomisd 0x18(%r9,%r10), %xmm0
ja 0x17e0f7
jmp 0x17e101
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 0x17e0c6
movl (%rdi), %r14d
movq (%r15), %rdi
cmpq 0x8(%r15), %rdi
jne 0x17e151
leaq (%rdi,%rdi), %rsi
testq %rdi, %rdi
movl $0x2, %ecx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%r15)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movq %rax, 0x10(%r15)
movq (%r15), %rdi
movq 0x8(%rsp), %rcx
movq (%rcx), %rcx
movq 0x20(%rcx), %rdx
xorq $0x1, %r14
movq %r14, %rsi
imulq %r13, %rsi
xorq %rbp, %rsi
leaq 0x1(%rdi), %r8
movq %r8, (%r15)
movq %rsi, (%rax,%rdi,8)
movl %r14d, %esi
shrl %esi
movq $0x1, (%rax,%rsi,8)
movq 0x8(%rcx), %rsi
movl 0x4(%rdx,%r14,8), %edx
shlq $0x5, %rdx
movl (%rsi,%rdx), %ebp
movl %ebp, %r14d
shrl %r14d
cmpq $0x0, (%rax,%r14,8)
jne 0x17e224
xorq $0x1, %rbp
movq (%r15), %rdx
cmpq 0x8(%r15), %rdx
jne 0x17e1d4
leaq (%rdx,%rdx), %rsi
testq %rdx, %rdx
movl $0x2, %ecx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%r15)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movq %rax, 0x10(%r15)
movq (%r15), %rdx
movq 0x8(%rsp), %rcx
movq (%rcx), %rcx
movq %rbp, %rsi
imulq %r13, %rsi
movabsq $0x100000000, %rdi      # imm = 0x100000000
xorq %rdi, %rsi
leaq 0x1(%rdx), %rdi
movq %rdi, (%r15)
movq %rsi, (%rax,%rdx,8)
movq $0x1, (%rax,%r14,8)
movq 0x8(%rcx), %rdx
movq 0x20(%rcx), %rsi
movl 0x4(%rsi,%rbp,8), %esi
shlq $0x5, %rsi
movl (%rdx,%rsi), %r14d
movq %r14, %rbp
xorq $0x1, %rbp
shrl %r14d
cmpq $0x0, (%rax,%r14,8)
je 0x17e19c
incq %r12
movl 0x14(%rcx), %esi
movl %esi, %r14d
andl $0x7fffffff, %r14d      # imm = 0x7FFFFFFF
cmpq %r14, %r12
movabsq $0x100000000, %rbp      # imm = 0x100000000
jb 0x17e090
jmp 0x17e24c
xorl %r14d, %r14d
movq (%r15), %rax
movq 0x20(%rsp), %r12
subq %r12, %rax
cmpq %r14, %rax
jne 0x17e3db
movl 0x14(%rsp), %eax
movl %eax, %edx
testl %eax, %eax
movq 0x18(%rsp), %rdi
je 0x17e2c1
leaq 0x1(%rdx), %rsi
movl $0x1, %r10d
xorl %r8d, %r8d
xorl %eax, %eax
cmpq %rdx, %r10
jne 0x17e28a
cmpq %rdx, %r8
jb 0x17e29f
jmp 0x17e2b1
cmpl $-0x1, (%rdi,%r10,4)
je 0x17e296
incq %r10
jmp 0x17e2b7
cmpq %r8, %r10
jbe 0x17e3bc
shlq $0x20, %r8
orq %r10, %r8
movq 0x10(%r15), %r9
movq %r8, (%r9,%rax,8)
incq %rax
incq %r10
movq %r10, %r8
cmpq %rsi, %r10
jne 0x17e27e
movl 0x14(%rcx), %esi
jmp 0x17e2c3
xorl %eax, %eax
andl $0x7fffffff, %esi       # imm = 0x7FFFFFFF
cmpq %rsi, %rax
jne 0x17e3fa
cmpq %r12, %rax
jne 0x17e3fa
movq (%r15), %rcx
cmpq %rcx, %r12
jae 0x17e359
movq 0x10(%r15), %rsi
xorl %eax, %eax
movq (%rsi,%r12,8), %r9
movq %r9, %r8
shrq $0x21, %r8
movq (%rsi,%r8,8), %r8
movl %r8d, %r14d
shrq $0x20, %r8
testq %rbp, %r9
jne 0x17e32c
cmpl %r8d, %r14d
jbe 0x17e345
subq %r8, %r14
leaq (%rdi,%r8,4), %r8
leaq (%rbx,%rax,4), %r10
xorl %r9d, %r9d
movl (%r8,%r9,4), %r11d
movl %r11d, (%r10,%r9,4)
incq %r9
cmpq %r9, %r14
jne 0x17e317
addq %r9, %rax
jmp 0x17e345
cmpl %r8d, %r14d
jbe 0x17e345
movl -0x4(%rdi,%r14,4), %r9d
decq %r14
movl %r9d, (%rbx,%rax,4)
incq %rax
cmpq %r8, %r14
jg 0x17e331
movl $0xffffffff, (%rbx,%rax,4) # imm = 0xFFFFFFFF
incq %rax
incq %r12
cmpq %rcx, %r12
jne 0x17e2e9
jmp 0x17e35b
xorl %eax, %eax
cmpq %rdx, %rax
jne 0x17e419
shlq $0x2, %rdx
movq %rbx, %rsi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2160
leaq 0xbf9e8(%rip), %rdi     # 0x23dd6d
leaq 0xbf49f(%rip), %rsi     # 0x23d82b
leaq 0xbf9f1(%rip), %rcx     # 0x23dd84
movl $0x101f, %edx           # imm = 0x101F
callq 0x2110
leaq 0xbfa37(%rip), %rdi     # 0x23dddb
leaq 0xbf480(%rip), %rsi     # 0x23d82b
leaq 0xbf9d2(%rip), %rcx     # 0x23dd84
movl $0x1046, %edx           # imm = 0x1046
callq 0x2110
leaq 0xbfa4b(%rip), %rdi     # 0x23de0e
leaq 0xbf461(%rip), %rsi     # 0x23d82b
leaq 0xbf9b3(%rip), %rcx     # 0x23dd84
movl $0x1073, %edx           # imm = 0x1073
callq 0x2110
leaq 0xbfa10(%rip), %rdi     # 0x23ddf2
leaq 0xbf442(%rip), %rsi     # 0x23d82b
leaq 0xbf994(%rip), %rcx     # 0x23dd84
movl $0x106d, %edx           # imm = 0x106D
callq 0x2110
leaq 0xbfa18(%rip), %rdi     # 0x23de19
leaq 0xbf423(%rip), %rsi     # 0x23d82b
leaq 0xbf975(%rip), %rcx     # 0x23dd84
movl $0x1078, %edx           # imm = 0x1078
callq 0x2110
leaq 0xbfa16(%rip), %rdi     # 0x23de36
leaq 0xbf404(%rip), %rsi     # 0x23d82b
leaq 0xbf956(%rip), %rcx     # 0x23dd84
movl $0x108e, %edx           # imm = 0x108E
callq 0x2110