// File: /workspace/github_cpp_makefile_star2_O2/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 0x6b32(%rip), %rax      # 0x9fc8
movq (%rax), %rdi
pushq $0x1
popq %rdx
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x3030
cmpl $0x3, %ebp
jle 0x37ef
movq 0x8(%rbx), %rdi
cmpb $0x2d, (%rdi)
jne 0x34cd
cmpb $0x76, 0x1(%rdi)
jne 0x34cd
xorl %eax, %eax
cmpb $0x0, 0x2(%rdi)
sete %al
movq 0x8(%rbx,%rax,8), %rdi
jmp 0x34cf
xorl %eax, %eax
movzbl %al, %eax
movl %eax, 0x729c(%rip)      # 0xa774
leaq (%rbx,%rax,8), %r14
callq 0x5218
movq %rax, %rdi
movq %rdx, %rsi
callq 0x4bc3
testq %rax, %rax
je 0x3821
movq %rax, %r12
movq %rdx, %rbx
movq 0x10(%r14), %rdi
callq 0x32d0
orl $0x1, %eax
movl %eax, 0x2c(%rsp)
pushq $0xa
popq %rsi
leaq 0x1c(%rsp), %r15
movq %r12, 0x48(%rsp)
movq %r12, %rdi
movq %r15, %rdx
callq 0x511c
movq %rax, 0x30(%rsp)
movslq (%r15), %rdi
shlq $0x3, %rdi
callq 0x3260
movq %rax, %r15
cmpl $0x0, 0x7236(%rip)      # 0xa774
je 0x3551
leaq 0x3bb3(%rip), %rdi      # 0x70fa
movq %rbx, %rsi
xorl %eax, %eax
callq 0x3050
movl 0x2c(%rsp), %eax
testl %eax, %eax
movl $0x0, %ecx
cmovgl %eax, %ecx
movl %ecx, 0x44(%rsp)
movq 0x30(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x50(%rsp)
pushq $0x3
popq %rbp
movq %r14, 0x58(%rsp)
movq (%r14,%rbp,8), %r13
testq %r13, %r13
je 0x37ca
movq %rbp, 0x70(%rsp)
movq %r13, %rdi
callq 0x30c0
movq %rax, 0x68(%rsp)
movslq 0x1c(%rsp), %rbx
movq %rbx, %rdx
shlq $0x3, %rdx
movq %r15, %rdi
movl $0xff, %esi
callq 0x3100
callq 0x5481
movsd %xmm0, 0x20(%rsp)
testl %ebx, %ebx
movl $0x0, %ebp
cmovgl %ebx, %ebp
movq 0x50(%rsp), %r14
xorl %ebx, %ebx
cmpq %rbx, %rbp
je 0x35ff
movq -0x8(%r14), %r12
movq %r12, %rdi
movq %r13, %rsi
callq 0x3070
movq (%r15,%rbx,8), %rcx
cmpq $-0x1, %rcx
je 0x35f2
cmpq %rax, %rcx
je 0x35f6
jmp 0x364a
movq %rax, (%r15,%rbx,8)
incq %rbx
addq $0x10, %r14
jmp 0x35cd
shlq $0x3, %rbp
xorl %ebx, %ebx
cmpl 0x44(%rsp), %ebx
je 0x363a
xorl %r14d, %r14d
cmpq %r14, %rbp
je 0x3636
movq (%r15,%r14), %r12
movq 0x30(%rsp), %rax
movq (%rax,%r14,2), %rdi
movq %r13, %rsi
callq 0x3070
addq $0x8, %r14
cmpq %rax, %r12
je 0x360e
jmp 0x36d4
incl %ebx
jmp 0x3605
callq 0x5481
subsd 0x20(%rsp), %xmm0
jmp 0x36d8
movq 0x698f(%rip), %rdx      # 0x9fe0
movq (%rdx), %rdx
movq %rdx, 0x20(%rsp)
movq %rcx, %rdx
subq %r12, %rdx
cmpq $0x1, %rcx
movl $0x0, %ecx
sbbq %rcx, %rcx
orq %rdx, %rcx
movq %rcx, 0x38(%rsp)
movq %rax, %rcx
subq %r12, %rcx
cmpq $0x1, %rax
movl $0x0, %ebp
sbbq %rbp, %rbp
orq %rcx, %rbp
movq (%r14), %r14
movq %r12, %rdi
movl %r14d, %esi
callq 0x43d0
movq %rax, %r12
movq %rax, 0x10(%rsp)
movq %r14, 0x8(%rsp)
movq %rbp, (%rsp)
movq 0x20(%rsp), %rdi
leaq 0x3ab7(%rip), %rsi      # 0x716a
leaq 0x3a63(%rip), %rdx      # 0x711d
movq %r13, %rcx
movl %ebx, %r8d
movq 0x38(%rsp), %r9
xorl %eax, %eax
callq 0x32a0
movq %r12, %rdi
callq 0x3230
xorpd %xmm0, %xmm0
movsd %xmm0, 0x20(%rsp)
movl 0x1c(%rsp), %ecx
movq 0x58(%rsp), %r14
movq 0x70(%rsp), %rbp
movq (%r14,%rbp,8), %r9
movq %r15, (%rsp)
leaq 0x3a29(%rip), %rdi      # 0x7124
leaq 0x2a3(%rip), %rsi       # 0x39a5
movq 0x30(%rsp), %r12
movq %r12, %rdx
movl 0x2c(%rsp), %ebx
movl %ebx, %r8d
callq 0x3833
movsd %xmm0, 0x38(%rsp)
movl 0x1c(%rsp), %ecx
movq (%r14,%rbp,8), %r9
movq %r15, (%rsp)
leaq 0x39fc(%rip), %rdi      # 0x712b
leaq 0x507(%rip), %rsi       # 0x3c3d
movq %r12, %rdx
movl %ebx, %r8d
callq 0x3833
movsd %xmm0, 0x60(%rsp)
movl 0x1c(%rsp), %ecx
movq (%r14,%rbp,8), %r9
movq %r15, (%rsp)
leaq 0x39db(%rip), %rdi      # 0x7135
leaq 0x7cd(%rip), %rsi       # 0x3f2e
movq %r12, %rdx
movl %ebx, %r8d
callq 0x3833
cmpl $0x0, 0x7001(%rip)      # 0xa774
je 0x37c2
movapd %xmm0, %xmm2
movsd 0x3887(%rip), %xmm3     # 0x7008
movsd 0x38(%rsp), %xmm0
mulsd %xmm3, %xmm0
movsd 0x20(%rsp), %xmm4
divsd %xmm4, %xmm0
movsd 0x60(%rsp), %xmm1
mulsd %xmm3, %xmm1
divsd %xmm4, %xmm1
mulsd %xmm3, %xmm2
divsd %xmm4, %xmm2
movq (%r14,%rbp,8), %rdx
leaq 0x3989(%rip), %rdi      # 0x713f
movq 0x68(%rsp), %rsi
movb $0x3, %al
callq 0x3050
incq %rbp
jmp 0x3579
movq 0x30(%rsp), %rdi
callq 0x3230
movq 0x48(%rsp), %rdi
callq 0x3230
xorl %eax, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x67ea(%rip), %rax      # 0x9fe0
movq (%rax), %rbx
callq 0x4d19
leaq 0x3957(%rip), %rsi      # 0x715c
leaq 0x3804(%rip), %rcx      # 0x7010
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x32a0
pushq $0x2
popq %rdi
callq 0x32f0
movq 0x8(%r14), %rsi
leaq 0x38bc(%rip), %rdi      # 0x70e8
xorl %eax, %eax
callq 0x4c11