// File: chhylp123[P]hifiasm/hic.cpp
// Function: get_enzyme_occ(char*, long long, char*, long long)
long long get_enzyme_occ(char* t, long long tlen, char* p, long long plen)
{
    long long i, c, s = 0, j, occ = 0;
    int badchar[5]; badchar[0] = badchar[1] = badchar[2] = badchar[3] = badchar[4] = -1;
    for (i = 0; i < plen; i++)
    {
        c = seq_nt4_table[(uint8_t)p[i]];
        badchar[c] = i; 
        if(c == 4) badchar[0] = badchar[1] = badchar[2] = badchar[3] = i; 
    } 
    badchar[4] = -1;

    while(s <= (tlen - plen)) 
    { 
        j = plen-1; 

        while(j >= 0)
        {
            if(seq_nt4_table[(uint8_t)t[s+j]] >= 4) break;
            if((p[j] != t[s+j]) && seq_nt4_table[(uint8_t)p[j]] < 4) break;
            j--; 
        } 
        
            
        if (j < 0) 
        { 
            occ++;
            ///s += (s+m < n)? m-badchar[txt[s+m]] : 1; 
            s++;
        } 
        else
        {
            /*******************************for debug************************************/
            // long long f, end = s + MAX(1, j - badchar[seq_nt4_table[(uint8_t)t[s+j]]]);
            // for (f = s+1; f < end; f++)
            // {
            //     if(check_exact_match(t+f, plen, p, plen))
            //     {
            //         fprintf(stderr, "s: %lld, end: %lld, s+j: %lld, t[s+j]: %c, badchar: %d, j: %lld\n", 
            //                     s, end, s+j, t[s+j], badchar[seq_nt4_table[(uint8_t)t[s+j]]], j);
            //     }
            // }            
            /*******************************for debug************************************/
            
            s += MAX(1, j - badchar[seq_nt4_table[(uint8_t)t[s+j]]]); 
        }
    } 

    return occ;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq $0x0, -0x38(%rbp)
movq $0x0, -0x48(%rbp)
movl $0xffffffff, -0x50(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x54(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x58(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x5c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x60(%rbp) # imm = 0xFFFFFFFF
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x20(%rbp), %rax
jge 0x1cb87b
movq -0x18(%rbp), %rax
movq -0x28(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, %ecx
leaq 0x1befa2(%rip), %rax    # 0x38a7e0
movzbl (%rax,%rcx), %eax
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, -0x60(%rbp,%rax,4)
cmpq $0x4, -0x30(%rbp)
jne 0x1cb86b
movq -0x28(%rbp), %rax
movl %eax, -0x54(%rbp)
movl %eax, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl %eax, -0x60(%rbp)
jmp 0x1cb86d
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x1cb81f
movl $0xffffffff, -0x50(%rbp) # imm = 0xFFFFFFFF
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
subq -0x20(%rbp), %rcx
cmpq %rcx, %rax
jg 0x1cb9b9
movq -0x20(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jl 0x1cb91c
movq -0x8(%rbp), %rax
movq -0x38(%rbp), %rcx
addq -0x40(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, %ecx
leaq 0x1bef1d(%rip), %rax    # 0x38a7e0
movzbl (%rax,%rcx), %eax
cmpl $0x4, %eax
jl 0x1cb8ce
jmp 0x1cb91c
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movsbl (%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movq -0x38(%rbp), %rdx
addq -0x40(%rbp), %rdx
movsbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
je 0x1cb90e
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, %ecx
leaq 0x1beedd(%rip), %rax    # 0x38a7e0
movzbl (%rax,%rcx), %eax
cmpl $0x4, %eax
jge 0x1cb90e
jmp 0x1cb91c
movq -0x40(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x1cb8a3
cmpq $0x0, -0x40(%rbp)
jge 0x1cb93d
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x1cb9b4
movq -0x40(%rbp), %rcx
movq -0x8(%rbp), %rax
movq -0x38(%rbp), %rdx
addq -0x40(%rbp), %rdx
movzbl (%rax,%rdx), %eax
movl %eax, %edx
leaq 0x1bee86(%rip), %rax    # 0x38a7e0
movzbl (%rax,%rdx), %eax
movslq -0x60(%rbp,%rax,4), %rax
subq %rax, %rcx
movl $0x1, %eax
cmpq %rcx, %rax
jl 0x1cb97b
movl $0x1, %eax
movq %rax, -0x68(%rbp)
jmp 0x1cb9a8
movq -0x40(%rbp), %rax
movq -0x8(%rbp), %rcx
movq -0x38(%rbp), %rdx
addq -0x40(%rbp), %rdx
movzbl (%rcx,%rdx), %ecx
movl %ecx, %edx
leaq 0x1bee48(%rip), %rcx    # 0x38a7e0
movzbl (%rcx,%rdx), %ecx
movslq -0x60(%rbp,%rcx,4), %rcx
subq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x1cb882
movq -0x48(%rbp), %rax
popq %rbp
retq
nop