// File: /workspace/github_c_makefile_star2_O2/skeeto[P]hash-prospector/hp16.c
// Function: main
int
main(int argc, char **argv)
{
    char *ptr;
    int n = 0;
    int exclude = 0;
    enum {
        MODE_HASH, MODE_SMART, MODE_XORMUL, MODE_SBOX, MODE_AXS
    } mode = MODE_HASH;
    unsigned long tmp;
    struct hf_op ops[1+2*OPS_MAX] = {{HF16_SBOX, 0}};

    int option;
    while ((option = xgetopt(argc, argv, "AHhImn:rSX")) != -1) {
        switch (option) {
        case 'A':
            mode = MODE_AXS;
            break;
        case 'H':
            mode = MODE_HASH;
            break;
        case 'h':
            usage(stdout);
            return 0;
        case 'I':
            mode = MODE_SMART;
            break;
        case 'm':
            exclude |= 1<<HF16_MUL;
            break;
        case 'n':
            tmp = strtoul(xoptarg, &ptr, 10);
            if (!tmp || *ptr || tmp > OPS_MAX) {
                fprintf(stderr, "fatal: invalid n, %s\n", xoptarg);
                usage(stderr);
                return 1;
            }
            n = tmp;
            break;
        case 'r':
            exclude |= 1<<HF16_ROT;
            break;
        case 'S':
            mode = MODE_SBOX;
            break;
        case 'X':
            mode = MODE_XORMUL;
            break;
        case '?':
            usage(stderr);
            return 1;
        }
    }

    switch (mode) {
    case MODE_HASH:
    case MODE_SMART:  n = n ? n : 7; break;
    case MODE_XORMUL: n = n ? 1 + 2*n : 5; break;
    case MODE_SBOX:   sbox_init(); n = 1; break;
    case MODE_AXS:    break;
    }

    double best = 1;
    unsigned long long s[1] = {hash64(time(0))};

    if (mode == MODE_AXS) {
        #pragma omp parallel for
        for (long i = 0; i < AXS_COUNT; i++) {
            struct hf_op hf[AXS_SIZE];
            hf_genaxs(hf, i);
            double r = score(hf, AXS_SIZE);
            #pragma omp critical
            if (r < best) {
                best = r;
                printf("// bias = %.17g\n", r);
                hf_print(hf, AXS_SIZE, stdout);
                fputc('\n', stdout);
                fflush(stdout);
            }
        }
        return 0;
    }

    for (;;) {
        *s += hash64(time(0));
        switch (mode) {
        case MODE_HASH:
            do {
                hf_genfunc(ops, n, s);
            } while (match(ops, n, exclude));
            break;
        case MODE_SMART:
            do {
                hf_gensmart(ops, n, s);
            } while (match(ops, n, exclude));
            break;
        case MODE_XORMUL:
            hf_genxormul(ops, (n-1)/2, s);
            break;
        case MODE_SBOX:
            sbox_shuffle(s);
            break;
        case MODE_AXS:
            abort();
        }
        *s -= hash64(clock());

        double r = score(ops, n);
        if (r < best) {
            switch (mode) {
            case MODE_HASH:
            case MODE_SMART:
            case MODE_XORMUL:
                printf("// bias = %.17g\n", r);
                hf_print(ops, n, stdout);
                fputc('\n', stdout);
                break;
            case MODE_SBOX:
                fprintf(stdout, "// bias = %.17g\n", r);
                sbox_print(stdout);
                fputc('\n', stdout);
                fprintf(stderr, "// bias = %.17g\n", r);
                fflush(stderr);
                break;
            case MODE_AXS:
                abort();
            }
            fflush(stdout);
            best = r;
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2b8, %rsp            # imm = 0x2B8
movq %rsi, %r15
leaq 0xb0(%rsp), %rbx
movl $0x0, (%rsp)
movl $0x208, %edx            # imm = 0x208
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1070
movl $0x9, (%rbx)
movl 0x3e52(%rip), %ebp      # 0x509c
movl $0x0, 0xc(%rsp)
movq $0x0, 0x10(%rsp)
testl %ebp, %ebp
jne 0x126e
pushq $0x1
popq %rbp
movl %ebp, 0x3e34(%rip)      # 0x509c
movl %ebp, 0x3e2a(%rip)      # 0x5098
movslq %ebp, %rbx
movq (%r15,%rbx,8), %r13
testq %r13, %r13
je 0x142d
cmpb $0x2d, (%r13)
jne 0x142d
movsbq 0x1(%r13), %r14
cmpq $0x2d, %r14
jne 0x129f
cmpb $0x0, 0x2(%r13)
je 0x1425
callq 0x1100
movq (%rax), %rax
testb $0x8, (%rax,%r14,2)
je 0x142d
movslq 0x3ddf(%rip), %r14      # 0x5098
movsbl (%r13,%r14), %r12d
leaq 0x1e0e(%rip), %rdi      # 0x30d4
movl %r12d, %esi
pushq $0xb
popq %rdx
callq 0x1090
testq %rax, %rax
je 0x166e
cmpb $0x3a, 0x1(%rax)
jne 0x12f2
addq %r14, %r13
cmpb $0x0, 0x1(%r13)
je 0x1309
incq %r13
pushq $0x1
popq %rax
jmp 0x131a
leaq 0x1(%r14), %rax
movl %eax, 0x3d9c(%rip)      # 0x5098
cmpb $0x0, 0x1(%r13,%r14)
pushq $0x1
popq %rax
jne 0x1333
jmp 0x1321
movq 0x8(%r15,%rbx,8), %r13
pushq $0x2
popq %rax
testq %r13, %r13
je 0x16c4
movq %r13, 0x3d8f(%rip)      # 0x50b0
addl %eax, %ebp
movl %ebp, 0x3d73(%rip)      # 0x509c
movl $0x1, 0x3d65(%rip)      # 0x5098
cmpb $0x41, %r12b
je 0x138e
movzbl %r12b, %eax
cmpl $0x48, %eax
je 0x140f
cmpl $0x49, %eax
je 0x1399
cmpl $0x53, %eax
je 0x13af
cmpl $0x58, %eax
je 0x13a4
cmpl $0x6d, %eax
je 0x141b
cmpl $0x6e, %eax
je 0x13ba
cmpl $0x72, %eax
je 0x1405
cmpl $0x3f, %eax
je 0x168c
cmpl $0x68, %eax
je 0x164b
cmpl $0xff, %eax
jne 0x125b
jmp 0x142d
pushq $0x4
popq %rax
movl %eax, (%rsp)
jmp 0x125b
pushq $0x1
popq %rax
movl %eax, (%rsp)
jmp 0x125b
pushq $0x2
popq %rax
movl %eax, (%rsp)
jmp 0x125b
pushq $0x3
popq %rax
movl %eax, (%rsp)
jmp 0x125b
movq 0x3cef(%rip), %rdi      # 0x50b0
leaq 0xa8(%rsp), %rsi
pushq $0xa
popq %rdx
callq 0x10d0
testq %rax, %rax
je 0x16a0
cmpq $0x20, %rax
ja 0x16a0
movq 0xa8(%rsp), %rcx
cmpb $0x0, (%rcx)
jne 0x16a0
movq %rax, 0x10(%rsp)
movl 0x3c9c(%rip), %ebp      # 0x509c
jmp 0x125b
orl $0x8, 0xc(%rsp)
jmp 0x125b
movl $0x0, (%rsp)
jmp 0x125b
orl $0x2, 0xc(%rsp)
jmp 0x125b
incl %ebp
movl %ebp, 0x3c6f(%rip)      # 0x509c
movl (%rsp), %ebp
cmpl $0x2, %ebp
jb 0x1463
movq 0x10(%rsp), %r14
je 0x1475
cmpl $0x3, %ebp
jne 0x1485
leaq 0x3c78(%rip), %rax      # 0x50c0
xorl %ecx, %ecx
pushq $0x1
popq %r14
cmpq $0x10000, %rcx          # imm = 0x10000
je 0x1485
movw %cx, (%rax)
incq %rcx
addq $0x2, %rax
jmp 0x144e
movq 0x10(%rsp), %rcx
testl %ecx, %ecx
pushq $0x7
popq %rax
cmovnel %ecx, %eax
movl %eax, %r14d
jmp 0x1485
testl %r14d, %r14d
leal 0x1(%r14,%r14), %eax
pushq $0x5
popq %r14
cmovnel %eax, %r14d
xorl %ebx, %ebx
xorl %edi, %edi
callq 0x10b0
cmpl $0x4, %ebp
jne 0x16cd
leaq 0x64(%rsp), %r13
movsd 0x1b64(%rip), %xmm0     # 0x3008
movsd %xmm0, (%rsp)
pushq $0xf
popq %r14
movw $0xf, %r15w
movl $0xffff, %ebx           # imm = 0xFFFF
movq 0x3b1a(%rip), %rbp      # 0x4fd8
xorl %r12d, %r12d
cmpq $0xadcea10, %r12        # imm = 0xADCEA10
je 0x165a
movl %r12d, %eax
xorl %edx, %edx
divl %r14d
incl %edx
movl %edx, 0x30(%rsp)
xorl %edx, %edx
divl %r14d
incl %edx
movl %edx, 0x34(%rsp)
movl %r12d, %eax
xorl %edx, %edx
movl $0xe1, %ecx
divl %ecx
xorl %edx, %edx
divl %r14d
incl %edx
movl %edx, 0x38(%rsp)
movl %r12d, %eax
xorl %edx, %edx
movl $0xd2f, %ecx            # imm = 0xD2F
divl %ecx
xorl %edx, %edx
divw %r15w
incl %edx
andl %ebx, %edx
movl %edx, 0x3c(%rsp)
movl %r12d, %eax
xorl %edx, %edx
movl $0xc5c1, %ecx           # imm = 0xC5C1
divl %ecx
xorl %edx, %edx
divw %r15w
incl %edx
andl %ebx, %edx
movl %edx, 0x40(%rsp)
movl %r12d, %eax
xorl %edx, %edx
movl $0xb964f, %ecx          # imm = 0xB964F
divl %ecx
movzbl %al, %eax
movb $0xf, %cl
divb %cl
movzbl %ah, %eax
incb %al
movzbl %al, %eax
movl %eax, 0x44(%rsp)
movl %r12d, %eax
xorl %edx, %edx
movl $0xadcea1, %ecx         # imm = 0xADCEA1
divl %ecx
andl $0x1, %eax
movl %eax, 0x54(%rsp)
movl %r12d, %eax
xorl %edx, %edx
movl $0x15b9d42, %ecx        # imm = 0x15B9D42
divl %ecx
andl $0x1, %eax
movl %eax, 0x58(%rsp)
movl %r12d, %eax
xorl %edx, %edx
movl $0x2b73a84, %ecx        # imm = 0x2B73A84
divl %ecx
leal -0x2(%rax), %ecx
xorl %edx, %edx
xorl %esi, %esi
cmpq $0x56e7508, %r12        # imm = 0x56E7508
cmovbl %eax, %ecx
setb %dl
movl %ecx, 0x5c(%rsp)
setae %sil
leaq (,%rdx,8), %rax
addq %r13, %rax
leaq (,%rsi,8), %rcx
addq %r13, %rcx
xorl %edx, %edx
cmpq $0x5, %rdx
ja 0x15ea
cmpl $0x1, 0x54(%rsp,%rdx,2)
movl $0x0, %esi
adcl $0x7, %esi
movl %esi, -0x4(%rcx,%rdx,8)
movl 0x30(%rsp,%rdx,4), %esi
movl %esi, (%rcx,%rdx,8)
movl $0x6, -0x4(%rax,%rdx,8)
movl 0x34(%rsp,%rdx,4), %esi
movl %esi, (%rax,%rdx,8)
addq $0x2, %rdx
jmp 0x15b7
leaq 0x60(%rsp), %rdi
pushq $0x6
popq %rsi
callq 0x1cbb
movapd %xmm0, %xmm1
movsd (%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1643
leaq 0x1ae8(%rip), %rdi      # 0x30f5
movapd %xmm1, %xmm0
movb $0x1, %al
movsd %xmm1, (%rsp)
callq 0x1050
movq (%rbp), %rdx
leaq 0x60(%rsp), %rdi
pushq $0x6
popq %rsi
callq 0x1dd1
movq (%rbp), %rsi
pushq $0xa
popq %rdi
callq 0x1080
movq (%rbp), %rdi
callq 0x10c0
incq %r12
jmp 0x14c1
movq 0x3986(%rip), %rax      # 0x4fd8
movq (%rax), %rdi
callq 0x1b99
xorl %eax, %eax
addq $0x2b8, %rsp            # imm = 0x2B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1a91(%rip), %rsi      # 0x3106
movq 0x397c(%rip), %rax      # 0x4ff8
movq (%rax), %rdi
movq (%r15), %rdx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x10a0
movq 0x3965(%rip), %rax      # 0x4ff8
movq (%rax), %rdi
callq 0x1b99
pushq $0x1
popq %rax
jmp 0x165c
movq 0x3951(%rip), %rbx      # 0x4ff8
movq (%rbx), %rdi
movq 0x39ff(%rip), %rdx      # 0x50b0
leaq 0x1a27(%rip), %rsi      # 0x30df
xorl %eax, %eax
callq 0x10a0
movq (%rbx), %rdi
jmp 0x1696
leaq 0x1a53(%rip), %rsi      # 0x311e
jmp 0x1675
movabsq $0x7c3c3267d015ceb5, %r12 # imm = 0x7C3C3267D015CEB5
movq %rax, %rdi
callq 0x1c80
movq %rax, %rsi
leal -0x1(%r14), %eax
pushq $0x2
popq %rcx
cltd
idivl %ecx
testl %eax, %eax
cmovlel %ebx, %eax
movq %r14, 0x10(%rsp)
movl %r14d, %ebx
movq %rsi, %r14
shlq $0x4, %rax
movq %rax, 0xa0(%rsp)
movsd 0x18f8(%rip), %xmm0     # 0x3008
movsd %xmm0, 0x28(%rsp)
movl %ebp, %eax
leaq 0x1901(%rip), %rcx      # 0x3020
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
movq %rax, 0x98(%rsp)
leaq 0x60(%rsp), %r13
leaq 0x18fa(%rip), %rbp      # 0x3034
movq %rbx, 0x20(%rsp)
xorl %edi, %edi
callq 0x10b0
movq %rax, %rdi
callq 0x1c80
movq %rax, %r15
addq %r14, %r15
movq %r15, 0x60(%rsp)
jmpq *0x98(%rsp)
xorl %r14d, %r14d
cmpq %rbx, %r14
jne 0x178d
leaq 0xb0(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl 0xc(%rsp), %edx
callq 0x1f5e
movl $0x0, %r14d
testl %eax, %eax
jne 0x1763
jmp 0x1a3d
movl $0x21f, %r15d           # imm = 0x21F
movq 0x60(%rsp), %rax
movq %rax, %rcx
shrq $0x20, %rcx
movq %rax, %rdx
imulq %r12, %rdx
incq %rdx
movq %rdx, 0x60(%rsp)
shrq $0x30, %rax
xorl %eax, %ecx
imull $0x60857ba9, %ecx, %eax # imm = 0x60857BA9
xorl %edx, %edx
pushq $0x9
popq %rcx
divl %ecx
movl %edx, %edi
movq %r13, %rsi
callq 0x2064
testq %r14, %r14
je 0x17e7
movl 0xa8(%rsp,%r14,8), %ecx
cmpl $0x9, %ecx
ja 0x1793
btl %ecx, %r15d
jae 0x17e7
cmpl %eax, %ecx
je 0x1793
movq %rax, 0xb0(%rsp,%r14,8)
incq %r14
jmp 0x1763
xorl %r14d, %r14d
xorl %r15d, %r15d
cmpq %rbx, %r14
jne 0x182a
leaq 0xb0(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl 0xc(%rsp), %edx
callq 0x1f5e
xorl %r14d, %r14d
movl $0x0, %r15d
testl %eax, %eax
jne 0x17fd
jmp 0x1a3d
movq 0x60(%rsp), %rax
movq %rax, %rcx
shrq $0x20, %rcx
movq %rax, %rdx
imulq %r12, %rdx
incq %rdx
movq %rdx, 0x60(%rsp)
shrq $0x30, %rax
xorl %eax, %ecx
imull $0x60857ba9, %ecx, %eax # imm = 0x60857BA9
xorl %ebx, %ebx
xorl %edx, %edx
pushq $0x9
popq %rcx
divl %ecx
movl %edx, %edi
movq %r13, %rsi
callq 0x2064
cmpl $0x9, %eax
ja 0x1b94
movl %eax, %ecx
movslq (%rbp,%rcx,4), %rcx
addq %rbp, %rcx
jmpq *%rcx
pushq $0x1
popq %rbx
testl %r15d, %r15d
je 0x18ac
cmpl %r15d, %ebx
je 0x182a
jmp 0x18ac
pushq $-0x1
jmp 0x187b
movq %rax, %rcx
shrq $0x23, %rcx
pushq $0x1
popq %rbx
je 0x187c
movq %rax, %rcx
shrq $0x20, %rcx
cmpl $0x9, %ecx
movl $0x0, %ebx
adcl $-0x1, %ebx
jmp 0x187c
movq %rax, 0xb0(%rsp,%r14,8)
testl %ebx, %ebx
cmovnel %ebx, %r15d
incq %r14
movq 0x20(%rsp), %rbx
jmp 0x17fd
movl $0xffff, %esi           # imm = 0xFFFF
movl $0xffff, %ecx           # imm = 0xFFFF
leaq 0x37e8(%rip), %r14      # 0x50c0
subq $0x1, %rcx
jb 0x196b
leaq 0x1(%rsi), %r8
movq %r15, %rax
shrq $0x20, %rax
movq %r15, %rdi
imulq %r12, %rdi
incq %rdi
shrq $0x30, %r15
xorl %r15d, %eax
imull $0x60857ba9, %eax, %r9d # imm = 0x60857BA9
imulq %r8, %r9
movl %r9d, %r10d
cmpq %rsi, %r10
jbe 0x1931
movzwl (%r14,%rsi,2), %eax
shrq $0x20, %r9
movzwl (%r14,%r9,2), %edx
movw %dx, (%r14,%rsi,2)
movw %ax, (%r14,%r9,2)
movq %rdi, %r15
movq %rcx, %rsi
jmp 0x18d8
movq %rsi, %rax
notq %rax
xorl %edx, %edx
divq %r8
cmpq %rdx, %r10
jae 0x1911
movq %rdi, %rax
shrq $0x20, %rax
movq %rdi, %r11
imulq %r12, %r11
incq %r11
shrq $0x30, %rdi
xorl %edi, %eax
imull $0x60857ba9, %eax, %r9d # imm = 0x60857BA9
imulq %r8, %r9
movl %r9d, %r10d
movq %r11, %rdi
jmp 0x193c
movq %r15, 0x60(%rsp)
jmp 0x1a3d
movl $0x6, 0xb0(%rsp)
movq %r15, %rax
shrq $0x20, %rax
movq %r15, %rcx
shrq $0x30, %rcx
xorl %ecx, %eax
imull $0x60857ba9, %eax, %edi # imm = 0x60857BA9
shrl $0x12, %edi
callq 0x20be
incl %eax
movl %eax, 0xb4(%rsp)
xorl %r14d, %r14d
imulq %r12, %r15
incq %r15
cmpq %r14, 0xa0(%rsp)
je 0x1a33
movl $0x1, 0xb8(%rsp,%r14)
movq %r15, %rax
shrq $0x20, %rax
movq %r15, %rbx
imulq %r12, %rbx
incq %rbx
shrq $0x30, %r15
xorl %r15d, %eax
imull $0x60857ba9, %eax, %eax # imm = 0x60857BA9
shrl $0x10, %eax
orl $0x1, %eax
movl %eax, 0xbc(%rsp,%r14)
movl $0x6, 0xc0(%rsp,%r14)
movq %rbx, %rax
shrq $0x20, %rax
movq %rbx, %rcx
shrq $0x30, %rcx
xorl %ecx, %eax
imull $0x60857ba9, %eax, %edi # imm = 0x60857BA9
shrl $0x12, %edi
callq 0x20be
incl %eax
movl %eax, 0xc4(%rsp,%r14)
addq $0x10, %r14
movq %rbx, %r15
jmp 0x19aa
movq %r15, 0x60(%rsp)
movq 0x20(%rsp), %rbx
callq 0x1040
movq %rax, %rdi
callq 0x1c80
movq 0x60(%rsp), %r14
subq %rax, %r14
movq %r14, 0x60(%rsp)
leaq 0xb0(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x1cbb
movapd %xmm0, %xmm1
movsd 0x28(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x173f
movq %r14, 0x90(%rsp)
cmpl $0x3, (%rsp)
movsd %xmm1, 0x18(%rsp)
jae 0x1aeb
leaq 0x165d(%rip), %rdi      # 0x30f5
movapd %xmm1, %xmm0
movb $0x1, %al
callq 0x1050
movq 0x352e(%rip), %r14      # 0x4fd8
movq (%r14), %rdx
leaq 0xb0(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x1dd1
movq (%r14), %rsi
pushq $0xa
popq %rdi
callq 0x1080
movq (%r14), %rdi
callq 0x10c0
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x90(%rsp), %r14
jmp 0x173f
jne 0x1b94
movq 0x34e0(%rip), %rbx      # 0x4fd8
movq (%rbx), %rdi
leaq 0x15f3(%rip), %rsi      # 0x30f5
movsd 0x18(%rsp), %xmm0
movb $0x1, %al
callq 0x10a0
movq (%rbx), %r15
leaq 0x35a7(%rip), %rbx      # 0x50c0
xorl %r14d, %r14d
cmpq $0x10000, %r14          # imm = 0x10000
je 0x1b52
movzwl (%rbx), %edx
movl %r14d, %eax
notl %eax
testb $0xf, %al
pushq $0x20
popq %rcx
pushq $0xa
popq %rax
cmovel %eax, %ecx
movq %r15, %rdi
leaq 0x1865(%rip), %rsi      # 0x33a7
xorl %eax, %eax
callq 0x10a0
incq %r14
addq $0x2, %rbx
jmp 0x1b1c
movq 0x347f(%rip), %r14      # 0x4fd8
movq (%r14), %rsi
pushq $0xa
popq %rdi
callq 0x1080
movq 0x348d(%rip), %rbx      # 0x4ff8
movq (%rbx), %rdi
leaq 0x1580(%rip), %rsi      # 0x30f5
movsd 0x18(%rsp), %xmm0
movb $0x1, %al
callq 0x10a0
movq (%rbx), %rdi
callq 0x10c0
movq 0x20(%rsp), %rbx
jmp 0x1aca
callq 0x1030