// File: /workspace/github_c_makefile_star2_O0/samtools[P]htslib/cram/cram_decode.c
// Function: cram_decode_slice_xref
static int cram_decode_slice_xref(cram_slice *s, int required_fields) {
    int rec;

    if (!(required_fields & (SAM_RNEXT | SAM_PNEXT | SAM_TLEN))) {
        for (rec = 0; rec < s->hdr->num_records; rec++) {
            cram_record *cr = &s->crecs[rec];

            cr->tlen = 0;
            cr->mate_pos = 0;
            cr->mate_ref_id = -1;
        }

        return 0;
    }

    for (rec = 0; rec < s->hdr->num_records; rec++) {
        cram_record *cr = &s->crecs[rec];

        if (cr->mate_line >= 0) {
            if (cr->mate_line < s->hdr->num_records) {
                /*
                 * On the first read, loop through computing lengths.
                 * It's not perfect as we have one slice per reference so we
                 * cannot detect when TLEN should be zero due to seqs that
                 * map to multiple references.
                 *
                 * We also cannot set tlen correct when it spans a slice for
                 * other reasons. This may make tlen too small. Should we
                 * fix this by forcing TLEN to be stored verbatim in such cases?
                 *
                 * Or do we just admit defeat and output 0 for tlen? It's the
                 * safe option...
                 */
                if (cr->tlen == INT64_MIN) {
                    int id1 = rec, id2 = rec;
                    int64_t aleft = cr->apos, aright = cr->aend;
                    int64_t tlen;
                    int ref = cr->ref_id;

                    // number of segments starting at the same point.
                    int left_cnt = 0;

                    do {
                        if (aleft > s->crecs[id2].apos)
                            aleft = s->crecs[id2].apos, left_cnt = 1;
                        else if (aleft == s->crecs[id2].apos)
                            left_cnt++;
                        if (aright < s->crecs[id2].aend)
                            aright = s->crecs[id2].aend;
                        if (s->crecs[id2].mate_line == -1) {
                            s->crecs[id2].mate_line = rec;
                            break;
                        }
                        if (s->crecs[id2].mate_line <= id2 ||
                            s->crecs[id2].mate_line >= s->hdr->num_records)
                            return -1;
                        id2 = s->crecs[id2].mate_line;

                        if (s->crecs[id2].ref_id != ref)
                            ref = -1;
                    } while (id2 != id1);

                    if (ref != -1) {
                        tlen = aright - aleft + 1;
                        id1 = id2 = rec;

                        /*
                         * When we have two seqs with identical start and
                         * end coordinates, set +/- tlen based on 1st/last
                         * bit flags instead, as a tie breaker.
                         */
                        if (s->crecs[id2].apos == aleft) {
                            if (left_cnt == 1 ||
                                (s->crecs[id2].flags & BAM_FREAD1))
                                s->crecs[id2].tlen = tlen;
                            else
                                s->crecs[id2].tlen = -tlen;
                        } else {
                            s->crecs[id2].tlen = -tlen;
                        }

                        id2 = s->crecs[id2].mate_line;
                        while (id2 != id1) {
                            if (s->crecs[id2].apos == aleft) {
                                if (left_cnt == 1 ||
                                    (s->crecs[id2].flags & BAM_FREAD1))
                                    s->crecs[id2].tlen = tlen;
                                else
                                    s->crecs[id2].tlen = -tlen;
                            } else {
                                s->crecs[id2].tlen = -tlen;
                            }
                            id2 = s->crecs[id2].mate_line;
                        }
                    } else {
                        id1 = id2 = rec;

                        s->crecs[id2].tlen = 0;
                        id2 = s->crecs[id2].mate_line;
                        while (id2 != id1) {
                            s->crecs[id2].tlen = 0;
                            id2 = s->crecs[id2].mate_line;
                        }
                    }
                }

                cr->mate_pos = s->crecs[cr->mate_line].apos;
                cr->mate_ref_id = s->crecs[cr->mate_line].ref_id;

                // paired
                cr->flags |= BAM_FPAIRED;

                // set mate unmapped if needed
                if (s->crecs[cr->mate_line].flags & BAM_FUNMAP) {
                    cr->flags |= BAM_FMUNMAP;
                    cr->tlen = 0;
                }
                if (cr->flags & BAM_FUNMAP) {
                    cr->tlen = 0;
                }

                // set mate reversed if needed
                if (s->crecs[cr->mate_line].flags & BAM_FREVERSE)
                    cr->flags |= BAM_FMREVERSE;
            } else {
                hts_log_error("Mate line out of bounds: %d vs [0, %d]",
                              cr->mate_line, s->hdr->num_records-1);
            }

            /* FIXME: construct read names here too if needed */
        } else {
            if (cr->mate_flags & CRAM_M_REVERSE) {
                cr->flags |= BAM_FPAIRED | BAM_FMREVERSE;
            }
            if (cr->mate_flags & CRAM_M_UNMAP) {
                cr->flags |= BAM_FMUNMAP;
                //cr->mate_ref_id = -1;
            }
            if (!(cr->flags & BAM_FPAIRED))
                cr->mate_ref_id = -1;
        }

        if (cr->tlen == INT64_MIN)
            cr->tlen = 0; // Just incase
    }

    for (rec = 0; rec < s->hdr->num_records; rec++) {
        cram_record *cr = &s->crecs[rec];
        if (cr->explicit_tlen != INT64_MIN)
            cr->tlen = cr->explicit_tlen;
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl -0x14(%rbp), %eax
andl $0x1c0, %eax            # imm = 0x1C0
cmpl $0x0, %eax
jne 0x57816
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x18(%rcx), %eax
jge 0x5780a
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x18(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq $0x0, 0x40(%rax)
movq -0x20(%rbp), %rax
movq $0x0, 0x38(%rax)
movq -0x20(%rbp), %rax
movl $0xffffffff, 0x30(%rax) # imm = 0xFFFFFFFF
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x577b3
movl $0x0, -0x4(%rbp)
jmp 0x57ea5
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x18(%rcx), %eax
jge 0x57e3d
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x18(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x0, 0x2c(%rax)
jl 0x57db3
movq -0x28(%rbp), %rax
movl 0x2c(%rax), %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x18(%rcx), %eax
jge 0x57d81
movq -0x28(%rbp), %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
cmpq %rcx, 0x40(%rax)
jne 0x57c9d
movl -0x18(%rbp), %eax
movl %eax, -0x2c(%rbp)
movl -0x18(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq 0x78(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x28(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x4c(%rbp)
movl $0x0, -0x50(%rbp)
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x30(%rcx), %rcx
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rcx
cmpq 0x18(%rcx), %rax
jle 0x57903
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
movq %rax, -0x38(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0x5792e
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x30(%rcx), %rcx
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rcx
cmpq 0x18(%rcx), %rax
jne 0x5792c
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x5792e
movq -0x40(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x30(%rcx), %rcx
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rcx
cmpq 0x78(%rcx), %rax
jge 0x5796c
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq 0x78(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
cmpl $-0x1, 0x2c(%rax)
jne 0x579a9
movl -0x18(%rbp), %ecx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x2c(%rax)
jmp 0x57a47
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x2c(%rax), %eax
cmpl -0x30(%rbp), %eax
jle 0x579ec
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x2c(%rax), %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x18(%rcx), %eax
jl 0x579f8
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x57ea5
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x2c(%rax), %eax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
cmpl -0x4c(%rbp), %eax
je 0x57a39
movl $0xffffffff, -0x4c(%rbp) # imm = 0xFFFFFFFF
jmp 0x57a3b
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jne 0x578bc
cmpl $-0x1, -0x4c(%rbp)
je 0x57c12
movq -0x40(%rbp), %rax
subq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
movl -0x18(%rbp), %eax
movl %eax, -0x30(%rbp)
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
cmpq -0x38(%rbp), %rax
jne 0x57af5
cmpl $0x1, -0x50(%rbp)
je 0x57ab1
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x57ad1
movq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x40(%rax)
jmp 0x57af3
xorl %eax, %eax
movl %eax, %ecx
subq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x40(%rax)
jmp 0x57b17
xorl %eax, %eax
movl %eax, %ecx
subq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x40(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x2c(%rax), %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
je 0x57c0d
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
cmpq -0x38(%rbp), %rax
jne 0x57bca
cmpl $0x1, -0x50(%rbp)
je 0x57b86
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x57ba6
movq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x40(%rax)
jmp 0x57bc8
xorl %eax, %eax
movl %eax, %ecx
subq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x40(%rax)
jmp 0x57bec
xorl %eax, %eax
movl %eax, %ecx
subq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rdx
imulq $0x90, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x40(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x2c(%rax), %eax
movl %eax, -0x30(%rbp)
jmp 0x57b33
jmp 0x57c9b
movl -0x18(%rbp), %eax
movl %eax, -0x30(%rbp)
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq $0x0, 0x40(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x2c(%rax), %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
je 0x57c99
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq $0x0, 0x40(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x30(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x2c(%rax), %eax
movl %eax, -0x30(%rbp)
jmp 0x57c55
jmp 0x57c9b
jmp 0x57c9d
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x28(%rbp), %rcx
movslq 0x2c(%rcx), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x28(%rbp), %rcx
movslq 0x2c(%rcx), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0x8(%rax), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x30(%rax)
movq -0x28(%rbp), %rax
movl 0xc(%rax), %ecx
orl $0x1, %ecx
movl %ecx, 0xc(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x28(%rbp), %rcx
movslq 0x2c(%rcx), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x57d32
movq -0x28(%rbp), %rax
movl 0xc(%rax), %ecx
orl $0x8, %ecx
movl %ecx, 0xc(%rax)
movq -0x28(%rbp), %rax
movq $0x0, 0x40(%rax)
movq -0x28(%rbp), %rax
movl 0xc(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x57d4d
movq -0x28(%rbp), %rax
movq $0x0, 0x40(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x28(%rbp), %rcx
movslq 0x2c(%rcx), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x57d7f
movq -0x28(%rbp), %rax
movl 0xc(%rax), %ecx
orl $0x20, %ecx
movl %ecx, 0xc(%rax)
jmp 0x57db1
movq -0x28(%rbp), %rax
movl 0x2c(%rax), %ecx
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl 0x18(%rax), %r8d
subl $0x1, %r8d
movl $0x1, %edi
leaq 0x9bdbe(%rip), %rsi     # 0xf3b61
leaq 0x9bdce(%rip), %rdx     # 0xf3b78
movb $0x0, %al
callq 0x1b030
jmp 0x57e0d
movq -0x28(%rbp), %rax
movl 0x8c(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x57dd2
movq -0x28(%rbp), %rax
movl 0xc(%rax), %ecx
orl $0x21, %ecx
movl %ecx, 0xc(%rax)
movq -0x28(%rbp), %rax
movl 0x8c(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x57df1
movq -0x28(%rbp), %rax
movl 0xc(%rax), %ecx
orl $0x8, %ecx
movl %ecx, 0xc(%rax)
movq -0x28(%rbp), %rax
movl 0xc(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x57e0b
movq -0x28(%rbp), %rax
movl $0xffffffff, 0x30(%rax) # imm = 0xFFFFFFFF
jmp 0x57e0d
movq -0x28(%rbp), %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
cmpq %rcx, 0x40(%rax)
jne 0x57e2d
movq -0x28(%rbp), %rax
movq $0x0, 0x40(%rax)
jmp 0x57e2f
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x5781d
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
cmpl 0x18(%rcx), %eax
jge 0x57e9e
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x18(%rbp), %rcx
imulq $0x90, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
cmpq %rcx, 0x48(%rax)
je 0x57e91
movq -0x58(%rbp), %rax
movq 0x48(%rax), %rcx
movq -0x58(%rbp), %rax
movq %rcx, 0x40(%rax)
jmp 0x57e93
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x57e44
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nop