// File: ArashPartow[P]exprtk-extras/exprtk_bsm_benchmark.cpp
// Function: double bsm_model<double>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, double, double, double, double, double)
inline T bsm_model(const std::string& callput_flag, const T s, const T k, const T t, const T r, const T v)
{
   using namespace std;
   using namespace exprtk::details::numeric;

   const T d1 = (log(s / k) + (r + (v * v) / 2) * t) / (v * sqrt(t));
   const T d2 = d1 - v * sqrt(t);

   if (callput_flag == "call")
      return s * ncdf(d1) - k * exp(-r * t) * ncdf(d2);
   else if (callput_flag == "put")
      return k * exp(-r * t) * ncdf(-d2) - s * ncdf(-d1);
   else
      return T(0);
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0x98(%rsp)
movsd %xmm0, 0x90(%rsp)
movsd %xmm1, 0x88(%rsp)
movsd %xmm2, 0x80(%rsp)
movsd %xmm3, 0x78(%rsp)
movsd %xmm4, 0x70(%rsp)
movsd 0x90(%rsp), %xmm0
divsd 0x88(%rsp), %xmm0
callq 0x111160
movaps %xmm0, %xmm1
movsd 0x78(%rsp), %xmm0
movsd 0x70(%rsp), %xmm2
mulsd 0x70(%rsp), %xmm2
movsd 0x85e(%rip), %xmm3      # 0x447018
divsd %xmm3, %xmm2
addsd %xmm2, %xmm0
movsd 0x80(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0x80(%rsp), %xmm0
callq 0x111370
movsd 0x40(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x48(%rsp), %xmm0
mulsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x68(%rsp)
movsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x80(%rsp), %xmm0
callq 0x111370
movsd 0x50(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x58(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rsp)
movq 0x98(%rsp), %rdi
leaq 0x9ef5(%rip), %rsi      # 0x45076e
callq 0x446a70
testb $0x1, %al
jne 0x446887
jmp 0x446945
movsd 0x90(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x68(%rsp), %xmm0
callq 0x1265e0
movsd %xmm0, 0x30(%rsp)
movsd 0x88(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x78(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd 0x80(%rsp), %xmm0
callq 0x111130
movaps %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x60(%rsp), %xmm0
callq 0x1265e0
movsd 0x28(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
movaps %xmm0, %xmm3
movsd 0x38(%rsp), %xmm0
mulsd %xmm3, %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0xa0(%rsp)
jmp 0x446a55
movq 0x98(%rsp), %rdi
leaq 0x63d5(%rip), %rsi      # 0x44cd29
callq 0x446a70
testb $0x1, %al
jne 0x446962
jmp 0x446a49
movsd 0x88(%rsp), %xmm0
movsd %xmm0, (%rsp)
movsd 0x78(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd 0x80(%rsp), %xmm0
callq 0x111130
movaps %xmm0, %xmm1
movsd (%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x60(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
callq 0x1265e0
movsd %xmm0, 0x10(%rsp)
movsd 0x90(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x68(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
callq 0x1265e0
movsd 0x8(%rsp), %xmm1
movsd 0x10(%rsp), %xmm2
movaps %xmm0, %xmm3
movsd 0x18(%rsp), %xmm0
mulsd %xmm3, %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0xa0(%rsp)
jmp 0x446a55
xorps %xmm0, %xmm0
movsd %xmm0, 0xa0(%rsp)
movsd 0xa0(%rsp), %xmm0
addq $0xa8, %rsp
retq
nopw %cs:(%rax,%rax)