// File: /workspace/github_cpp_makefile_star2_O1/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 0x3e6c
shlq $0x6, %rcx
fldt 0x20(%rax,%rcx)
jmp 0x40f7
movq %rdi, %r14
cmpq $0x0, 0x168(%rdi)
je 0x4109
movq 0x170(%r14), %rcx
cmpq 0x178(%r14), %rcx
je 0x4109
movq %rdx, 0x30(%rsp)
leaq 0x50(%r14), %r15
leaq 0x170(%r14), %r12
movl $0x0, 0x60(%rsp)
fld1
fld %st(0)
fchs
fld %st(0)
fstpt 0x80(%rsp)
fstpt 0x70(%rsp)
movl $0xffffffff, 0x90(%rsp) # imm = 0xFFFFFFFF
movq %rsi, 0x38(%rsp)
movslq %esi, %rdx
movq %rdx, %rsi
shlq $0x6, %rsi
decl %edx
movl 0x3c(%r14), %ecx
movl %edx, 0xc(%rsp)
fldt -0x30(%rsi,%rax)
fstpt 0x50(%rsp)
movl (%rbx), %eax
movq 0x58(%r14), %rdx
subq 0x50(%r14), %rdx
sarq $0x6, %rdx
cmpq %rax, %rdx
ja 0x401e
fstp %st(0)
movl %ecx, %r13d
shrl $0x1f, %r13d
addl %ecx, %r13d
sarl %r13d
movl %r13d, %ebp
notl %ebp
movslq %r13d, %rax
shlq $0x6, %rax
movq %rax, 0x10(%rsp)
fldz
fstp %st(0)
movq 0x168(%r14), %rax
incl 0xc(%rsp)
leaq 0xc(%rsp), %rdi
leaq 0x50(%rsp), %rsi
movq %r12, %rdx
callq *%rax
fld %st(0)
fstpt 0x50(%rsp)
fstpt 0x70(%rsp)
movq 0x58(%r14), %rsi
cmpq 0x60(%r14), %rsi
je 0x3f81
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 0x3f8e
movq %r15, %rdi
leaq 0x60(%rsp), %rdx
callq 0x7b3e
movl 0xc(%rsp), %eax
movl 0x3c(%r14), %edx
movl %eax, %ecx
subl %edx, %ecx
fld1
jge 0x3fc5
decl %edx
cmpl %eax, %edx
jne 0x4007
testl %eax, %eax
js 0x3ff9
movq (%r15), %rcx
shlq $0x6, %rax
addq $0x40, %rax
xorl %esi, %esi
xorl %edx, %edx
addl (%rcx,%rsi), %edx
addq $0x40, %rsi
cmpq %rsi, %rax
jne 0x3fb7
jmp 0x3ffb
leal (%rax,%rbp), %edx
movslq %edx, %rdx
movq (%r15), %rsi
shlq $0x6, %rdx
movl 0x30(%rsi,%rdx), %edx
movslq %ecx, %rcx
shlq $0x6, %rcx
subl (%rsi,%rcx), %edx
movslq %eax, %rcx
shlq $0x6, %rcx
addl (%rsi,%rcx), %edx
subl %r13d, %eax
cltq
shlq $0x6, %rax
movl %edx, 0x30(%rsi,%rax)
jmp 0x4007
xorl %edx, %edx
movq (%r15), %rax
movq 0x10(%rsp), %rcx
movl %edx, 0x30(%rax,%rcx)
movl (%rbx), %eax
movq 0x58(%r14), %rcx
subq 0x50(%r14), %rcx
sarq $0x6, %rcx
cmpq %rax, %rcx
jbe 0x3f21
fstpt 0x20(%rsp)
movq 0x168(%r14), %rax
leaq 0xc(%rsp), %rdi
incl (%rdi)
leaq 0x20(%rsp), %rsi
movq %r12, %rdx
callq *%rax
fld1
fldl 0x4fe6(%rip)            # 0x9028
fxch %st(2)
fucomi %st(2), %st
jbe 0x409a
fstp %st(1)
fld1
leaq 0xc(%rsp), %r13
leaq 0x20(%rsp), %rbp
fxch %st(2)
fstpt 0x44(%rsp)
fldz
fxch %st(2)
fxch %st(1)
fstp %st(2)
fadd %st(1), %st
fstpt 0x10(%rsp)
fstpt 0x20(%rsp)
movq 0x168(%r14), %rax
incl 0xc(%rsp)
movq %r13, %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq *%rax
fldt 0x44(%rsp)
fldt 0x10(%rsp)
fxch %st(2)
fucomi %st(1), %st
fstp %st(1)
fldz
fxch %st(2)
fxch %st(1)
ja 0x4062
fstp %st(0)
fstp %st(1)
movl (%rbx), %eax
movq (%r15), %rsi
movq %rax, %rdx
shlq $0x6, %rdx
leaq (%rsi,%rdx), %rcx
fldt 0x10(%rsi,%rdx)
fmulp %st, %st(1)
fstpt 0x20(%rsi,%rdx)
cmpl 0x38(%rsp), %eax
jle 0x40f0
cltq
movq 0x30(%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 0x40da
movl %eax, 0xc(%rsp)
fldt 0x20(%rcx)
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8ee0(%rip), %rdi      # 0xcff0
leaq 0x54c7(%rip), %rsi      # 0x95de
callq 0x2210
movl (%rbx), %esi
movq %rax, %rdi
callq 0x22d0
leaq 0x54d0(%rip), %rsi      # 0x95fd
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x20e0
movl $0x1, %edi
callq 0x22c0
nop