// File: /workspace/github_cpp_makefile_star2_O2/quiath[P]fast-atoi/main.cpp
// Function: main
int main(int argc, char* argv[])
{
    unsigned MAX_WORD_LEN = 8;
    unsigned long N = 10000000UL;
    unsigned WORD_COUNT = 10000;
    bool digits_only = false;
    bool use_atol = false;
    std::string out_filename = "";

    std::vector<std::string> args(argv, argv + argc);
    int i = 1;
    while (i < args.size())
    {
        if (args[i] == "-t" || args[i] == "--unittest")
        {
            unit_test();
            return 0;
        }
        if (args[i] == "-d" || args[i] == "--digitsonly")
        {
            digits_only = true;
        }
        if (args[i] == "-a" || args[i] == "--atol")
        {
            use_atol = true;
        }

        if ((args[i] == "-l" || args[i] == "--length") && 
            i < args.size()) 
        {
            if ((MAX_WORD_LEN = atoi(args[i + 1].c_str())) > 20 || MAX_WORD_LEN == 0) 
            {
                std::cerr << "Invalid length" << std::endl;
                return 1;
            }
            i++;
        }       
        if ((args[i] == "-w" || args[i] == "--words") && 
            i < args.size())
        {
            if ((WORD_COUNT = atol(args[i + 1].c_str())) > 1000000 || WORD_COUNT == 0) 
            {
                std::cerr << "Invalid word count" << std::endl;
                return 1;
            }
            i++;
        }
        if ((args[i] == "-n" || args[i] == "--numloops") && 
            i < args.size())
        {
            if ((N = atol(args[i + 1].c_str())) > 1000000000000UL || N == 0) 
            {
                std::cerr << "Invalid number of loops" << std::endl;
                return 1;
            }
            i++;
        }
        if ((args[i] == "-o" || args[i] == "--output") && 
            i < args.size())
        {
            out_filename = args[i + 1];
            i++;
        }

        i++;
    }

    for (size_t L = 1; L <= MAX_WORD_LEN; ++L)
    {

        Name2Time best;
        std::vector<std::string> v;
        generate_add(v, WORD_COUNT, L, digits_only);


        std::cout << "Digits per number: " << L << " The string contains"
                  << (digits_only ? " digits only" : " whitespace and sign" ) << std::endl; 
        std::cout << "Int size in bytes:" << sizeof(myint) << std::endl;
        std::cout << "Loops:" << N << std::endl;
        std::cout << "Words:" << WORD_COUNT << std::endl;
        std::cout << "Ramp up:" << std::endl;
        test(N, atoi, v, best, "");

        for (int i = 0; i < 3; ++i) 
        {
            test(N, zero, v, best,            "zero..........");
            if (use_atol)
            {
                test(N, atol, v, best,            "atol..........");
            }
            else
            {
                test(N, atoi, v, best,            "atoi..........");
            }
            test(N, atoisimple, v, best,      "atoisimple....");
            test(N, fastatoi, v, best,        "fastatoi......");
            test(N, fastatoiadd, v, best,     "fastatoiadd...");
            test(N, fastatoiaddunr, v, best,  "fastatoiaddunr");
        }

        for (auto& kv : best)
        {
            std::cout << "Best: " << kv.first << " : " << std::setw(11) << kv.second << std::endl;
        }

        if (out_filename.length() > 0) 
        {
            std::ofstream f(out_filename.c_str(), std::ios::app | std::ios::out);
            if (!f.fail())
            {
                if (L == 1)
                {
                    // header
                    f << "\"Length\",\"Digits only\"" ;
                    for (auto& kv : best)
                    {
                         f << ",\"" << kv.first << "\""; 
                    }
                    f << std::endl;
                }
                f << L << "," << (digits_only ? 1 : 0);

                for (auto& kv : best)
                {
                    f << "," << kv.second;
                }
                f << std::endl;
            }
        }
        else
        {
          std::cout << "No output file param" << std::endl;
        }
    
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2b8, %rsp            # imm = 0x2B8
movq %rsi, %rbx
movl %edi, %ebp
leaq 0x24b9(%rip), %rsi      # 0x5046
leaq 0x80(%rsp), %rdi
leaq 0xb8(%rsp), %rdx
callq 0x20a0
movslq %ebp, %rax
leaq (%rbx,%rax,8), %rdx
leaq 0xb8(%rsp), %rcx
movq %rsp, %rdi
movq %rbx, %rsi
callq 0x360e
pushq $0x8
popq %r14
movl $0x989680, %ebx         # imm = 0x989680
movl $0x2710, %eax           # imm = 0x2710
movq %rax, 0x28(%rsp)
pushq $0x1
popq %r12
movl $0x0, 0x24(%rsp)
movl $0x0, 0x18(%rsp)
movq (%rsp), %rdi
movq 0x8(%rsp), %rax
movslq %r12d, %r15
subq %rdi, %rax
sarq $0x5, %rax
cmpq %r15, %rax
jbe 0x2e8f
movq %r15, %rbp
shlq $0x5, %rbp
leaq 0x24d9(%rip), %rsi      # 0x50e6
addq %rbp, %rdi
callq 0x3642
testb %al, %al
jne 0x2e83
movq (%rsp), %rdi
leaq 0x24c1(%rip), %rsi      # 0x50e9
addq %rbp, %rdi
callq 0x3642
testb %al, %al
jne 0x2e83
movq (%rsp), %rdi
leaq 0x24b1(%rip), %rsi      # 0x50f4
addq %rbp, %rdi
callq 0x3642
testb %al, %al
jne 0x2c66
movq (%rsp), %rdi
leaq 0x249d(%rip), %rsi      # 0x50f7
addq %rbp, %rdi
callq 0x3642
testb %al, %al
je 0x2c6c
movb $0x1, %al
movl %eax, 0x18(%rsp)
movq (%rsp), %rdi
leaq 0x248d(%rip), %rsi      # 0x5104
addq %rbp, %rdi
callq 0x3642
testb %al, %al
jne 0x2c9a
movq (%rsp), %rdi
leaq 0x2479(%rip), %rsi      # 0x5107
addq %rbp, %rdi
callq 0x3642
testb %al, %al
je 0x2ca0
movb $0x1, %al
movl %eax, 0x24(%rsp)
movq (%rsp), %rdi
leaq 0x2463(%rip), %rsi      # 0x510e
addq %rbp, %rdi
callq 0x3642
testb %al, %al
jne 0x2cce
addq (%rsp), %rbp
leaq 0x244f(%rip), %rsi      # 0x5111
movq %rbp, %rdi
callq 0x3642
testb %al, %al
je 0x2d0f
movq (%rsp), %rbp
movq 0x8(%rsp), %rax
subq %rbp, %rax
sarq $0x5, %rax
cmpq %r15, %rax
jbe 0x2d13
movslq %r12d, %r15
incq %r15
movq %r15, %rax
shlq $0x5, %rax
movq (%rbp,%rax), %rdi
callq 0x22e0
movl %eax, %r14d
leal -0x15(%r14), %eax
cmpl $-0x15, %eax
jbe 0x3374
incl %r12d
jmp 0x2d13
movq (%rsp), %rbp
movq %r15, %r13
shlq $0x5, %r13
leaq 0x2408(%rip), %rsi      # 0x5129
addq %r13, %rbp
movq %rbp, %rdi
callq 0x3642
testb %al, %al
jne 0x2d47
addq (%rsp), %r13
leaq 0x23f1(%rip), %rsi      # 0x512c
movq %r13, %rdi
callq 0x3642
testb %al, %al
je 0x2d8d
movq (%rsp), %rbp
movq 0x8(%rsp), %rax
subq %rbp, %rax
sarq $0x5, %rax
cmpq %r15, %rax
jbe 0x2d91
movslq %r12d, %r15
incq %r15
movq %r15, %rax
shlq $0x5, %rax
movq (%rbp,%rax), %rdi
callq 0x22d8
movq %rax, 0x28(%rsp)
addl $0xfff0bdbf, %eax       # imm = 0xFFF0BDBF
cmpl $0xfff0bdc0, %eax       # imm = 0xFFF0BDC0
jb 0x337d
incl %r12d
jmp 0x2d91
movq (%rsp), %rbp
movq %r15, %r13
shlq $0x5, %r13
leaq 0x23a8(%rip), %rsi      # 0x5147
addq %r13, %rbp
movq %rbp, %rdi
callq 0x3642
testb %al, %al
jne 0x2dc5
addq (%rsp), %r13
leaq 0x2391(%rip), %rsi      # 0x514a
movq %r13, %rdi
callq 0x3642
testb %al, %al
je 0x2e12
movq (%rsp), %rbp
movq 0x8(%rsp), %rax
subq %rbp, %rax
sarq $0x5, %rax
cmpq %r15, %rax
jbe 0x2e16
movslq %r12d, %r15
incq %r15
movq %r15, %rax
shlq $0x5, %rax
movq (%rbp,%rax), %rdi
callq 0x22d8
movabsq $-0xe8d4a51001, %rcx    # imm = 0xFFFFFF172B5AEFFF
movq %rax, %rbx
addq %rcx, %rax
incq %rcx
cmpq %rcx, %rax
jb 0x3386
incl %r12d
jmp 0x2e16
movq (%rsp), %rbp
movq %r15, %r13
shlq $0x5, %r13
leaq 0x2349(%rip), %rsi      # 0x516d
addq %r13, %rbp
movq %rbp, %rdi
callq 0x3642
testb %al, %al
jne 0x2e4a
addq (%rsp), %r13
leaq 0x2332(%rip), %rsi      # 0x5170
movq %r13, %rdi
callq 0x3642
testb %al, %al
je 0x2e7b
movq (%rsp), %rax
movq 0x8(%rsp), %rcx
subq %rax, %rcx
sarq $0x5, %rcx
cmpq %r15, %rcx
jbe 0x2e7b
movslq %r12d, %rcx
shlq $0x5, %rcx
leaq 0x20(%rcx,%rax), %rsi
leaq 0x80(%rsp), %rdi
callq 0x2100
incl %r12d
incl %r12d
jmp 0x2be3
callq 0x2593
xorl %ebx, %ebx
jmp 0x33a4
movl 0x18(%rsp), %edi
leaq 0x2308(%rip), %rax      # 0x51a2
leaq 0x230e(%rip), %rdx      # 0x51af
movl %r14d, %ecx
movzbl %dil, %esi
andb $0x1, %dil
cmovneq %rax, %rdx
movl 0x28(%rsp), %eax
incq %rcx
movq %rdx, 0x70(%rsp)
movzbl %dil, %edx
movq %rcx, 0x78(%rsp)
movl %edx, 0x30(%rsp)
movq %rax, 0x68(%rsp)
pushq $0x1
popq %rdx
andl $0x1, %esi
leaq 0xa0(%rsp), %r12
leaq 0xb8(%rsp), %rbp
leaq 0x23(%rsp), %r14
leaq 0x38(%rsp), %r13
movl %esi, 0x34(%rsp)
cmpq 0x78(%rsp), %rdx
je 0x2e88
leaq 0x40(%rsp), %rax
andl $0x0, 0x40(%rsp)
andq $0x0, 0x48(%rsp)
andq $0x0, 0xb0(%rsp)
vxorps %xmm0, %xmm0, %xmm0
movq %rax, 0x50(%rsp)
movq %rax, 0x58(%rsp)
andq $0x0, 0x60(%rsp)
vmovaps %xmm0, 0xa0(%rsp)
movl 0x34(%rsp), %ecx
movq 0x28(%rsp), %rsi
movq %rdx, 0x18(%rsp)
movq %r12, %rdi
callq 0x296f
movq 0x507c(%rip), %rdi      # 0x7fc8
leaq 0x2226(%rip), %rsi      # 0x5179
callq 0x21c0
movq 0x18(%rsp), %rsi
movq %rax, %rdi
callq 0x2140
leaq 0x2221(%rip), %rsi      # 0x518d
movq %rax, %rdi
callq 0x21c0
movq 0x70(%rsp), %rsi
movq %rax, %rdi
callq 0x21c0
movq %rax, %rdi
callq 0x20e0
movq 0x5038(%rip), %rdi      # 0x7fc8
leaq 0x222d(%rip), %rsi      # 0x51c4
callq 0x21c0
movq %rax, %rdi
pushq $0x8
popq %rsi
callq 0x2140
movq %rax, %rdi
callq 0x20e0
movq 0x5012(%rip), %rdi      # 0x7fc8
leaq 0x221a(%rip), %rsi      # 0x51d7
callq 0x21c0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2140
movq %rax, %rdi
callq 0x20e0
movq 0x4fec(%rip), %rdi      # 0x7fc8
leaq 0x21fb(%rip), %rsi      # 0x51de
callq 0x21c0
movq 0x68(%rsp), %rsi
movq %rax, %rdi
callq 0x2140
movq %rax, %rdi
callq 0x20e0
movq 0x4fc4(%rip), %rdi      # 0x7fc8
leaq 0x21da(%rip), %rsi      # 0x51e5
callq 0x21c0
movq %rax, %rdi
callq 0x20e0
leaq 0x2027(%rip), %rsi      # 0x5046
movq %rbp, %rdi
movq %r14, %rdx
callq 0x20a0
movq 0x4f9f(%rip), %rsi      # 0x7fd0
movq %rbx, %rdi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x364f
movq %rbp, %rdi
callq 0x20d0
pushq $0x3
popq %r15
subl $0x1, %r15d
jb 0x31bc
leaq 0x218f(%rip), %rsi      # 0x51ee
movq %rbp, %rdi
movq %r14, %rdx
callq 0x20a0
leaq -0xaf1(%rip), %rsi      # 0x2580
movq %rbx, %rdi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x3885
movq %rbp, %rdi
callq 0x20d0
testb $0x1, 0x24(%rsp)
je 0x30bd
leaq 0x2165(%rip), %rsi      # 0x51fd
movq %rbp, %rdi
movq %r14, %rdx
callq 0x20a0
movq 0x4f16(%rip), %rsi      # 0x7fc0
movq %rbx, %rdi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x3885
jmp 0x30e7
leaq 0x2148(%rip), %rsi      # 0x520c
movq %rbp, %rdi
movq %r14, %rdx
callq 0x20a0
movq 0x4efa(%rip), %rsi      # 0x7fd0
movq %rbx, %rdi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x364f
movq %rbp, %rdi
callq 0x20d0
leaq 0x2125(%rip), %rsi      # 0x521b
movq %rbp, %rdi
movq %r14, %rdx
callq 0x20a0
leaq -0xcfc(%rip), %rsi      # 0x240c
movq %rbx, %rdi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x3885
movq %rbp, %rdi
callq 0x20d0
leaq 0x2102(%rip), %rsi      # 0x522a
movq %rbp, %rdi
movq %r14, %rdx
callq 0x20a0
leaq -0xce1(%rip), %rsi      # 0x2459
movq %rbx, %rdi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x3885
movq %rbp, %rdi
callq 0x20d0
leaq 0x20df(%rip), %rsi      # 0x5239
movq %rbp, %rdi
movq %r14, %rdx
callq 0x20a0
leaq -0xcc3(%rip), %rsi      # 0x24a9
movq %rbx, %rdi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x3885
movq %rbp, %rdi
callq 0x20d0
leaq 0x20bc(%rip), %rsi      # 0x5248
movq %rbp, %rdi
movq %r14, %rdx
callq 0x20a0
leaq -0xc9a(%rip), %rsi      # 0x2504
movq %rbx, %rdi
movq %r12, %rdx
movq %r13, %rcx
movq %rbp, %r8
callq 0x3885
movq %rbp, %rdi
callq 0x20d0
jmp 0x304e
movq 0x50(%rsp), %r15
leaq 0x40(%rsp), %rax
cmpq %rax, %r15
je 0x322a
movq 0x4df6(%rip), %rdi      # 0x7fc8
leaq 0x207e(%rip), %rsi      # 0x5257
callq 0x21c0
leaq 0x20(%r15), %rsi
movq %rax, %rdi
callq 0x2190
leaq 0x206d(%rip), %rsi      # 0x525e
movq %rax, %rdi
callq 0x21c0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0xb, 0x10(%rax,%rcx)
movq 0x40(%r15), %rsi
movq %rax, %rdi
callq 0x2130
movq %rax, %rdi
callq 0x20e0
movq %r15, %rdi
callq 0x2150
movq %rax, %r15
jmp 0x31c1
cmpq $0x0, 0x88(%rsp)
je 0x32c3
movq 0x80(%rsp), %rsi
movq %rbp, %rdi
pushq $0x11
popq %rdx
callq 0x2200
movq 0xb8(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0xd8(%rsp,%rax)
jne 0x334f
cmpq $0x1, 0x18(%rsp)
jne 0x32e8
leaq 0x1fed(%rip), %rsi      # 0x5262
movq %rbp, %rdi
callq 0x21c0
movq 0x50(%rsp), %r15
leaq 0x40(%rsp), %rax
cmpq %rax, %r15
je 0x32e0
leaq 0x1fe6(%rip), %rsi      # 0x5279
movq %rbp, %rdi
callq 0x21c0
leaq 0x20(%r15), %rsi
movq %rax, %rdi
callq 0x2190
leaq 0x1fcc(%rip), %rsi      # 0x527a
movq %rax, %rdi
callq 0x21c0
movq %r15, %rdi
callq 0x2150
movq %rax, %r15
jmp 0x3282
movq 0x4cfe(%rip), %rdi      # 0x7fc8
leaq 0x1fad(%rip), %rsi      # 0x527e
callq 0x21c0
movq %rax, %rdi
callq 0x20e0
jmp 0x3357
movq %rbp, %rdi
callq 0x20e0
movq 0x18(%rsp), %rsi
movq %rbp, %rdi
callq 0x2140
leaq 0x1f80(%rip), %rsi      # 0x527c
movq %rax, %rdi
callq 0x21c0
movl 0x30(%rsp), %esi
movq %rax, %rdi
callq 0x2290
movq 0x50(%rsp), %r15
leaq 0x40(%rsp), %rax
cmpq %rax, %r15
je 0x3347
leaq 0x1f56(%rip), %rsi      # 0x527c
movq %rbp, %rdi
callq 0x21c0
movq 0x40(%r15), %rsi
movq %rax, %rdi
callq 0x2130
movq %r15, %rdi
callq 0x2150
movq %rax, %r15
jmp 0x3315
movq %rbp, %rdi
callq 0x20e0
movq %rbp, %rdi
callq 0x2240
movq %r12, %rdi
callq 0x34ce
movq %r13, %rdi
callq 0x3ac4
movq 0x18(%rsp), %rdx
incq %rdx
jmp 0x2ef2
leaq 0x1d9f(%rip), %rsi      # 0x511a
jmp 0x338d
leaq 0x1db0(%rip), %rsi      # 0x5134
jmp 0x338d
leaq 0x1dc8(%rip), %rsi      # 0x5155
movq 0x4c5c(%rip), %rdi      # 0x7ff0
callq 0x21c0
movq %rax, %rdi
callq 0x20e0
pushq $0x1
popq %rbx
movq %rsp, %rdi
callq 0x34ce
leaq 0x80(%rsp), %rdi
callq 0x20d0
movl %ebx, %eax
addq $0x2b8, %rsp            # imm = 0x2B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x3445
jmp 0x33d4
movq %rax, %rbx
jmp 0x343d
jmp 0x3423
jmp 0x3423
jmp 0x3411
jmp 0x33e3
jmp 0x33e3
leaq 0xb8(%rsp), %rdi
movq %rax, %rbx
callq 0x2240
jmp 0x3426
jmp 0x3411
jmp 0x3411
jmp 0x3423
jmp 0x3423
jmp 0x3423
jmp 0x3423
jmp 0x3423
jmp 0x3411
jmp 0x3411
jmp 0x3423
jmp 0x3411
jmp 0x3423
jmp 0x3411
jmp 0x3423
leaq 0xb8(%rsp), %rdi
movq %rax, %rbx
callq 0x20d0
jmp 0x3426
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x34ce
leaq 0x38(%rsp), %rdi
callq 0x3ac4
movq %rsp, %rdi
callq 0x34ce
leaq 0x80(%rsp), %rdi
callq 0x20d0
movq %rbx, %rdi
callq 0x22a0