// File: /workspace/github_cpp_makefile_star2_O2/ArashPartow[P]exprtk-extras/exprtk_rtc_overhead.cpp
// Function: void vector_rtc_overhead_analysis_01<double>()
void vector_rtc_overhead_analysis_01()
{
   typedef exprtk::expression<T> expression_t;
   typedef exprtk::parser<T>     parser_t;

   const std::string sieve_of_eratosthenes_program =
      " var sieve[10^8] := [false];                   "
      " var m := trunc(sqrt(sieve[]));                "
      "                                               "
      " sieve[0] := true;                             "
      " sieve[1] := true;                             "
      "                                               "
      " for (var i := 0; i <= m; i += 1)              "
      " {                                             "
      "    assert(i < sieve[]);                       "
      "    if (false == sieve[i])                     "
      "    {                                          "
      "       for (var j := i^2; j < sieve[]; j += i) "
      "       {                                       "
      "          assert(j < sieve[]);                 "
      "          sieve[j] := true;                    "
      "       }                                       "
      "    }                                          "
      " };                                            "
      "                                               "
      " var prime_count := sieve[] - sum(sieve);      "
      "                                               "
      " prime_count == 5761455;                       ";

   T nortc_result  = T(0);
   T rtc_result    = T(0);
   T assert_result = T(0);

   T nortc_time_sec  = T(0);
   T rtc_time_sec    = T(0);
   T assert_time_sec = T(0);

   {
      expression_t expression;

      parser_t parser;
      parser.compile(sieve_of_eratosthenes_program,expression);

      exprtk::timer timer;
      timer.start();

      nortc_result = expression.value();

      timer.stop();
      nortc_time_sec = timer.time();
   }

   {
      vector_access_rtc vec_rtc;

      expression_t expression;

      parser_t parser;
      parser.register_vector_access_runtime_check(vec_rtc);
      parser.compile(sieve_of_eratosthenes_program,expression);

      exprtk::timer timer;
      timer.start();

      rtc_result = expression.value();

      timer.stop();
      rtc_time_sec = timer.time();
   }

   {
      assert_handler asrt_handler;
      expression_t expression;

      parser_t parser;
      parser.register_assert_check(asrt_handler);
      parser.compile(sieve_of_eratosthenes_program,expression);

      exprtk::timer timer;
      timer.start();

      assert_result = expression.value();

      timer.stop();
      assert_time_sec = timer.time();
   }

   if (
        (nortc_result == T(1)         ) &&
        (nortc_result == rtc_result   ) &&
        (nortc_result == assert_result)
      )
   {
      printf("Prime Sieve - NORTC time: %5.3fsec\tRTC time: %5.3fsec\tassert time: %5.3fsec\trtc_overhead: %5.3f%%\tassert_overhead: %5.3f%%\n",
             nortc_time_sec,
             rtc_time_sec,
             assert_time_sec,
             std::max(0.0, 100.0 * ((rtc_time_sec    - nortc_time_sec) / nortc_time_sec)),
             std::max(0.0, 100.0 * ((assert_time_sec - nortc_time_sec) / nortc_time_sec)));
   }
   else
      printf("ERROR - Results of NORTC and RTC runs do not match!\n");
}

// Assembly:
pushq %r14
pushq %rbx
subq $0xb08, %rsp            # imm = 0xB08
leaq 0x12ad89(%rip), %rsi    # 0x23b10f
leaq 0x40(%rsp), %rdi
leaq 0x1e0(%rsp), %rdx
callq 0x11033a
movq %rsp, %rdi
callq 0x110d8c
leaq 0x90(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x110dec
leaq 0x1e0(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x110efc
leaq 0x90(%rsp), %rdi
callq 0x111514
leaq 0x1e0(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movq %rsp, %rdx
callq 0x11155c
leaq 0x90(%rsp), %rdi
movb $0x0, (%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rdi)
movups %xmm0, 0x18(%rdi)
callq 0x1119de
movq (%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
movsd %xmm0, 0x38(%rsp)
leaq 0x90(%rsp), %rbx
movq %rbx, %rdi
callq 0x1119ec
movq %rbx, %rdi
callq 0x111a00
movaps %xmm0, 0x80(%rsp)
leaq 0x1e0(%rsp), %rdi
callq 0x111a32
movq %rsp, %rdi
callq 0x111b6c
leaq 0x2b484e(%rip), %rax    # 0x3c4ca0
movq %rax, 0x20(%rsp)
movq %rsp, %rdi
callq 0x110d8c
leaq 0x90(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x110dec
leaq 0x1e0(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x110efc
leaq 0x90(%rsp), %rdi
callq 0x111514
leaq 0x20(%rsp), %r14
leaq 0x1e0(%rsp), %rdi
movq %r14, 0x8e0(%rdi)
leaq 0x40(%rsp), %rsi
movq %rsp, %rdx
callq 0x11155c
leaq 0x90(%rsp), %rdi
movb $0x0, (%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rdi)
movups %xmm0, 0x18(%rdi)
callq 0x1119de
movq (%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
movsd %xmm0, 0x30(%rsp)
leaq 0x90(%rsp), %rbx
movq %rbx, %rdi
callq 0x1119ec
movq %rbx, %rdi
callq 0x111a00
movaps %xmm0, 0x70(%rsp)
leaq 0x1e0(%rsp), %rdi
callq 0x111a32
movq %rsp, %rdi
callq 0x111b6c
leaq 0x2b47d6(%rip), %rax    # 0x3c4cf0
movq %rax, 0x20(%rsp)
movq %rsp, %rdi
callq 0x110d8c
leaq 0x90(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x110dec
leaq 0x1e0(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x110efc
leaq 0x90(%rsp), %rdi
callq 0x111514
leaq 0x1e0(%rsp), %rdi
movq %r14, 0x8f0(%rdi)
leaq 0x40(%rsp), %rsi
movq %rsp, %rdx
callq 0x11155c
leaq 0x90(%rsp), %rdi
movb $0x0, (%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rdi)
movups %xmm0, 0x18(%rdi)
callq 0x1119de
movq (%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
movsd %xmm0, 0x28(%rsp)
leaq 0x90(%rsp), %rbx
movq %rbx, %rdi
callq 0x1119ec
movq %rbx, %rdi
callq 0x111a00
movaps %xmm0, 0x60(%rsp)
leaq 0x1e0(%rsp), %rdi
callq 0x111a32
movq %rsp, %rdi
callq 0x111b6c
movsd 0x38(%rsp), %xmm0
ucomisd 0x125a24(%rip), %xmm0   # 0x236008
jne 0x110648
jp 0x110648
ucomisd 0x30(%rsp), %xmm0
jne 0x110648
jp 0x110648
ucomisd 0x28(%rsp), %xmm0
jne 0x110648
jp 0x110648
movapd 0x60(%rsp), %xmm2
movapd %xmm2, %xmm4
movapd 0x70(%rsp), %xmm1
unpcklpd %xmm1, %xmm4            # xmm4 = xmm4[0],xmm1[0]
movapd 0x80(%rsp), %xmm0
movapd %xmm0, %xmm3
unpcklpd %xmm0, %xmm3            # xmm3 = xmm3[0],xmm0[0]
subpd %xmm3, %xmm4
divpd %xmm3, %xmm4
mulpd 0x125a9f(%rip), %xmm4   # 0x2360d0
xorpd %xmm3, %xmm3
cmpltpd %xmm4, %xmm3
movmskpd %xmm3, %eax
testb $0x2, %al
jne 0x110656
xorpd %xmm3, %xmm3
jmp 0x11065e
leaq 0x1300b0(%rip), %rdi    # 0x2406ff
callq 0x10e520
jmp 0x110674
movapd %xmm4, %xmm3
unpckhpd %xmm4, %xmm3            # xmm3 = xmm3[1],xmm4[1]
testb $0x1, %al
jne 0x110666
xorpd %xmm4, %xmm4
leaq 0x12aead(%rip), %rdi    # 0x23b51a
movb $0x5, %al
callq 0x10e060
leaq 0x40(%rsp), %rdi
callq 0x10e5f8
addq $0xb08, %rsp            # imm = 0xB08
popq %rbx
popq %r14
retq
jmp 0x1106bb
jmp 0x11069b
jmp 0x1106ad
jmp 0x1106b2
jmp 0x1106bb
jmp 0x11069b
jmp 0x1106ad
jmp 0x1106b2
jmp 0x1106bb
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x111514
jmp 0x1106cb
movq %rax, %rbx
jmp 0x1106cb
movq %rax, %rbx
jmp 0x1106d3
jmp 0x1106bb
jmp 0x1106bb
movq %rax, %rbx
leaq 0x1e0(%rsp), %rdi
callq 0x111a32
movq %rsp, %rdi
callq 0x111b6c
leaq 0x40(%rsp), %rdi
callq 0x10e5f8
movq %rbx, %rdi
callq 0x10e340