// File: /workspace/github_cpp_makefile_star2_O3/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, %r13
subq %r13, %r12
movl %r13d, %ebp
cmpl $0x20, %r13d
jg 0x58c1
leaq 0x100(%rsp), %rdi
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x3110
testl %r14d, %r14d
jle 0x5868
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,%rbp), %rax
decq %rax
decq %rcx
cmpq $0x1f, %rax
jne 0x5836
cmpq %rbx, %r12
jb 0x59e3
movslq %r14d, %rax
decq %rax
movzbl (%rbx,%rax), %ecx
movl 0x100(%rsp,%rcx,4), %ecx
movq %r13, %rdx
testl %ecx, %ecx
je 0x58b4
movq %rax, %rdx
movl %r14d, %esi
testl %ecx, %ecx
jns 0x589e
movl %edx, %esi
testq %rdx, %rdx
je 0x59e5
addl %ecx, %ecx
movzbl -0x1(%rbx,%rdx), %edi
decq %rdx
andl 0x100(%rsp,%rdi,4), %ecx
jne 0x588f
movslq %esi, %rdx
addq %rdx, %rbx
cmpq %r12, %rbx
jbe 0x5877
jmp 0x59e3
cmpl $0x40, %r14d
ja 0x5971
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,%rbp), %rax
decq %rax
decq %rcx
cmpq $0x3f, %rax
jne 0x58e4
cmpq %rbx, %r12
jb 0x59e3
decl %r14d
movslq %r14d, %rax
movzbl (%rbx,%r14), %ecx
movq 0x100(%rsp,%rcx,8), %rcx
movq %r13, %rdx
testq %rcx, %rcx
je 0x5967
movq %rax, %rdx
movl %ebp, %esi
testq %rcx, %rcx
jns 0x594f
movl %edx, %esi
testq %rdx, %rdx
je 0x59e5
addq %rcx, %rcx
movzbl -0x1(%rbx,%rdx), %edi
decq %rdx
andq 0x100(%rsp,%rdi,8), %rcx
jne 0x593f
movslq %esi, %rdx
addq %rdx, %rbx
cmpq %r12, %rbx
jbe 0x5925
jmp 0x59e3
cmpl $0x80, %r14d
ja 0x59e3
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 0x59ae
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,%rbp), %rax
decq %rax
decq %rcx
cmpq $0x7f, %rax
jne 0x5992
cmpq %rbx, %r12
jae 0x59fa
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x1108, %rsp           # imm = 0x1108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
decl %r14d
movslq %r14d, %rax
pxor %xmm0, %xmm0
movzbl (%rbx,%r14), %ecx
cmpb $0x0, (%rsp,%rcx)
movq %r13, %rdx
je 0x5a7c
shll $0x4, %ecx
movdqa 0x100(%rsp,%rcx), %xmm1
movq %rax, %rcx
movl %ebp, %edx
pmovmskb %xmm1, %esi
testw %si, %si
jns 0x5a33
movl %ecx, %edx
testq %rcx, %rcx
je 0x59e5
movzbl -0x1(%rbx,%rcx), %esi
cmpb $0x0, (%rsp,%rsi)
je 0x5a79
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, %esi
pand 0x100(%rsp,%rsi), %xmm2
movdqa %xmm2, %xmm1
pcmpeqb %xmm0, %xmm2
pmovmskb %xmm2, %esi
xorl $0xffff, %esi           # imm = 0xFFFF
decq %rcx
testl %esi, %esi
jne 0x5a23
movslq %edx, %rdx
addq %rdx, %rbx
cmpq %r12, %rbx
jbe 0x5a04
jmp 0x59e3
nopl (%rax)