// File: chhylp123[P]hifiasm/hic.cpp
// Function: load_hc_pt_index(ha_ug_index**, ma_ug_t*, char*)
int load_hc_pt_index(ha_ug_index** r_idx, ma_ug_t *ug, char* file_name)
{
    uint64_t flag = 0;
    // double index_time = yak_realtime();
    char* gfa_name = (char*)malloc(strlen(file_name)+25);
    sprintf(gfa_name, "%s.hic.tlb.bin", file_name);
    FILE* fp = fopen(gfa_name, "r");
    if (!fp) {
        free(gfa_name);
        return 0;
    }
    ha_ug_index* idx = NULL; CALLOC(idx, 1);
    uint64_t i;

    flag += fread(&i, sizeof(i), 1, fp);
    if(i != HC_PT_MA)
    {
        free(gfa_name);
        destory_hc_pt_index(idx);
        free(idx);
        (*r_idx) = NULL;
        fclose(fp);
        fprintf(stderr, "[M::%s::] ==> Renew Hi-C index\n", __func__);
        return 0;
    }
    flag += fread(&idx->uID_bits, sizeof(idx->uID_bits), 1, fp);
    flag += fread(&idx->uID_mode, sizeof(idx->uID_mode), 1, fp);
    flag += fread(&idx->pos_bits, sizeof(idx->pos_bits), 1, fp);
    flag += fread(&idx->pos_mode, sizeof(idx->pos_mode), 1, fp);
    flag += fread(&idx->rev_mode, sizeof(idx->rev_mode), 1, fp);
    flag += fread(&idx->k, sizeof(idx->k), 1, fp);
    flag += fread(&idx->pre, sizeof(idx->pre), 1, fp);
    flag += fread(&idx->tot, sizeof(idx->tot), 1, fp);
    flag += fread(&idx->tot_pos, sizeof(idx->tot_pos), 1, fp);
    MALLOC(idx->idx_buf, idx->tot);

    for (i = 0; i < idx->tot; i++)
    {
        flag += fread(&idx->idx_buf[i].n, sizeof(idx->idx_buf[i].n), 1, fp);
        flag += fread(&idx->idx_buf[i].end, sizeof(idx->idx_buf[i].end), 1, fp);
        MALLOC(idx->idx_buf[i].a, idx->idx_buf[i].n);
        flag += fread(idx->idx_buf[i].a, sizeof(uint64_t), idx->idx_buf[i].n, fp);
        hc_pt_load(&(idx->idx_buf[i].h), fp);
    }


    (*r_idx) = idx;

    free(gfa_name);
    if(!test_dbug(ug, fp))
    {
        destory_hc_pt_index(idx);
        free(idx);
        (*r_idx) = NULL;
        fclose(fp);
        fprintf(stderr, "[M::%s::] ==> Renew Hi-C index\n", __func__);
        return 0;
    }

    fclose(fp);
    // fprintf(stderr, "[M::%s::%.3f] ==> HiC index has been loaded\n", __func__, yak_realtime()-index_time);
    return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x20(%rbp), %rdi
callq 0x20a0
movq %rax, %rdi
addq $0x19, %rdi
callq 0x2270
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rdx
leaq 0x1cbe7d(%rip), %rsi    # 0x38bf21
movb $0x0, %al
callq 0x2050
movq -0x30(%rbp), %rdi
leaq 0x1d0320(%rip), %rsi    # 0x3903d6
callq 0x2200
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x1c00db
movq -0x30(%rbp), %rdi
callq 0x2210
movl $0x0, -0x4(%rbp)
jmp 0x1c047a
movq $0x0, -0x40(%rbp)
movl $0x1, %edi
movl $0xc0, %esi
callq 0x2140
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rcx
leaq -0x48(%rbp), %rdi
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpq $0x41, -0x48(%rbp)
je 0x1c0176
movq -0x30(%rbp), %rdi
callq 0x2210
movq -0x40(%rbp), %rdi
callq 0x1c0490
movq -0x40(%rbp), %rdi
callq 0x2210
movq -0x10(%rbp), %rax
movq $0x0, (%rax)
movq -0x38(%rbp), %rdi
callq 0x21a0
movq 0x203e8e(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x1cbde6(%rip), %rsi    # 0x38bf42
leaq 0x1cbdff(%rip), %rdx    # 0x38bf62
movb $0x0, %al
callq 0x22a0
movl $0x0, -0x4(%rbp)
jmp 0x1c047a
movq -0x40(%rbp), %rdi
addq $0x18, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rdi
addq $0x20, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rdi
addq $0x28, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rdi
addq $0x30, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rdi
addq $0x38, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rdi
addq $0x40, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rdi
addq $0x50, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rdi
addq $0x58, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rdi
addq $0x60, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rdi
shlq $0x5, %rdi
callq 0x2270
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x78(%rax)
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq 0x58(%rcx), %rax
jae 0x1c03f6
movq -0x40(%rbp), %rax
movq 0x78(%rax), %rdi
movq -0x48(%rbp), %rax
shlq $0x5, %rax
addq %rax, %rdi
addq $0x8, %rdi
movq -0x38(%rbp), %rcx
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rax
movq 0x78(%rax), %rdi
movq -0x48(%rbp), %rax
shlq $0x5, %rax
addq %rax, %rdi
addq $0x18, %rdi
movq -0x38(%rbp), %rcx
movl $0x4, %esi
movl $0x1, %edx
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rax
movq 0x78(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
shlq $0x3, %rdi
callq 0x2270
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq 0x78(%rax), %rax
movq -0x48(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x78(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rdi
movq -0x40(%rbp), %rax
movq 0x78(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdx
movq -0x38(%rbp), %rcx
movl $0x8, %esi
callq 0x22e0
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rax
movq 0x78(%rax), %rdi
movq -0x48(%rbp), %rax
shlq $0x5, %rax
addq %rax, %rdi
movq -0x38(%rbp), %rsi
callq 0x1c0560
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x1c02d5
movq -0x40(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rdi
callq 0x2210
movq -0x18(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x101650
cmpl $0x0, %eax
jne 0x1c046a
movq -0x40(%rbp), %rdi
callq 0x1c0490
movq -0x40(%rbp), %rdi
callq 0x2210
movq -0x10(%rbp), %rax
movq $0x0, (%rax)
movq -0x38(%rbp), %rdi
callq 0x21a0
movq 0x203b97(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x1cbaef(%rip), %rsi    # 0x38bf42
leaq 0x1cbb08(%rip), %rdx    # 0x38bf62
movb $0x0, %al
callq 0x22a0
movl $0x0, -0x4(%rbp)
jmp 0x1c047a
movq -0x38(%rbp), %rdi
callq 0x21a0
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)