// File: /workspace/github_cpp_makefile_star2_O1/ctSkennerton[P]fxtract/util/./bndmem.c
// Function: bndmem
char *
bndmem(char *target, int tgtlen, char *pattern, int patlen)
{
    uint8_t *tgt = (uint8_t*)target, *pat = (uint8_t*)pattern;
    uint8_t *tgtend = tgt + tgtlen - patlen;
    int i, skip;
#if __SIZEOF_INT__ == 4
    if (patlen <= 32) {
        int32_t mask, maskv[256] = {};
        
        for (i = 0; i < patlen; ++i)
            setbit(&maskv[pat[i]], sizeof(mask)*8 - 1 - i);

        for (; tgt <= tgtend; tgt += skip)
            for (i = skip = patlen, mask = maskv[tgt[--i]];
                    mask; mask = (mask << 1) & maskv[tgt[--i]])
                if (mask < 0 && !(skip = i)) return (char*)tgt;
    } else 
#endif
    if (patlen <= 64) {
        int64_t mask, maskv[256] = {};

        for (i = 0; i < patlen; ++i)
            setbit(&maskv[pat[i]], sizeof(mask)*8 - 1 - i);

        for (; tgt <= tgtend; tgt += skip)
            for (i = skip = patlen, mask = maskv[tgt[--i]];
                    mask; mask = (mask << 1) & maskv[tgt[--i]])
                if (mask < 0 && !(skip = i)) return (char*)tgt;

    } else if (patlen <= 128) {
        __m128i mask, maskv[256], zero = {};
        int8_t used[256] = {};

        for (i = 0; i < patlen; ++i) {
            if (!used[pat[i]]) used[pat[i]] = 1, maskv[pat[i]] = zero;
            setbit(&maskv[pat[i]], sizeof(mask)*8 - 1 - i);
        }
        
        for (; tgt <= tgtend; tgt += skip) {
            i = skip = patlen;
            if (!used[tgt[--i]]) continue;
            mask = maskv[tgt[i]]; // gteed not zero.
            do {
                if (0 > (int16_t)_mm_movemask_epi8(mask) && !(skip = i))
                    return (char*)tgt;
                if (!used[tgt[--i]]) break;
                mask = _mm_and_si128(xm_shl_001(mask), maskv[tgt[i]]);
            } while (0xFFFF != _mm_movemask_epi8(_mm_cmpeq_epi8(mask, zero)));
        }
    }
    //TODO: AVX 256-bit ops.
    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1108, %rsp           # imm = 0x1108
movl %ecx, %r14d
movq %rdx, %r15
movq %rdi, %rbx
movslq %esi, %r12
addq %rdi, %r12
movslq %ecx, %rbp
subq %rbp, %r12
movl %ebp, %r13d
cmpl $0x20, %ebp
jg 0x5ab1
leaq 0x100(%rsp), %rdi
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x3110
testl %r14d, %r14d
jle 0x5a58
movl $0x1f, %ecx
movzbl (%r15), %eax
leaq (%rsp,%rax,4), %rax
addq $0x100, %rax            # imm = 0x100
movl $0x1, %edx
shll %cl, %edx
movq %rcx, %rsi
shrq $0x5, %rsi
orl %edx, (%rax,%rsi,4)
incq %r15
leaq (%rcx,%r13), %rax
decq %rax
decq %rcx
cmpq $0x1f, %rax
jne 0x5a26
cmpq %rbx, %r12
jb 0x5bd5
decq %rbp
movslq %ebp, %rax
movzbl (%rbx,%rbp), %ecx
movl 0x100(%rsp,%rcx,4), %ecx
movl %r14d, %edx
testl %ecx, %ecx
je 0x5aa1
movq %rax, %rsi
movl %r14d, %edx
testl %ecx, %ecx
jns 0x5a8e
movl %esi, %edx
testq %rsi, %rsi
je 0x5bd7
addl %ecx, %ecx
movzbl -0x1(%rbx,%rsi), %edi
decq %rsi
andl 0x100(%rsp,%rdi,4), %ecx
jne 0x5a7f
movslq %edx, %rcx
addq %rcx, %rbx
cmpq %r12, %rbx
jbe 0x5a67
jmp 0x5bd5
cmpl $0x40, %r14d
jg 0x5b63
leaq 0x100(%rsp), %rdi
movl $0x800, %edx            # imm = 0x800
xorl %esi, %esi
callq 0x3110
movl $0x3f, %ecx
movzbl (%r15), %eax
leaq (%rsp,%rax,8), %rax
addq $0x100, %rax            # imm = 0x100
movl $0x1, %edx
shll %cl, %edx
movq %rcx, %rsi
shrq $0x5, %rsi
orl %edx, (%rax,%rsi,4)
incq %r15
leaq (%rcx,%r13), %rax
decq %rax
decq %rcx
cmpq $0x3f, %rax
jne 0x5ad4
cmpq %rbx, %r12
jb 0x5bd5
leal -0x1(%r14), %eax
movslq %eax, %rcx
movzbl (%rbx,%rax), %edx
movq 0x100(%rsp,%rdx,8), %rdx
movl %r14d, %esi
testq %rdx, %rdx
je 0x5b56
movq %rcx, %rdi
movl %r13d, %esi
testq %rdx, %rdx
jns 0x5b40
movl %edi, %esi
testq %rdi, %rdi
je 0x5bd7
addq %rdx, %rdx
movzbl -0x1(%rbx,%rdi), %r8d
decq %rdi
andq 0x100(%rsp,%r8,8), %rdx
jne 0x5b30
movslq %esi, %rdx
addq %rdx, %rbx
cmpq %r12, %rbx
jbe 0x5b16
jmp 0x5bd5
cmpl $0x80, %r14d
jg 0x5bd5
movq %rsp, %rdi
movl $0x100, %edx            # imm = 0x100
xorl %esi, %esi
callq 0x3110
movl $0x7f, %ecx
pxor %xmm0, %xmm0
movzbl (%r15), %eax
cmpb $0x0, (%rsp,%rax)
jne 0x5ba0
movb $0x1, (%rsp,%rax)
movl %eax, %edx
shll $0x4, %edx
movdqa %xmm0, 0x100(%rsp,%rdx)
shll $0x4, %eax
addq %rsp, %rax
addq $0x100, %rax            # imm = 0x100
movl $0x1, %edx
shll %cl, %edx
movq %rcx, %rsi
shrq $0x5, %rsi
orl %edx, (%rax,%rsi,4)
incq %r15
leaq (%rcx,%r13), %rax
decq %rax
decq %rcx
cmpq $0x7f, %rax
jne 0x5b84
cmpq %rbx, %r12
jae 0x5bec
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x1108, %rsp           # imm = 0x1108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leal -0x1(%r14), %eax
movslq %eax, %rcx
pxor %xmm0, %xmm0
movzbl (%rbx,%rax), %esi
cmpb $0x0, (%rsp,%rsi)
movl %r14d, %edx
je 0x5c6c
shll $0x4, %esi
movdqa 0x100(%rsp,%rsi), %xmm1
movq %rcx, %rsi
movl %r13d, %edx
pmovmskb %xmm1, %edi
testw %di, %di
jns 0x5c26
movl %esi, %edx
testq %rsi, %rsi
je 0x5bd7
movzbl -0x1(%rbx,%rsi), %edi
cmpb $0x0, (%rsp,%rdi)
je 0x5c6c
movdqa %xmm1, %xmm2
pslldq $0x8, %xmm2             # xmm2 = zero,zero,zero,zero,zero,zero,zero,zero,xmm2[0,1,2,3,4,5,6,7]
paddq %xmm1, %xmm1
psrlq $0x3f, %xmm2
por %xmm1, %xmm2
shll $0x4, %edi
pand 0x100(%rsp,%rdi), %xmm2
movdqa %xmm2, %xmm1
pcmpeqb %xmm0, %xmm2
pmovmskb %xmm2, %edi
xorl $0xffff, %edi           # imm = 0xFFFF
decq %rsi
testl %edi, %edi
jne 0x5c16
movslq %edx, %rdx
addq %rdx, %rbx
cmpq %r12, %rbx
jbe 0x5bf7
jmp 0x5bd5