// File: ArashPartow[P]exprtk/exprtk_benchmark.cpp
// Function: main
int main(int argc, char* argv[])
{
   if (argc >= 2)
   {
      const std::string file_name = argv[1];

      if (argc == 2)
         perform_file_based_benchmark(file_name);
      else
         perform_file_based_benchmark(file_name,atoi(argv[2]));

      return 0;
   }

   pgo_primer();

   double x = 0;
   double y = 0;

   exprtk::symbol_table<double> symbol_table;
   symbol_table.add_constants();
   symbol_table.add_variable("x",x);
   symbol_table.add_variable("y",y);

   std::deque<exprtk::expression<double> > compiled_expr_list;

   if (!load_expression(symbol_table,compiled_expr_list))
   {
      return 1;
   }

   {
      printf("--- EXPRTK ---\n");
      for (std::size_t i = 0; i < compiled_expr_list.size(); ++i)
      {
         run_exprtk_benchmark(x,y,compiled_expr_list[i],global_expression_list[i]);
      }
   }

   {
      printf("--- NATIVE ---\n");
      run_native_benchmark(x, y, native<double>::func00,global_expression_list[ 0]);
      run_native_benchmark(x, y, native<double>::func01,global_expression_list[ 1]);
      run_native_benchmark(x, y, native<double>::func02,global_expression_list[ 2]);
      run_native_benchmark(x, y, native<double>::func03,global_expression_list[ 3]);
      run_native_benchmark(x, y, native<double>::func04,global_expression_list[ 4]);
      run_native_benchmark(x, y, native<double>::func05,global_expression_list[ 5]);
      run_native_benchmark(x, y, native<double>::func06,global_expression_list[ 6]);
      run_native_benchmark(x, y, native<double>::func07,global_expression_list[ 7]);
      run_native_benchmark(x, y, native<double>::func08,global_expression_list[ 8]);
      run_native_benchmark(x, y, native<double>::func09,global_expression_list[ 9]);
      run_native_benchmark(x, y, native<double>::func10,global_expression_list[10]);
      run_native_benchmark(x, y, native<double>::func11,global_expression_list[11]);
      run_native_benchmark(x, y, native<double>::func12,global_expression_list[12]);
      run_native_benchmark(x, y, native<double>::func13,global_expression_list[13]);
      run_native_benchmark(x, y, native<double>::func14,global_expression_list[14]);
      run_native_benchmark(x, y, native<double>::func15,global_expression_list[15]);
      run_native_benchmark(x, y, native<double>::func16,global_expression_list[16]);
   }

   {
      printf("--- PARSE ----\n");
      run_parse_benchmark(symbol_table);
   }

   return 0;
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movl $0x0, 0x154(%rsp)
movl %edi, 0x150(%rsp)
movq %rsi, 0x148(%rsp)
cmpl $0x2, 0x150(%rsp)
jl 0x11cfe7
movq 0x148(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x28(%rsp)
leaq 0x127(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x1156d0
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
leaq 0x128(%rsp), %rdi
callq 0x11f450
jmp 0x11cf0b
leaq 0x127(%rsp), %rdi
callq 0x115800
cmpl $0x2, 0x150(%rsp)
jne 0x11cf96
movq $0x186a0, 0x108(%rsp) # imm = 0x186A0
leaq 0x128(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0x11d590
jmp 0x11cf45
jmp 0x11cfca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0x127(%rsp), %rdi
callq 0x115800
jmp 0x11d583
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0x128(%rsp), %rdi
callq 0x115818
jmp 0x11d583
movq 0x148(%rsp), %rax
movq 0x10(%rax), %rdi
callq 0x115290
cltq
movq %rax, 0x100(%rsp)
leaq 0x128(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x11d590
jmp 0x11cfc8
jmp 0x11cfca
movl $0x0, 0x154(%rsp)
leaq 0x128(%rsp), %rdi
callq 0x115818
jmp 0x11d574
callq 0x11f010
movq $0x0, 0xf8(%rsp)
movq $0x0, 0xf0(%rsp)
leaq 0xe8(%rsp), %rdi
movq %rdi, 0x20(%rsp)
movl $0x1, %esi
callq 0x11f510
movq 0x20(%rsp), %rdi
callq 0x11f550
jmp 0x11d027
leaq 0xc7(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x1156d0
movq 0x18(%rsp), %rdx
leaq 0x347815(%rip), %rsi    # 0x46485a
leaq 0xc8(%rsp), %rdi
callq 0x11f450
jmp 0x11d054
leaq 0xe8(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
xorl %ecx, %ecx
callq 0x11f5b0
jmp 0x11d075
leaq 0xc8(%rsp), %rdi
callq 0x115818
leaq 0xc7(%rsp), %rdi
callq 0x115800
leaq 0x9f(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x1156d0
movq 0x10(%rsp), %rdx
leaq 0x3476fb(%rip), %rsi    # 0x4647a8
leaq 0xa0(%rsp), %rdi
callq 0x11f450
jmp 0x11d0bc
leaq 0xe8(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
leaq 0xf0(%rsp), %rdx
xorl %ecx, %ecx
callq 0x11f5b0
jmp 0x11d0dd
leaq 0xa0(%rsp), %rdi
callq 0x115818
leaq 0x9f(%rsp), %rdi
callq 0x115800
leaq 0x48(%rsp), %rdi
callq 0x11f660
jmp 0x11d103
leaq 0xe8(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x11f670
movb %al, 0xf(%rsp)
jmp 0x11d11b
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x11d20f
jmp 0x11d129
movl $0x1, 0x154(%rsp)
movl $0x1, 0x44(%rsp)
jmp 0x11d54c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x11d565
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x11d191
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x115818
leaq 0xc7(%rsp), %rdi
callq 0x115800
jmp 0x11d565
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
jmp 0x11d1da
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x115818
leaq 0x9f(%rsp), %rdi
callq 0x115800
jmp 0x11d565
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x1206c0
jmp 0x11d565
leaq 0x347646(%rip), %rdi    # 0x46485c
xorl %eax, %eax
callq 0x1150b0
jmp 0x11d21f
movq $0x0, 0x38(%rsp)
movq 0x38(%rsp), %rax
movq %rax, (%rsp)
leaq 0x48(%rsp), %rdi
callq 0x11f890
movq %rax, %rcx
movq (%rsp), %rax
cmpq %rcx, %rax
jae 0x11d295
movq 0x38(%rsp), %rsi
leaq 0x48(%rsp), %rdi
callq 0x11fa30
movq %rax, %rdx
movq 0x38(%rsp), %rax
shlq $0x5, %rax
leaq 0x522cd7(%rip), %rcx    # 0x63ff40
addq %rax, %rcx
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11f8b0
jmp 0x11d283
jmp 0x11d285
movq 0x38(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x38(%rsp)
jmp 0x11d228
leaq 0x3475d0(%rip), %rdi    # 0x46486c
xorl %eax, %eax
callq 0x1150b0
jmp 0x11d2a5
leaq 0x2934(%rip), %rdx      # 0x11fbe0
leaq 0x522c8d(%rip), %rcx    # 0x63ff40
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d2ca
leaq 0x292f(%rip), %rdx      # 0x11fc00
leaq 0x522c88(%rip), %rcx    # 0x63ff60
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d2ef
leaq 0x293a(%rip), %rdx      # 0x11fc30
leaq 0x522c83(%rip), %rcx    # 0x63ff80
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d314
leaq 0x2945(%rip), %rdx      # 0x11fc60
leaq 0x522c7e(%rip), %rcx    # 0x63ffa0
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d339
leaq 0x2960(%rip), %rdx      # 0x11fca0
leaq 0x522c79(%rip), %rcx    # 0x63ffc0
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d35e
leaq 0x298b(%rip), %rdx      # 0x11fcf0
leaq 0x522c74(%rip), %rcx    # 0x63ffe0
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d383
leaq 0x29b6(%rip), %rdx      # 0x11fd40
leaq 0x522c6f(%rip), %rcx    # 0x640000
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d3a8
leaq 0x29e1(%rip), %rdx      # 0x11fd90
leaq 0x522c6a(%rip), %rcx    # 0x640020
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d3cd
leaq 0x2a5c(%rip), %rdx      # 0x11fe30
leaq 0x522c65(%rip), %rcx    # 0x640040
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d3f2
leaq 0x2b67(%rip), %rdx      # 0x11ff60
leaq 0x522c60(%rip), %rcx    # 0x640060
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d417
leaq 0x2b92(%rip), %rdx      # 0x11ffb0
leaq 0x522c5b(%rip), %rcx    # 0x640080
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d43c
leaq 0x2bcd(%rip), %rdx      # 0x120010
leaq 0x522c56(%rip), %rcx    # 0x6400a0
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d461
leaq 0x2c18(%rip), %rdx      # 0x120080
leaq 0x522c51(%rip), %rcx    # 0x6400c0
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d486
leaq 0x2c63(%rip), %rdx      # 0x1200f0
leaq 0x522c4c(%rip), %rcx    # 0x6400e0
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d4ab
leaq 0x2d0e(%rip), %rdx      # 0x1201c0
leaq 0x522c47(%rip), %rcx    # 0x640100
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d4d0
leaq 0x2d89(%rip), %rdx      # 0x120260
leaq 0x522c42(%rip), %rcx    # 0x640120
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d4f5
leaq 0x2e24(%rip), %rdx      # 0x120320
leaq 0x522c3d(%rip), %rcx    # 0x640140
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x11fa60
jmp 0x11d51a
leaq 0x34735b(%rip), %rdi    # 0x46487c
xorl %eax, %eax
callq 0x1150b0
jmp 0x11d52a
leaq 0xe8(%rsp), %rdi
callq 0x1203c0
jmp 0x11d539
movl $0x0, 0x154(%rsp)
movl $0x1, 0x44(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x1206c0
leaq 0xe8(%rsp), %rdi
callq 0x120730
jmp 0x11d574
leaq 0xe8(%rsp), %rdi
callq 0x120730
jmp 0x11d583
movl 0x154(%rsp), %eax
addq $0x158, %rsp            # imm = 0x158
retq
movq 0x118(%rsp), %rdi
callq 0x1154d0