// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/Correct.cpp
// Function: gen_gov_idx(overlap_region_alloc*, ul_idx_t const*, ug_opt_t const*, long, double, asg64_v*)
void gen_gov_idx(overlap_region_alloc* ol, const ul_idx_t *uref, const ug_opt_t *uopt, int64_t bw, double diff_ec_ul, asg64_v* idx)
{
    int64_t on = ol->length, k, i; uint64_t os, oe, ovlp; ul_ov_t p, q, *li, *lj;
    kv_resize(uint64_t, *idx, (uint64_t)on); memset(idx->a, 0, sizeof(*(idx->a))*on);
    for (k = 0, idx->n = on; k < on; k++) {
        convert_ul_ov_t(&p, &(ol->list[k]), uref->ug); p.qn = k; 
        // idx->a[k] = idx->n; idx->a[k] <<= 32;
        for (i = on - 1; i >= 0 && i > k && ol->list[i].x_pos_e >= ol->list[k].x_pos_s; i--) {
            // if(k >= i) continue;
            convert_ul_ov_t(&q, &(ol->list[i]), uref->ug); q.qn = i;

            if(p.qe > q.qe) li = &p, lj = &q;
			else if(p.qe == q.qe && p.qs >= q.qs) li = &p, lj = &q;
			else lj = &p, li = &q;
			os = MAX(li->qs, lj->qs), oe = MIN(li->qe, lj->qe);
			ovlp = ((oe > os)? (oe - os):0);
			if(!ovlp) continue;//no overlap

            if(lj->qs <= li->qs+G_CHAIN_INDEL) {
				if(govlp_check(uref, uopt, bw, diff_ec_ul, li, lj)) {
                    idx->a[k]++; idx->a[i]++; 
                    kv_push(uint64_t, *idx, (((uint64_t)k)<<32)|((uint64_t)i));
                    kv_push(uint64_t, *idx, (((uint64_t)i)<<32)|((uint64_t)k));
                }
			} else if((lj->qe+G_CHAIN_INDEL>=li->qe) && (lj->qs+G_CHAIN_INDEL>=li->qs)) {
				if(govlp_check(uref, uopt, bw, diff_ec_ul, lj, li)) {
                    idx->a[k]++; idx->a[i]++; 
                    kv_push(uint64_t, *idx, (((uint64_t)k)<<32)|((uint64_t)i));
                    kv_push(uint64_t, *idx, (((uint64_t)i)<<32)|((uint64_t)k));
                }
			}
        }
    }
    radix_sort_bc64(idx->a + on, idx->a + idx->n);
    for (k = 0, os = oe = on; k < on; k++) {
        oe = os + idx->a[k];
        idx->a[k] = (os<<32)|oe;
        os = oe;
    }

    // for (k = 0; k < on; k++) {
    //     int64_t s, e;
    //     s = idx->a[k]>>32; e = (uint32_t)idx->a[k];
    //     for (i = s; i < e; i++) {
    //         assert((idx->a[i]>>32) == (uint32_t)k);
    //         fprintf(stderr, "k::%ld[M::%s::utg%.6dl] utg%.6dl\n", k, __func__, 
    //             (int32_t)ol->list[k].y_id+1, (int32_t)ol->list[(uint32_t)idx->a[i]].y_id+1);
    //     }
    // }   
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %r8, %rbx
movsd %xmm0, 0x48(%rsp)
movq %rcx, 0x40(%rsp)
movq %rdx, 0x38(%rsp)
movq %rsi, 0x8(%rsp)
movq %rdi, 0x50(%rsp)
movq 0x10(%rdi), %r14
cmpq %r14, 0x8(%r8)
jae 0x3d9d5
leaq -0x1(%r14), %rax
movq %rax, %rcx
shrq %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x2, %rax
orq %rcx, %rax
movq %rax, %rcx
shrq $0x4, %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x8, %rax
orq %rcx, %rax
movq %rax, %rcx
shrq $0x10, %rcx
orq %rax, %rcx
leaq 0x1(%rcx), %rax
movq %rax, 0x8(%rbx)
movq 0x10(%rbx), %rdi
leaq 0x8(,%rcx,8), %rsi
callq 0x2370
movq %rax, %rdi
movq %rax, 0x10(%rbx)
jmp 0x3d9d9
movq 0x10(%rbx), %rdi
movabsq $-0x100000000, %r13     # imm = 0xFFFFFFFF00000000
leaq (,%r14,8), %rdx
xorl %r15d, %r15d
xorl %esi, %esi
callq 0x20e0
movq %r14, (%rbx)
testq %r14, %r14
movl $0x0, %r12d
cmovgq %r14, %r12
leaq -0x1(%r14), %rax
movq %rax, 0x70(%rsp)
movq %r14, %rax
shlq $0x20, %rax
addq %r13, %rax
movq %rax, 0x68(%rsp)
movq %r14, 0x58(%rsp)
imulq $0xa8, %r14, %rax
addq $-0xa8, %rax
movq %rax, 0x60(%rsp)
movq %r12, 0x78(%rsp)
cmpq %r12, %r15
je 0x3dc83
imulq $0xa8, %r15, %rcx
movq 0x50(%rsp), %rax
movq (%rax), %rsi
movq %rcx, 0x80(%rsp)
addq %rcx, %rsi
movq 0x8(%rsp), %rax
movq (%rax), %rdx
leaq 0x8c(%rsp), %rdi
callq 0x3d508
leaq 0x14(%rsp), %rbp
movl %r15d, 0x8c(%rsp)
movq %r15, %rax
shlq $0x20, %rax
movq %rax, 0x30(%rsp)
movq 0x60(%rsp), %r13
movq 0x68(%rsp), %r14
movq 0x70(%rsp), %r12
cmpq %r15, %r12
jle 0x3dc76
movq 0x50(%rsp), %rax
movq (%rax), %rsi
movl 0x8(%rsi,%r13), %eax
movq 0x80(%rsp), %rcx
cmpl 0x4(%rsi,%rcx), %eax
jb 0x3dc76
addq %r13, %rsi
movq 0x8(%rsp), %rax
movq (%rax), %rdx
movq %rbp, %rdi
callq 0x3d508
movl %r12d, 0x14(%rsp)
movl 0x94(%rsp), %eax
movl 0x1c(%rsp), %ecx
cmpl %ecx, %eax
jbe 0x3daf9
movl %ecx, %edx
movl %eax, %ecx
leaq 0x8c(%rsp), %rax
movq %rbp, %r8
jmp 0x3db1e
jne 0x3db0c
movl 0x90(%rsp), %edx
cmpl 0x18(%rsp), %edx
jae 0x3dc60
movl %eax, %edx
leaq 0x14(%rsp), %rbp
movq %rbp, %rax
leaq 0x8c(%rsp), %r8
movl 0x4(%rax), %esi
movl 0x4(%r8), %edi
cmpl %edi, %esi
movl %edi, %r9d
cmoval %esi, %r9d
cmpl %edx, %ecx
movl %edx, %r10d
cmovbl %ecx, %r10d
cmpl %r9d, %r10d
jbe 0x3dc44
leal 0x80(%rsi), %r9d
cmpl %r9d, %edi
jbe 0x3db89
movl $0x80, %r9d
addl %r9d, %edi
cmpl %esi, %edi
jb 0x3dc44
movl $0x80, %esi
addl %esi, %edx
cmpl %ecx, %edx
jb 0x3dc44
movq 0x8(%rsp), %rdi
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rdx
movsd 0x48(%rsp), %xmm0
movq %r8, %rcx
movq %rax, %r8
jmp 0x3dba1
movq 0x8(%rsp), %rdi
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rdx
movsd 0x48(%rsp), %xmm0
movq %rax, %rcx
callq 0x3d8a8
leaq 0x14(%rsp), %rbp
testl %eax, %eax
je 0x3dc44
movq 0x10(%rbx), %rax
incq (%rax,%r15,8)
incq (%rax,%r12,8)
movq (%rbx), %rcx
cmpq 0x8(%rbx), %rcx
jne 0x3dbed
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%rbx)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movq %rax, 0x10(%rbx)
movq (%rbx), %rcx
movq %r12, %rdx
orq 0x30(%rsp), %rdx
leaq 0x1(%rcx), %rsi
movq %rsi, (%rbx)
movq %rdx, (%rax,%rcx,8)
movq (%rbx), %rcx
cmpq 0x8(%rbx), %rcx
jne 0x3dc2e
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %rsi
movq %rsi, 0x8(%rbx)
shlq $0x3, %rsi
movq %rax, %rdi
callq 0x2370
movq %rax, 0x10(%rbx)
movq (%rbx), %rcx
leaq 0x14(%rsp), %rbp
movq %r14, %rdx
orq %r15, %rdx
leaq 0x1(%rcx), %rsi
movq %rsi, (%rbx)
movq %rdx, (%rax,%rcx,8)
decq %r12
movabsq $-0x100000000, %rax     # imm = 0xFFFFFFFF00000000
addq %rax, %r14
addq $-0xa8, %r13
jmp 0x3da99
movl %eax, %edx
movl %eax, %ecx
leaq 0x8c(%rsp), %rax
leaq 0x14(%rsp), %rbp
jmp 0x3daf4
incq %r15
movq 0x78(%rsp), %r12
jmp 0x3da39
movq (%rbx), %rax
movq 0x10(%rbx), %rcx
movq 0x58(%rsp), %r14
leaq (%rcx,%r14,8), %rdi
leaq (%rcx,%rax,8), %rsi
callq 0x1905d
xorl %eax, %eax
cmpq %rax, %r12
je 0x3dcc1
movq 0x10(%rbx), %rcx
movq (%rcx,%rax,8), %rdx
addq %r14, %rdx
shlq $0x20, %r14
orq %rdx, %r14
movq %r14, (%rcx,%rax,8)
incq %rax
movq %rdx, %r14
jmp 0x3dc9e
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq