// File: readmapping[P]alfalfa/src/mapper.cpp
// Function: recoverCIGAR4(int, unsigned int*, unsigned char const*, unsigned char const*, std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char>>&)
int recoverCIGAR4(int n_cigar, uint32_t *BamCigar, const uint8_t * query, const uint8_t * rseq, stringstream & sNM){
    int i, k, x, y, n_mm = 0, n_gap = 0;
    for (k = 0, x = y = 0; k < n_cigar; ++k) {
        int op  = BamCigar[k]&0xf;
        int len = BamCigar[k]>>4;
        if (op == 0) { // match
            int matchLen = 0;
            int mmLen = 0;
            for(i = 0; i < len; i++){
                if(query[x + i] != rseq[y + i]){
                    ++n_mm; ++mmLen;
                    if(matchLen){
                        sNM << matchLen << "=";
                        matchLen = 0;
                    }
                }
                else{
                    ++matchLen;
                    if(mmLen){
                        sNM << mmLen << "X";
                        mmLen = 0;
                    }
                }
            }
            if(matchLen)
                sNM << matchLen << "=";
            else
                sNM << mmLen << "X";
            x += len; y += len;
        } 
        else{
            sNM << len << "MIDSH"[op];
            if (op == 1) x += len, n_gap += len;
            else if (op == 2) y += len, n_gap += len;
        }
    }
    return n_mm + n_gap;
}

// Assembly:
subq $0x58, %rsp
movl %edi, 0x54(%rsp)
movq %rsi, 0x48(%rsp)
movq %rdx, 0x40(%rsp)
movq %rcx, 0x38(%rsp)
movq %r8, 0x30(%rsp)
movl $0x0, 0x1c(%rsp)
movl $0x0, 0x18(%rsp)
movl $0x0, 0x28(%rsp)
movl $0x0, 0x20(%rsp)
movl $0x0, 0x24(%rsp)
movl 0x28(%rsp), %eax
cmpl 0x54(%rsp), %eax
jge 0x3a313
movq 0x48(%rsp), %rax
movslq 0x28(%rsp), %rcx
movl (%rax,%rcx,4), %eax
andl $0xf, %eax
movl %eax, 0x14(%rsp)
movq 0x48(%rsp), %rax
movslq 0x28(%rsp), %rcx
movl (%rax,%rcx,4), %eax
shrl $0x4, %eax
movl %eax, 0x10(%rsp)
cmpl $0x0, 0x14(%rsp)
jne 0x3a293
movl $0x0, 0xc(%rsp)
movl $0x0, 0x8(%rsp)
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x10(%rsp), %eax
jge 0x3a22e
movq 0x40(%rsp), %rax
movl 0x24(%rsp), %ecx
addl 0x2c(%rsp), %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
movq 0x38(%rsp), %rcx
movl 0x20(%rsp), %edx
addl 0x2c(%rsp), %edx
movslq %edx, %rdx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
je 0x3a1df
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
movl 0x8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8(%rsp)
cmpl $0x0, 0xc(%rsp)
je 0x3a1dd
movq 0x30(%rsp), %rdi
addq $0x10, %rdi
movl 0xc(%rsp), %esi
callq 0x8710
movq %rax, %rdi
leaq 0x3f2f9(%rip), %rsi     # 0x794c9
callq 0x8360
movl $0x0, 0xc(%rsp)
jmp 0x3a21c
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
cmpl $0x0, 0x8(%rsp)
je 0x3a21a
movq 0x30(%rsp), %rdi
addq $0x10, %rdi
movl 0x8(%rsp), %esi
callq 0x8710
movq %rax, %rdi
leaq 0x4242b(%rip), %rsi     # 0x7c638
callq 0x8360
movl $0x0, 0x8(%rsp)
jmp 0x3a21c
jmp 0x3a21e
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x3a15d
cmpl $0x0, 0xc(%rsp)
je 0x3a258
movq 0x30(%rsp), %rdi
addq $0x10, %rdi
movl 0xc(%rsp), %esi
callq 0x8710
movq %rax, %rdi
leaq 0x3f278(%rip), %rsi     # 0x794c9
callq 0x8360
jmp 0x3a279
movq 0x30(%rsp), %rdi
addq $0x10, %rdi
movl 0x8(%rsp), %esi
callq 0x8710
movq %rax, %rdi
leaq 0x423c4(%rip), %rsi     # 0x7c638
callq 0x8360
movl 0x10(%rsp), %eax
addl 0x24(%rsp), %eax
movl %eax, 0x24(%rsp)
movl 0x10(%rsp), %eax
addl 0x20(%rsp), %eax
movl %eax, 0x20(%rsp)
jmp 0x3a301
movq 0x30(%rsp), %rdi
addq $0x10, %rdi
movl 0x10(%rsp), %esi
callq 0x8710
movq %rax, %rdi
movslq 0x14(%rsp), %rcx
leaq 0x438dc(%rip), %rax     # 0x7db90
movsbl (%rax,%rcx), %esi
callq 0x8440
cmpl $0x1, 0x14(%rsp)
jne 0x3a2de
movl 0x10(%rsp), %eax
addl 0x24(%rsp), %eax
movl %eax, 0x24(%rsp)
movl 0x10(%rsp), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
jmp 0x3a2ff
cmpl $0x2, 0x14(%rsp)
jne 0x3a2fd
movl 0x10(%rsp), %eax
addl 0x20(%rsp), %eax
movl %eax, 0x20(%rsp)
movl 0x10(%rsp), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
jmp 0x3a2ff
jmp 0x3a301
jmp 0x3a303
movl 0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
jmp 0x3a104
movl 0x1c(%rsp), %eax
addl 0x18(%rsp), %eax
addq $0x58, %rsp
retq