// File: /workspace/github_cpp_makefile_star2_O3/Altius[P]hotspot2/src/hotspot2_part1.cpp
// Function: BackgroundRegionManager::getPvalue(unsigned int const&)
long double BackgroundRegionManager::getPvalue(const unsigned int& k)
{
  if (k < m_distn.size()) // Yes, m_distn.size(), not m_sampledDataDistnSize
    return m_distn[k].pval;

  // k is greater than all count values in the distribution, so we need to add bin(s) for it.
  // This can only happen if the user has specified a sampling interval
  // and k happens to have not been sampled.

  if (NULL == m_pmf || m_pmfParams.empty())
    {
      cerr << "Coding error:  BRM::getPvalue(" << k << ") was called when m_pmf == NULL and/or m_pmfParams.empty() == true." << endl;
      exit(1);
    }

  StatsForCount sc;
  sc.numOccs = 0;
  sc.pmf = sc.pval = -1.;
  sc.MAxN = -1;

  const int prev_max_k(static_cast<int>(m_distn.size()) - 1), MAlenOver2(m_MAlength / 2); // Yes, m_distn.size(), not m_sampledDataDistnSize.
  int kk = prev_max_k;
  long double curPMF(m_distn[kk].pmf);
  while (k >= m_distn.size()) // Yes, k, not kk.  We're growing the vector until k fits into its highest bin.
    {
      curPMF = m_pmf(++kk, curPMF, m_pmfParams);
      sc.pmf = curPMF;
      m_distn.push_back(sc);
      if (kk >= m_MAlength)
        m_distn[kk - MAlenOver2].MAxN = m_distn[kk - MAlenOver2 - 1].MAxN - m_distn[kk - m_MAlength].numOccs + m_distn[kk].numOccs;
      else
        {
          if (m_MAlength - 1 == kk)
            {
              int sum(0);
              for (int j = 0; j <= kk; j++)
                sum += m_distn[j].numOccs;
              m_distn[MAlenOver2].MAxN = sum;
            }
        }
    }
  // Compute the P-value.  See comments in method computeStats() for further info.
  // kk == k at this point.
  long double sum(1.), prevTerm(1.), curTerm;
  const long double SMALL_VALUE(5.0e-7); // restrict the correctness of the final P-value to ~5 significant digits
  while ((curTerm = m_pmf(++kk, prevTerm, m_pmfParams)) > SMALL_VALUE)
    {
      sum += curTerm;
      prevTerm = curTerm;
    }
  m_distn[k].pval = m_distn[k].pmf * sum;
  //  if (m_distn[k].pval < numeric_limits<double>::min())
  //    m_distn[k].pval = numeric_limits<double>::min();
  // Fill in P-values for any bins that were added between prev_max_k and k.
  kk = k;
  while (kk > prev_max_k + 1)
    {
      m_distn[kk - 1].pval = m_distn[kk - 1].pmf + m_distn[kk].pval;
      //      if (m_distn[k].pval < numeric_limits<double>::min())
      //	m_distn[k].pval = numeric_limits<double>::min();
      kk--;
    }

  return m_distn[k].pval;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rsi, %rbx
movl (%rsi), %ecx
movq 0x50(%rdi), %rax
movq 0x58(%rdi), %rdx
subq %rax, %rdx
movq %rdx, %rsi
sarq $0x6, %rsi
cmpq %rcx, %rsi
jbe 0x3e3a
shlq $0x6, %rcx
fldt 0x20(%rax,%rcx)
jmp 0x40a1
movq %rdi, %r14
cmpq $0x0, 0x168(%rdi)
je 0x40b3
movq 0x170(%r14), %rcx
cmpq 0x178(%r14), %rcx
je 0x40b3
movq %rdx, 0x28(%rsp)
leaq 0x50(%r14), %rcx
movq %rcx, 0x8(%rsp)
leaq 0x170(%r14), %r12
leaq 0x60(%rsp), %rcx
movl $0x0, (%rcx)
fld1
fchs
fld %st(0)
fstpt 0x80(%rsp)
fstpt 0x70(%rsp)
movl $0xffffffff, 0x30(%rcx) # imm = 0xFFFFFFFF
movq %rsi, 0x30(%rsp)
movslq %esi, %rcx
movq %rcx, %rdx
shlq $0x6, %rdx
decl %ecx
movl 0x3c(%r14), %esi
movl %esi, %r15d
shrl $0x1f, %r15d
addl %esi, %r15d
sarl %r15d
leaq 0x4(%rsp), %rsi
movl %ecx, (%rsi)
fldt -0x30(%rdx,%rax)
fstpt 0x50(%rsp)
movl %r15d, %ebp
notl %ebp
leaq 0x50(%rsp), %r13
fldz
fstp %st(0)
movq 0x168(%r14), %rax
incl 0x4(%rsp)
leaq 0x4(%rsp), %rdi
movq %r13, %rsi
movq %r12, %rdx
callq *%rax
fld %st(0)
fstpt 0x50(%rsp)
fstpt 0x70(%rsp)
movq 0x58(%r14), %rsi
cmpq 0x60(%r14), %rsi
je 0x3f32
movaps 0x60(%rsp), %xmm0
movaps 0x70(%rsp), %xmm1
movaps 0x80(%rsp), %xmm2
movaps 0x90(%rsp), %xmm3
movaps %xmm3, 0x30(%rsi)
movaps %xmm2, 0x20(%rsi)
movaps %xmm1, 0x10(%rsi)
movaps %xmm0, (%rsi)
addq $0x40, 0x58(%r14)
jmp 0x3f41
movq 0x8(%rsp), %rdi
leaq 0x60(%rsp), %rdx
callq 0x7e82
movl 0x4(%rsp), %ecx
movl 0x3c(%r14), %edx
movl %ecx, %esi
movq 0x50(%r14), %rax
subl %edx, %esi
fld1
jge 0x3f79
decl %edx
cmpl %ecx, %edx
jne 0x3fb0
testl %ecx, %ecx
js 0x3fa0
shlq $0x6, %rcx
addq $0x40, %rcx
xorl %esi, %esi
xorl %edx, %edx
addl (%rax,%rsi), %edx
addq $0x40, %rsi
cmpq %rsi, %rcx
jne 0x3f6b
jmp 0x3fa2
movslq %ecx, %rdi
leal (%rcx,%rbp), %edx
movslq %edx, %rdx
shlq $0x6, %rdx
movl 0x30(%rax,%rdx), %edx
movslq %esi, %rsi
shlq $0x6, %rsi
subl (%rax,%rsi), %edx
shlq $0x6, %rdi
addl (%rax,%rdi), %edx
subl %r15d, %ecx
jmp 0x3fa5
xorl %edx, %edx
movl %r15d, %ecx
movslq %ecx, %rcx
shlq $0x6, %rcx
movl %edx, 0x30(%rax,%rcx)
movl (%rbx), %ecx
movq 0x58(%r14), %rdx
subq %rax, %rdx
sarq $0x6, %rdx
cmpq %rcx, %rdx
jbe 0x3ed4
movq 0x168(%r14), %rax
leaq 0x4(%rsp), %rdi
incl (%rdi)
fstpt 0x10(%rsp)
leaq 0x10(%rsp), %rsi
movq %r12, %rdx
callq *%rax
fld1
fldl 0x503e(%rip)            # 0x9028
fxch %st(2)
fucomi %st(2), %st
jbe 0x4042
fstp %st(1)
fld1
leaq 0x4(%rsp), %r13
leaq 0x10(%rsp), %rbp
fxch %st(2)
fstpt 0x38(%rsp)
fldz
fxch %st(2)
fxch %st(1)
fstp %st(2)
fadd %st(1), %st
fstpt 0x44(%rsp)
fstpt 0x10(%rsp)
movq 0x168(%r14), %rax
incl 0x4(%rsp)
movq %r13, %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq *%rax
fldt 0x38(%rsp)
fldt 0x44(%rsp)
fxch %st(2)
fucomi %st(1), %st
fstp %st(1)
fldz
fxch %st(2)
fxch %st(1)
ja 0x400a
fstp %st(0)
fstp %st(1)
movslq (%rbx), %rax
movl %eax, %ecx
movq 0x8(%rsp), %rdx
movq (%rdx), %rsi
shlq $0x6, %rcx
fldt 0x10(%rsi,%rcx)
fmulp %st, %st(1)
fld %st(0)
fstpt 0x20(%rsi,%rcx)
cmpl 0x30(%rsp), %eax
jle 0x40a1
fstp %st(0)
addq %rsi, %rcx
movq 0x28(%rsp), %rdx
shrq $0x6, %rdx
movslq %edx, %rdx
movq %rax, %rdi
shlq $0x6, %rdi
addq %rdi, %rsi
addq $-0x30, %rsi
decq %rax
fldt (%rsi)
fldt 0x50(%rsi)
faddp %st, %st(1)
fstpt 0x10(%rsi)
addq $-0x40, %rsi
cmpq %rdx, %rax
jg 0x4088
fldt 0x20(%rcx)
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8f36(%rip), %rdi      # 0xcff0
leaq 0x554d(%rip), %rsi      # 0x960e
callq 0x2210
movl (%rbx), %esi
movq %rax, %rdi
callq 0x22d0
leaq 0x5556(%rip), %rsi      # 0x962d
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x20e0
movl $0x1, %edi
callq 0x22c0
nop