// File: /workspace/github_cpp_makefile_star2_O3/ctSkennerton[P]fxtract/util/str_x.c
// Function: main
int
main(int argc, char **argv)
{
    setvbuf(stdout, NULL, _IOLBF, 0);
    int         count = 10001;  // count MUST be odd, or hash is always zero!
    int         patlen, nr, a;
    if (argc < 4)
        usage("[-v] <file> <count> <str>...\n"
              "Compares STRSTR (SSE4.2) with:\n"
             // "- SSE2: scan for leading pair of chars using SSE2\n"
              //"- BERG: Steven van den Berg's strstr\n"
             // "- WINS: use 2,3,4-byte sliding window\n"
              "- BNDM: Backward Non-deterministic DAWG matching (suffix shift-and)\n"
              "- RG7G: Georgi's Railgun version 7-Gulliver\n"
              "- RG7W: Georgi's Railgun version 7-Wolfram\n");
    argv += verbose = !strcmp(argv[1], "-v");
    MEMBUF x = chomp(slurp(argv[1]));
    if (nilbuf(x)) die(": cannot read %s:", argv[1]);
    count = atoi(argv[2]) | 1;  // count MUST be odd
    MEMREF  *rv = refsplit(x.ptr, '\n', &nr);
    char    **exp = malloc(nr * sizeof(*exp));

    //if (verbose) printf("SSE2 BERG WINS BNDM RG7g RG7w nchrs=%"FSIZE"d\n", x.len);
    if (verbose) printf("BNDM... RG7g... RG7w... nchrs=%"FSIZE"d\n", x.len);
    for (a = 3; argv[a]; ++a) {
        patlen = strlen(argv[a]);
        memset(exp, -1, nr * sizeof(*exp));

#           define DO_MEM(T,F) double T = do_mem(#F, (MEMF)F, rv, nr, count, argv[a], exp)
#           define DO_STR(T,F) double T = do_str(#F, (STRF)F, rv, nr, count, argv[a], exp)
        DO_STR(tbase, strstr);
        //DO_STR(tsse2, sse2str);
        //DO_STR(tberg, bergstr);
        //DO_STR(twins, winstr);
        DO_MEM(tbndm, bndmem);
        DO_MEM(trg7g, Railgun7g);
        DO_MEM(trg7w, Railgun7w);
#           undef  DO_MEM
#           undef  DO_STR
        //if (verbose) printf("%4.0f %4.0f %4.0f %4.0f %4.0f %4.0f P=%d '%s'\n",
        if (verbose) printf("%7.2f %7.2f %7.2f P=%d '%s'\n",
               //tsse2 * 100 / tbase,
               //tberg * 100 / tbase,
               //twins * 100 / tbase,
               tbndm * 100 / tbase,
               trg7g * 100 / tbase,
               trg7w * 100 / tbase,
               patlen, argv[a]);
    }

    free(rv);
    buffree(x);

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rsi, %rbx
movl %edi, %ebp
movq 0x6a72(%rip), %rax      # 0x9fc8
movq (%rax), %rdi
xorl %esi, %esi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x3030
cmpl $0x3, %ebp
jle 0x38de
movq 0x8(%rbx), %rdi
cmpb $0x2d, (%rdi)
jne 0x358f
cmpb $0x76, 0x1(%rdi)
jne 0x358f
xorl %eax, %eax
cmpb $0x0, 0x2(%rdi)
sete %al
movq 0x8(%rbx,%rax,8), %rdi
jmp 0x3591
xorl %eax, %eax
movzbl %al, %eax
movl %eax, 0x71da(%rip)      # 0xa774
leaq (%rbx,%rax,8), %r14
callq 0x53cd
movq %rax, %rdi
movq %rdx, %rsi
callq 0x4d58
testq %rax, %rax
je 0x38e3
movq %rax, %rbp
movq %rdx, %rbx
movq 0x10(%r14), %rdi
callq 0x32d0
movl %eax, 0x30(%rsp)
leaq 0x1c(%rsp), %r15
movq %rbp, %rdi
movl $0xa, %esi
movq %r15, %rdx
callq 0x5299
movq %rax, 0x38(%rsp)
movslq (%r15), %rdi
shlq $0x3, %rdi
callq 0x3260
movq %rax, %r15
cmpl $0x0, 0x717a(%rip)      # 0xa774
je 0x360d
leaq 0x3af7(%rip), %rdi      # 0x70fa
movq %rbx, %rsi
xorl %eax, %eax
callq 0x3050
movq 0x18(%r14), %rbx
testq %rbx, %rbx
je 0x38bb
movl 0x30(%rsp), %eax
orl $0x1, %eax
movl %eax, 0x34(%rsp)
leaq 0x18(%r14), %rcx
movq 0x38(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x40(%rsp)
movl $0x3, %r13d
movq %r14, 0x50(%rsp)
movq %rbp, 0x48(%rsp)
movq %rcx, 0x68(%rsp)
movq %r13, 0x70(%rsp)
movq %rbx, %rdi
callq 0x30c0
movq %rax, 0x60(%rsp)
movslq 0x1c(%rsp), %r14
leaq (,%r14,8), %rdx
movq %r15, %rdi
movl $0xff, %esi
callq 0x3100
callq 0x5655
movsd %xmm0, 0x28(%rsp)
movl %r14d, %r12d
testq %r14, %r14
jle 0x36c2
movq 0x40(%rsp), %r14
xorl %ebp, %ebp
movq -0x8(%r14), %r13
movq %r13, %rdi
movq %rbx, %rsi
callq 0x3070
movq (%r15,%rbp,8), %rcx
cmpq $-0x1, %rcx
je 0x36b2
cmpq %rax, %rcx
je 0x36b6
jmp 0x3721
movq %rax, (%r15,%rbp,8)
incq %rbp
addq $0x10, %r14
cmpq %rbp, %r12
jne 0x3692
cmpl $0x0, 0x30(%rsp)
js 0x3711
movq %r12, %r14
shlq $0x3, %r14
xorl %eax, %eax
movl %eax, 0x20(%rsp)
testl %r12d, %r12d
jle 0x3705
xorl %r13d, %r13d
movq (%r15,%r13), %rbp
movq 0x38(%rsp), %rax
movq (%rax,%r13,2), %rdi
movq %rbx, %rsi
callq 0x3070
cmpq %rax, %rbp
jne 0x37ac
addq $0x8, %r13
cmpq %r13, %r14
jne 0x36de
movl 0x20(%rsp), %eax
incl %eax
cmpl 0x34(%rsp), %eax
jne 0x36d2
callq 0x5655
subsd 0x28(%rsp), %xmm0
jmp 0x37b0
movq 0x68b8(%rip), %rdx      # 0x9fe0
movq (%rdx), %rdx
movq %rdx, 0x20(%rsp)
movq %rcx, %rdx
subq %r13, %rdx
cmpq $0x1, %rcx
movl $0x0, %ecx
sbbq %rcx, %rcx
orq %rdx, %rcx
movq %rcx, 0x28(%rsp)
movq %rax, %rcx
subq %r13, %rcx
cmpq $0x1, %rax
movl $0x0, %r12d
sbbq %r12, %r12
orq %rcx, %r12
movq (%r14), %r14
movq %r13, %rdi
movl %r14d, %esi
callq 0x44e4
movq %rax, %r13
movq %rax, 0x10(%rsp)
movq %r14, 0x8(%rsp)
movq %r12, (%rsp)
movq 0x20(%rsp), %rdi
leaq 0x39df(%rip), %rsi      # 0x716a
leaq 0x398b(%rip), %rdx      # 0x711d
movq %rbx, %rcx
movl %ebp, %r8d
movq 0x28(%rsp), %r9
xorl %eax, %eax
callq 0x32a0
movq %r13, %rdi
callq 0x3230
xorpd %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
movl 0x1c(%rsp), %ecx
movq 0x68(%rsp), %r12
movq (%r12), %r9
movq %r15, (%rsp)
leaq 0x3956(%rip), %rdi      # 0x7124
leaq 0x28e(%rip), %rsi       # 0x3a63
movq 0x38(%rsp), %rbx
movq %rbx, %rdx
movl 0x34(%rsp), %ebp
movl %ebp, %r8d
callq 0x38f5
movsd %xmm0, 0x28(%rsp)
movl 0x1c(%rsp), %ecx
movq (%r12), %r9
movq %r15, (%rsp)
leaq 0x3929(%rip), %rdi      # 0x712b
leaq 0x4fe(%rip), %rsi       # 0x3d07
movq %rbx, %rdx
movl %ebp, %r8d
callq 0x38f5
movsd %xmm0, 0x58(%rsp)
movl 0x1c(%rsp), %ecx
movq (%r12), %r9
movq %r15, (%rsp)
leaq 0x3908(%rip), %rdi      # 0x7135
leaq 0x7e3(%rip), %rsi       # 0x4017
movq %rbx, %rdx
movl %ebp, %r8d
callq 0x38f5
cmpl $0x0, 0x6f2e(%rip)      # 0xa774
movq 0x50(%rsp), %r14
movq 0x48(%rsp), %rbp
movq 0x70(%rsp), %r13
je 0x38a4
movapd %xmm0, %xmm2
movsd 0x37a5(%rip), %xmm3     # 0x7008
movsd 0x28(%rsp), %xmm0
mulsd %xmm3, %xmm0
movsd 0x20(%rsp), %xmm4
divsd %xmm4, %xmm0
movsd 0x58(%rsp), %xmm1
mulsd %xmm3, %xmm1
divsd %xmm4, %xmm1
mulsd %xmm3, %xmm2
divsd %xmm4, %xmm2
movq (%r12), %rdx
leaq 0x38a7(%rip), %rdi      # 0x713f
movq 0x60(%rsp), %rsi
movb $0x3, %al
callq 0x3050
leaq (%r14,%r13,8), %rcx
addq $0x8, %rcx
incq %r13
movq (%rcx), %rbx
testq %rbx, %rbx
jne 0x3647
movq 0x38(%rsp), %rdi
callq 0x3230
movq %rbp, %rdi
callq 0x3230
xorl %eax, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x3390
movq 0x8(%r14), %rsi
leaq 0x37fa(%rip), %rdi      # 0x70e8
xorl %eax, %eax
callq 0x4da6