// File: Altius[P]hotspot2/src/hotspot2_part1.cpp
// Function: BackgroundRegionManager::computeStats(int const&)
void BackgroundRegionManager::computeStats(const int& this_k)
{
  if (1 == m_sampledDataDistnSize)
    {
      // All observations within this region were of count == 0.
      m_distn[0].pmf = m_distn[0].pval = 1.;
      m_runningSum_count_duringPrevComputation = m_runningSum_count;
      m_runningSum_countSquared_duringPrevComputation = m_runningSum_countSquared;
      m_numPtsInNullRegion = m_distn[0].numOccs;
      m_numPtsInNullRegion_duringPrevComputation = m_numPtsInNullRegion;
      m_prev_k = 0;
      m_pmf = &nextProbPoisson;
      m_pmfParams.clear();
      m_pmfParams.push_back(0.);
      return;
    }

  int k;
  // Make *pmf() and params private member variables,
  // so they can be accessed elsewhere during debugging.
  long double prob0; // probability of observing 0 counts by random chance
  long double m; // mean
  long double v; // variance
  long double N(static_cast<long double>(m_numPtsInNullRegion));
  m = static_cast<long double>(m_runningSum_count) / N;
  v = (static_cast<long double>(m_runningSum_countSquared) - N * m * m) / (N - 1.);
  m_pmfParams.clear();
  static bool warningAlreadyIssued(false);

  // Set up the negative binomial model.
  // Double-check that m < v; if m >= v, which is extremely unlikely,
  // use a more appropriate model (binomial or Poisson).
  // Use the definitions of variance and mean to perform an integer (exact) test for m == v.
  if (m_numPtsInNullRegion * m_runningSum_countSquared - m_runningSum_count*m_runningSum_count == m_runningSum_count*(m_numPtsInNullRegion - 1))
    {
      // Poisson, m = v
      prob0 = exp(-m);
      m_pmfParams.push_back(m);
      m_pmf = &nextProbPoisson;
      if ((0 == m_runningSum_count || 1 == m_runningSum_count) && !warningAlreadyIssued)
        {
          cerr << "Warning:  In region " << *m_pCurChrom << ':' << m_posL << '-' << m_posR
               << ", all counts used for statistics were 0, or all were 0 except one was 1.\n"
               << "This generally should not happen.  If this region is unmappable or problematic for other reasons,\n"
               << "it would almost certainly be best to filter it out of the input.\n"
               << "There may be other such regions in the input; this warning will only be issued once during this run."
               << endl;
          warningAlreadyIssued = true;
        }
    }
  else
    {
      if (m < v)
        {
          // negative binomial
          long double r = m * m / (v - m);
          m_pmfParams.push_back(m);
          m_pmfParams.push_back(r);
          prob0 = pow(r / (r + m), r);
          m_pmf = &nextProbNegativeBinomial;
        }
      else // m > v (this is very unlikely)
        {
          // binomial
          long double n(floor(m * m / (m - v) + 0.5)); // estimate n of the fit from the observed mean and variance
          long double kk_max(static_cast<long double>(m_kcutoff)); // BUGBUG if m_kcutoff has 0 observations, do we still want to use it here??!?
          if (kk_max > n + 0.1) // + 0.1 to account for roundoff error, e.g. k=16.00001 and n=15.99999
            {
              // We don't expect this to happen, but if the estimated n is smaller than the observed m_kcutoff,
              // then we need to set n = m_kcutoff to allow m_kcutoff to be generated by the binomial model.
              n = kk_max;
            }
          // Now that we've set n, there's inconsistency among n, m, and v, with respect to the binomial.
          // We choose to keep m as observed, and update the variance parameter v so that consistency is achieved.
          v = m * (1. - m / n); // Now m*m/(m-v) = the integer n. Example: m=1.8952, v=1.6747, n=16.2893-->16, v-->1.6701.
          prob0 = pow(v / m, n);
          m_pmfParams.push_back(m);
          m_pmfParams.push_back(v);
          m_pmfParams.push_back(n);
          if (v > 1.0e-8)
            m_pmf = &nextProbBinomial;
          else
            {
              m_pmf = NULL;
              return;
            }
        }
    }

  // Now compute the minimum necessary number of pmf values, from the null model (e.g. negative binomial fit).

  // BUGBUG potential speed-up:  Allow the user to specify a minimum pmf,
  // such that no pmf values below it will be computed and
  // the P-values reported will asymptote at the P-value corresponding to that cutoff.
  // E.g., the user might specify a minimum pmf of numeric_limits<double>::epsilon().
  // If a P-value is, say, 1.23456e-218, do we really want to know that,
  // or are we content to know that it's something smaller than, say, 1e-40?

  long double curPMF(prob0);
  int k_begin(1), k_end(m_sampledDataDistnSize - 1); // default (-1 == this_k):  compute for all k observed in the background window
  const int MAlenOver2(m_MAlength / 2);
  if (-1 == this_k)
    m_distn[0].pmf = curPMF;
  else
    {
      k_end = this_k;
      if (-1 == m_prev_k) // compute for 0 <= k <= this_k.
        m_distn[0].pmf = curPMF;
      else // compute for (highest k previously handled) < k <= this_k.
        {
          curPMF = m_distn[m_prev_k].pmf;
          k_begin = m_prev_k + 1;
        }
    }
  for (k = k_begin; k <= k_end; k++)
    {
      curPMF = m_pmf(k, curPMF, m_pmfParams); // note:  if pmf == binomial and k > binomial's n, 0 is returned
      if (static_cast<int>(m_distn.size()) == k)
        {
          StatsForCount sc;
          sc.numOccs = 0;
          sc.pmf = sc.pval = -1.;
          sc.MAxN = -1; // don't compute moving averages until/unless we're sliding, for efficiency's sake
          m_distn.push_back(sc); // be sure not to increment m_sampledDataDistnSize...
          if (k >= m_MAlength)
            m_distn[k - MAlenOver2].MAxN = m_distn[k - MAlenOver2 - 1].MAxN - m_distn[k - m_MAlength].numOccs + m_distn[k].numOccs;
          else
            {
              if (m_MAlength - 1 == k)
                {
                  int sum(0);
                  for (int j = 0; j <= k; j++)
                    sum += m_distn[j].numOccs;
                  m_distn[MAlenOver2].MAxN = sum;
                }
            }
        }
      m_distn[k].pmf = curPMF;
    }

  // Because pmf(k) happens to be a multiple of pmf(k-1) for every k for each model (negative binomial, binomial, Poisson),
  // we can write the P-value for observing k counts as
  //
  // pval(k) = pmf(k) * (1 + term(k+1) + term(k+2) + term(k+3) + ...),
  //
  // where the terms in the sum decrease monotonically with k.
  // We can cap the sum at, say, 5 significant digits for pval(k),
  // and then work backwards, filling in pval(k-1) = pmf(k-1) + pval(k),
  // ending with pval(0) = 1.
  k--; // reset so that k corresponds to the last pmf computed
  int j = k;
  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(++j, 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();
  while (k > 1)
    {
      m_distn[k - 1].pval = m_distn[k - 1].pmf + m_distn[k].pval;
      //      if (m_distn[k].pval < numeric_limits<double>::min())
      //	m_distn[k].pval = numeric_limits<double>::min();
      k--;
    }
  m_distn[0].pval = 1.; // explicitly set it to 1, to avoid potential round-off error

  if (-1 != this_k)
    m_prev_k = this_k;
  else
    m_prev_k = m_sampledDataDistnSize - 1;

  m_runningSum_count_duringPrevComputation = m_runningSum_count;
  m_runningSum_countSquared_duringPrevComputation = m_runningSum_countSquared;
  m_numPtsInNullRegion_duringPrevComputation = m_numPtsInNullRegion;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x240, %rsp            # imm = 0x240
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x170(%rbp)
movl $0x1, %eax
cmpl 0x160(%rcx), %eax
jne 0x500e
movq -0x170(%rbp), %rdi
addq $0x50, %rdi
movq %rdi, -0x188(%rbp)
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x180(%rbp)
callq 0xa950
movq -0x188(%rbp), %rdi
movq -0x180(%rbp), %rsi
fld1
fld %st(0)
fstpt -0x194(%rbp)
fstpt 0x20(%rax)
callq 0xa950
fldt -0x194(%rbp)
movq -0x188(%rbp), %rdi
movq -0x180(%rbp), %rsi
movq %rax, %rcx
movq -0x170(%rbp), %rax
fstpt 0x10(%rcx)
movq 0x10(%rax), %rcx
movq %rcx, 0x28(%rax)
movq 0x18(%rax), %rcx
movq %rcx, 0x30(%rax)
callq 0xa950
movq -0x170(%rbp), %rdi
movl (%rax), %eax
movl %eax, 0x20(%rdi)
movl 0x20(%rdi), %eax
movl %eax, 0x38(%rdi)
movl $0x0, 0x154(%rdi)
leaq -0x144a(%rip), %rax     # 0x3b90
movq %rax, 0x168(%rdi)
addq $0x170, %rdi            # imm = 0x170
movq %rdi, -0x178(%rbp)
callq 0xab50
movq -0x178(%rbp), %rdi
fldz
fstpt -0x20(%rbp)
leaq -0x20(%rbp), %rsi
callq 0xab70
jmp 0x5861
movq -0x170(%rbp), %rdi
movl 0x20(%rdi), %eax
movl %eax, -0x164(%rbp)
fildl -0x164(%rbp)
fstpt -0x70(%rbp)
movq 0x10(%rdi), %rax
movq %rax, -0x160(%rbp)
fildll -0x160(%rbp)
fldt -0x70(%rbp)
fdivrp %st, %st(1)
fstpt -0x50(%rbp)
movq 0x18(%rdi), %rax
movq %rax, -0x158(%rbp)
fildll -0x158(%rbp)
fldt -0x70(%rbp)
fldt -0x50(%rbp)
fld %st(1)
fmul %st(1), %st
fmulp %st, %st(1)
fsubrp %st, %st(2)
fld1
fchs
faddp %st, %st(1)
fdivrp %st, %st(1)
fstpt -0x60(%rbp)
addq $0x170, %rdi            # imm = 0x170
callq 0xab50
movq -0x170(%rbp), %rdx
movslq 0x20(%rdx), %rax
imulq 0x18(%rdx), %rax
movq 0x10(%rdx), %rcx
imulq 0x10(%rdx), %rcx
subq %rcx, %rax
movq 0x10(%rdx), %rcx
movl 0x20(%rdx), %edx
subl $0x1, %edx
movslq %edx, %rdx
imulq %rdx, %rcx
cmpq %rcx, %rax
jne 0x51d2
fldt -0x50(%rbp)
fchs
movq %rsp, %rax
fstpt (%rax)
callq 0xaba0
movq -0x170(%rbp), %rdi
fstpt -0x40(%rbp)
addq $0x170, %rdi            # imm = 0x170
leaq -0x50(%rbp), %rsi
callq 0xabd0
movq -0x170(%rbp), %rcx
leaq -0x1553(%rip), %rax     # 0x3b90
movq %rax, 0x168(%rcx)
xorl %eax, %eax
cmpq 0x10(%rcx), %rax
je 0x5108
movq -0x170(%rbp), %rcx
movl $0x1, %eax
cmpq 0x10(%rcx), %rax
jne 0x51cd
testb $0x1, 0x161d9(%rip)     # 0x1b2e8
jne 0x51cd
movq 0x15ed4(%rip), %rdi     # 0x1aff0
leaq 0xe2fe(%rip), %rsi      # 0x13421
callq 0x3240
movq %rax, %rdi
movq -0x170(%rbp), %rax
movq 0x188(%rax), %rsi
callq 0x3230
movq %rax, %rdi
movl $0x3a, %esi
callq 0x3310
movq %rax, %rdi
movq -0x170(%rbp), %rax
movl (%rax), %esi
callq 0x3420
movq %rax, %rdi
movl $0x2d, %esi
callq 0x3310
movq %rax, %rdi
movq -0x170(%rbp), %rax
movl 0x4(%rax), %esi
callq 0x3420
movq %rax, %rdi
leaq 0xe2b1(%rip), %rsi      # 0x13436
callq 0x3240
movq %rax, %rdi
leaq 0xe2ec(%rip), %rsi      # 0x13480
callq 0x3240
movq %rax, %rdi
leaq 0xe340(%rip), %rsi      # 0x134e3
callq 0x3240
movq %rax, %rdi
leaq 0xe373(%rip), %rsi      # 0x13525
callq 0x3240
movq %rax, %rdi
movq 0x15de7(%rip), %rsi     # 0x1afa8
callq 0x3280
movb $0x1, 0x1611b(%rip)     # 0x1b2e8
jmp 0x537c
fldt -0x50(%rbp)
fldt -0x60(%rbp)
fucompi %st(1), %st
fstp %st(0)
jbe 0x5255
jmp 0x51e0
movq -0x170(%rbp), %rdi
fldt -0x50(%rbp)
fld %st(0)
fmul %st(1), %st
fldt -0x60(%rbp)
fsubp %st, %st(2)
fdivp %st, %st(1)
fstpt -0x80(%rbp)
addq $0x170, %rdi            # imm = 0x170
movq %rdi, -0x1a0(%rbp)
leaq -0x50(%rbp), %rsi
callq 0xabd0
movq -0x1a0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0xabd0
fldt -0x80(%rbp)
fldt -0x50(%rbp)
fadd %st(1), %st
fdivr %st(1), %st
movq %rsp, %rax
fxch %st(1)
fstpt 0x10(%rax)
fstpt (%rax)
callq 0xac40
movq -0x170(%rbp), %rax
fstpt -0x40(%rbp)
leaq -0x1a09(%rip), %rcx     # 0x3840
movq %rcx, 0x168(%rax)
jmp 0x537a
fldt -0x50(%rbp)
fld %st(0)
fmul %st(1), %st
fldt -0x60(%rbp)
fsubrp %st, %st(2)
fdivp %st, %st(1)
flds 0xdd9b(%rip)            # 0x13004
faddp %st, %st(1)
movq %rsp, %rax
fstpt (%rax)
callq 0xa410
movq -0x170(%rbp), %rax
fstpt -0x90(%rbp)
movl 0x110(%rax), %eax
movl %eax, -0x168(%rbp)
fildl -0x168(%rbp)
fstpt -0xa0(%rbp)
fldt -0xa0(%rbp)
fldt -0x90(%rbp)
fldl 0xdd74(%rip)            # 0x13020
faddp %st, %st(1)
fxch %st(1)
fucompi %st(1), %st
fstp %st(0)
jbe 0x52c4
jmp 0x52b8
fldt -0xa0(%rbp)
fstpt -0x90(%rbp)
fldt -0x50(%rbp)
fldt -0x90(%rbp)
fdivr %st(1), %st
fld1
fsubp %st, %st(1)
fmulp %st, %st(1)
fstpt -0x60(%rbp)
fldt -0x60(%rbp)
fldt -0x50(%rbp)
fdivrp %st, %st(1)
fldt -0x90(%rbp)
movq %rsp, %rax
fstpt 0x10(%rax)
fstpt (%rax)
callq 0xac40
movq -0x170(%rbp), %rdi
fstpt -0x40(%rbp)
addq $0x170, %rdi            # imm = 0x170
movq %rdi, -0x1a8(%rbp)
leaq -0x50(%rbp), %rsi
callq 0xabd0
movq -0x1a8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0xabd0
movq -0x1a8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0xabd0
fldt -0x60(%rbp)
fldl 0xdcd0(%rip)            # 0x13010
fxch %st(1)
fucompi %st(1), %st
fstp %st(0)
jbe 0x5361
jmp 0x534a
movq -0x170(%rbp), %rax
leaq -0x1968(%rip), %rcx     # 0x39f0
movq %rcx, 0x168(%rax)
jmp 0x5378
movq -0x170(%rbp), %rax
movq $0x0, 0x168(%rax)
jmp 0x5861
jmp 0x537a
jmp 0x537c
movq -0x170(%rbp), %rax
fldt -0x40(%rbp)
fstpt -0xb0(%rbp)
movl $0x1, -0xb4(%rbp)
movl 0x160(%rax), %ecx
subl $0x1, %ecx
movl %ecx, -0xb8(%rbp)
movl 0x3c(%rax), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0xbc(%rbp)
movq -0x10(%rbp), %rcx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl (%rcx), %eax
jne 0x53f1
movq -0x170(%rbp), %rdi
fldt -0xb0(%rbp)
fstpt -0x1b4(%rbp)
addq $0x50, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xa950
fldt -0x1b4(%rbp)
fstpt 0x10(%rax)
jmp 0x547a
movq -0x170(%rbp), %rcx
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xb8(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl 0x154(%rcx), %eax
jne 0x543c
movq -0x170(%rbp), %rdi
fldt -0xb0(%rbp)
fstpt -0x1c0(%rbp)
addq $0x50, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xa950
fldt -0x1c0(%rbp)
fstpt 0x10(%rax)
jmp 0x5478
movq -0x170(%rbp), %rax
movq %rax, %rdi
addq $0x50, %rdi
movslq 0x154(%rax), %rsi
callq 0xa950
movq %rax, %rcx
movq -0x170(%rbp), %rax
fldt 0x10(%rcx)
fstpt -0xb0(%rbp)
movl 0x154(%rax), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x547a
movl -0xb4(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0xb8(%rbp), %eax
jg 0x5699
movq -0x170(%rbp), %rdx
movq 0x168(%rdx), %rax
addq $0x170, %rdx            # imm = 0x170
leaq -0x24(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq *%rax
movq -0x170(%rbp), %rdi
fstpt -0xb0(%rbp)
addq $0x50, %rdi
callq 0xa930
cmpl -0x24(%rbp), %eax
jne 0x5662
movq -0x170(%rbp), %rdi
movl $0x0, -0x100(%rbp)
fld1
fchs
fld %st(0)
fstpt -0xe0(%rbp)
fstpt -0xf0(%rbp)
movl $0xffffffff, -0xd0(%rbp) # imm = 0xFFFFFFFF
addq $0x50, %rdi
leaq -0x100(%rbp), %rsi
callq 0xa970
movq -0x170(%rbp), %rcx
movl -0x24(%rbp), %eax
cmpl 0x3c(%rcx), %eax
jl 0x55c7
movq -0x170(%rbp), %rdi
addq $0x50, %rdi
movl -0x24(%rbp), %eax
subl -0xbc(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0xa950
movq -0x170(%rbp), %rcx
movl 0x30(%rax), %eax
movl %eax, -0x1cc(%rbp)
movq %rcx, %rdi
addq $0x50, %rdi
movl -0x24(%rbp), %eax
subl 0x3c(%rcx), %eax
movslq %eax, %rsi
callq 0xa950
movq -0x170(%rbp), %rdi
movq %rax, %rcx
movl -0x1cc(%rbp), %eax
subl (%rcx), %eax
movl %eax, -0x1c8(%rbp)
addq $0x50, %rdi
movslq -0x24(%rbp), %rsi
callq 0xa950
movq -0x170(%rbp), %rdi
movq %rax, %rcx
movl -0x1c8(%rbp), %eax
addl (%rcx), %eax
movl %eax, -0x1c4(%rbp)
addq $0x50, %rdi
movl -0x24(%rbp), %eax
subl -0xbc(%rbp), %eax
movslq %eax, %rsi
callq 0xa950
movl -0x1c4(%rbp), %ecx
movl %ecx, 0x30(%rax)
jmp 0x5660
movq -0x170(%rbp), %rax
movl 0x3c(%rax), %eax
subl $0x1, %eax
cmpl -0x24(%rbp), %eax
jne 0x565e
movl $0x0, -0x104(%rbp)
movl $0x0, -0x108(%rbp)
movl -0x108(%rbp), %eax
cmpl -0x24(%rbp), %eax
jg 0x5632
movq -0x170(%rbp), %rdi
addq $0x50, %rdi
movslq -0x108(%rbp), %rsi
callq 0xa950
movl (%rax), %eax
addl -0x104(%rbp), %eax
movl %eax, -0x104(%rbp)
movl -0x108(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x108(%rbp)
jmp 0x55f1
movq -0x170(%rbp), %rdi
movl -0x104(%rbp), %eax
movl %eax, -0x1d0(%rbp)
addq $0x50, %rdi
movslq -0xbc(%rbp), %rsi
callq 0xa950
movl -0x1d0(%rbp), %ecx
movl %ecx, 0x30(%rax)
jmp 0x5660
jmp 0x5662
movq -0x170(%rbp), %rdi
fldt -0xb0(%rbp)
fstpt -0x1dc(%rbp)
addq $0x50, %rdi
movslq -0x24(%rbp), %rsi
callq 0xa950
fldt -0x1dc(%rbp)
fstpt 0x10(%rax)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x5483
movl -0x24(%rbp), %eax
decl %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x10c(%rbp)
fld1
fld %st(0)
fstpt -0x120(%rbp)
fstpt -0x130(%rbp)
fldl 0xd968(%rip)            # 0x13028
fstpt -0x150(%rbp)
movq -0x170(%rbp), %rdx
movq 0x168(%rdx), %rax
movl -0x10c(%rbp), %ecx
incl %ecx
movl %ecx, -0x10c(%rbp)
addq $0x170, %rdx            # imm = 0x170
leaq -0x10c(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq *%rax
fld %st(0)
fstp %st(0)
fld %st(0)
fstpt -0x140(%rbp)
fldl 0xd91d(%rip)            # 0x13028
fxch %st(1)
fucompi %st(1), %st
fstp %st(0)
jbe 0x5737
jmp 0x5715
fldt -0x140(%rbp)
fldt -0x120(%rbp)
faddp %st, %st(1)
fstpt -0x120(%rbp)
fldt -0x140(%rbp)
fstpt -0x130(%rbp)
jmp 0x56c6
movq -0x170(%rbp), %rdi
addq $0x50, %rdi
movq %rdi, -0x1f0(%rbp)
movslq -0x24(%rbp), %rsi
callq 0xa950
movq -0x1f0(%rbp), %rdi
fldt 0x10(%rax)
fldt -0x120(%rbp)
fmulp %st, %st(1)
fstpt -0x1e8(%rbp)
movslq -0x24(%rbp), %rsi
callq 0xa950
fldt -0x1e8(%rbp)
fstpt 0x20(%rax)
cmpl $0x1, -0x24(%rbp)
jle 0x57f3
movq -0x170(%rbp), %rdi
addq $0x50, %rdi
movq %rdi, -0x208(%rbp)
movl -0x24(%rbp), %eax
decl %eax
movslq %eax, %rsi
callq 0xa950
movq -0x208(%rbp), %rdi
fldt 0x10(%rax)
fstpt -0x214(%rbp)
movslq -0x24(%rbp), %rsi
callq 0xa950
fldt -0x214(%rbp)
movq -0x208(%rbp), %rdi
fldt 0x20(%rax)
faddp %st, %st(1)
fstpt -0x1fc(%rbp)
movl -0x24(%rbp), %eax
decl %eax
movslq %eax, %rsi
callq 0xa950
fldt -0x1fc(%rbp)
fstpt 0x20(%rax)
movl -0x24(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x577c
movq -0x170(%rbp), %rdi
addq $0x50, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xa950
fld1
fstpt 0x20(%rax)
movq -0x10(%rbp), %rcx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl (%rcx), %eax
je 0x582e
movq -0x170(%rbp), %rax
movq -0x10(%rbp), %rcx
movl (%rcx), %ecx
movl %ecx, 0x154(%rax)
jmp 0x5844
movq -0x170(%rbp), %rax
movl 0x160(%rax), %ecx
subl $0x1, %ecx
movl %ecx, 0x154(%rax)
movq -0x170(%rbp), %rax
movq 0x10(%rax), %rcx
movq %rcx, 0x28(%rax)
movq 0x18(%rax), %rcx
movq %rcx, 0x30(%rax)
movl 0x20(%rax), %ecx
movl %ecx, 0x38(%rax)
addq $0x240, %rsp            # imm = 0x240
popq %rbp
retq
nopw (%rax,%rax)