// File: /workspace/github_cpp_makefile_star2_O2/redpony[P]libpopt/./lbfgs.h
// Function: scitbx::lbfgs::detail::mcsrch<double, unsigned long>::mcstep(double&, double&, double&, double&, double&, double&, double&, double, double, bool&, double, double)
int mcsrch<FloatType, SizeType>::mcstep(
      FloatType& stx,
      FloatType& fx,
      FloatType& dx,
      FloatType& sty,
      FloatType& fy,
      FloatType& dy,
      FloatType& stp,
      FloatType fp,
      FloatType dp,
      bool& brackt,
      FloatType stpmin,
      FloatType stpmax)
    {
      bool bound;
      FloatType gamma, p, q, r, s, sgnd, stpc, stpf, stpq, theta;
      int info = 0;
      if (   (   brackt && (stp <= std::min(stx, sty)
              || stp >= std::max(stx, sty)))
          || dx * (stp - stx) >= FloatType(0) || stpmax < stpmin) {
        return 0;
      }
      // Determine if the derivatives have opposite sign.
      sgnd = dp * (dx / abs(dx));
      if (fp > fx) {
        // First case. A higher function value.
        // The minimum is bracketed. If the cubic step is closer
        // to stx than the quadratic step, the cubic step is taken,
        // else the average of the cubic and quadratic steps is taken.
        info = 1;
        bound = true;
        theta = FloatType(3) * (fx - fp) / (stp - stx) + dx + dp;
        s = max3(abs(theta), abs(dx), abs(dp));
        gamma = s * std::sqrt(pow2(theta / s) - (dx / s) * (dp / s));
        if (stp < stx) gamma = - gamma;
        p = (gamma - dx) + theta;
        q = ((gamma - dx) + gamma) + dp;
        r = p/q;
        stpc = stx + r * (stp - stx);
        stpq = stx
          + ((dx / ((fx - fp) / (stp - stx) + dx)) / FloatType(2))
            * (stp - stx);
        if (abs(stpc - stx) < abs(stpq - stx)) {
          stpf = stpc;
        }
        else {
          stpf = stpc + (stpq - stpc) / FloatType(2);
        }
        brackt = true;
      }
      else if (sgnd < FloatType(0)) {
        // Second case. A lower function value and derivatives of
        // opposite sign. The minimum is bracketed. If the cubic
        // step is closer to stx than the quadratic (secant) step,
        // the cubic step is taken, else the quadratic step is taken.
        info = 2;
        bound = false;
        theta = FloatType(3) * (fx - fp) / (stp - stx) + dx + dp;
        s = max3(abs(theta), abs(dx), abs(dp));
        gamma = s * std::sqrt(pow2(theta / s) - (dx / s) * (dp / s));
        if (stp > stx) gamma = - gamma;
        p = (gamma - dp) + theta;
        q = ((gamma - dp) + gamma) + dx;
        r = p/q;
        stpc = stp + r * (stx - stp);
        stpq = stp + (dp / (dp - dx)) * (stx - stp);
        if (abs(stpc - stp) > abs(stpq - stp)) {
          stpf = stpc;
        }
        else {
          stpf = stpq;
        }
        brackt = true;
      }
      else if (abs(dp) < abs(dx)) {
        // Third case. A lower function value, derivatives of the
        // same sign, and the magnitude of the derivative decreases.
        // The cubic step is only used if the cubic tends to infinity
        // in the direction of the step or if the minimum of the cubic
        // is beyond stp. Otherwise the cubic step is defined to be
        // either stpmin or stpmax. The quadratic (secant) step is also
        // computed and if the minimum is bracketed then the the step
        // closest to stx is taken, else the step farthest away is taken.
        info = 3;
        bound = true;
        theta = FloatType(3) * (fx - fp) / (stp - stx) + dx + dp;
        s = max3(abs(theta), abs(dx), abs(dp));
        gamma = s * std::sqrt(
          std::max(FloatType(0), pow2(theta / s) - (dx / s) * (dp / s)));
        if (stp > stx) gamma = -gamma;
        p = (gamma - dp) + theta;
        q = (gamma + (dx - dp)) + gamma;
        r = p/q;
        if (r < FloatType(0) && gamma != FloatType(0)) {
          stpc = stp + r * (stx - stp);
        }
        else if (stp > stx) {
          stpc = stpmax;
        }
        else {
          stpc = stpmin;
        }
        stpq = stp + (dp / (dp - dx)) * (stx - stp);
        if (brackt) {
          if (abs(stp - stpc) < abs(stp - stpq)) {
            stpf = stpc;
          }
          else {
            stpf = stpq;
          }
        }
        else {
          if (abs(stp - stpc) > abs(stp - stpq)) {
            stpf = stpc;
          }
          else {
            stpf = stpq;
          }
        }
      }
      else {
        // Fourth case. A lower function value, derivatives of the
        // same sign, and the magnitude of the derivative does
        // not decrease. If the minimum is not bracketed, the step
        // is either stpmin or stpmax, else the cubic step is taken.
        info = 4;
        bound = false;
        if (brackt) {
          theta = FloatType(3) * (fp - fy) / (sty - stp) + dy + dp;
          s = max3(abs(theta), abs(dy), abs(dp));
          gamma = s * std::sqrt(pow2(theta / s) - (dy / s) * (dp / s));
          if (stp > sty) gamma = -gamma;
          p = (gamma - dp) + theta;
          q = ((gamma - dp) + gamma) + dy;
          r = p/q;
          stpc = stp + r * (sty - stp);
          stpf = stpc;
        }
        else if (stp > stx) {
          stpf = stpmax;
        }
        else {
          stpf = stpmin;
        }
      }
      // Update the interval of uncertainty. This update does not
      // depend on the new step or the case analysis above.
      if (fp > fx) {
        sty = stp;
        fy = fp;
        dy = dp;
      }
      else {
        if (sgnd < FloatType(0)) {
          sty = stx;
          fy = fx;
          dy = dx;
        }
        stx = stp;
        fx = fp;
        dx = dp;
      }
      // Compute the new step and safeguard it.
      stpf = std::min(stpmax, stpf);
      stpf = std::max(stpmin, stpf);
      stp = stpf;
      if (brackt && bound) {
        if (sty > stx) {
          stp = std::min(stx + FloatType(0.66) * (sty - stx), stp);
        }
        else {
          stp = std::max(stx + FloatType(0.66) * (sty - stx), stp);
        }
      }
      return info;
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movapd %xmm3, %xmm10
movapd %xmm0, %xmm12
movq 0xa8(%rsp), %rbx
movq 0xa0(%rsp), %r11
movb (%rbx), %r10b
movsd (%r11), %xmm11
movsd (%rdi), %xmm9
cmpb $0x1, %r10b
jne 0x6ea3
movsd (%rcx), %xmm0
movapd %xmm0, %xmm3
minsd %xmm9, %xmm3
xorl %eax, %eax
ucomisd %xmm11, %xmm3
jae 0x746b
maxsd %xmm9, %xmm0
ucomisd %xmm0, %xmm11
jae 0x746b
xorl %eax, %eax
ucomisd %xmm10, %xmm2
ja 0x746b
movsd (%rdx), %xmm14
movapd %xmm11, %xmm4
subsd %xmm9, %xmm4
movapd %xmm14, %xmm0
mulsd %xmm4, %xmm0
xorpd %xmm3, %xmm3
ucomisd %xmm3, %xmm0
jae 0x746b
movapd 0x1142(%rip), %xmm0     # 0x8020
xorpd %xmm14, %xmm0
movapd %xmm0, %xmm5
maxsd %xmm14, %xmm5
movapd %xmm14, %xmm13
divsd %xmm5, %xmm13
mulsd %xmm1, %xmm13
movsd (%rsi), %xmm3
ucomisd %xmm3, %xmm12
jbe 0x6f7f
subsd %xmm12, %xmm3
mulsd 0x14dd(%rip), %xmm3     # 0x83f0
divsd %xmm4, %xmm3
addsd %xmm3, %xmm14
addsd %xmm1, %xmm14
movapd 0x10f7(%rip), %xmm6     # 0x8020
movapd %xmm14, %xmm3
xorpd %xmm6, %xmm3
maxsd %xmm14, %xmm3
xorpd %xmm1, %xmm6
maxsd %xmm1, %xmm6
maxsd %xmm3, %xmm5
maxsd %xmm5, %xmm6
movapd %xmm14, %xmm4
divsd %xmm6, %xmm4
mulsd %xmm4, %xmm4
movapd %xmm1, %xmm3
divsd %xmm6, %xmm3
divsd %xmm6, %xmm0
mulsd %xmm3, %xmm0
addsd %xmm4, %xmm0
xorpd %xmm3, %xmm3
ucomisd %xmm3, %xmm0
jb 0x7003
sqrtsd %xmm0, %xmm0
jmp 0x7098
xorpd %xmm6, %xmm6
ucomisd %xmm13, %xmm6
jbe 0x717e
subsd %xmm12, %xmm3
mulsd 0x1455(%rip), %xmm3     # 0x83f0
divsd %xmm4, %xmm3
addsd %xmm3, %xmm14
addsd %xmm1, %xmm14
movapd 0x106f(%rip), %xmm7     # 0x8020
movapd %xmm14, %xmm3
xorpd %xmm7, %xmm3
maxsd %xmm14, %xmm3
xorpd %xmm1, %xmm7
maxsd %xmm1, %xmm7
maxsd %xmm3, %xmm5
maxsd %xmm5, %xmm7
movapd %xmm14, %xmm4
divsd %xmm7, %xmm4
mulsd %xmm4, %xmm4
movapd %xmm1, %xmm3
divsd %xmm7, %xmm3
divsd %xmm7, %xmm0
mulsd %xmm3, %xmm0
addsd %xmm4, %xmm0
ucomisd %xmm6, %xmm0
jb 0x726f
sqrtsd %xmm0, %xmm0
jmp 0x7304
movsd %xmm2, 0x18(%rsp)
movsd %xmm10, 0x10(%rsp)
movapd %xmm1, 0x50(%rsp)
movsd %xmm12, 0x8(%rsp)
movq %r9, %rbp
movq %rcx, %rbx
movq %r8, %r15
movq %rdx, %r12
movq %rsi, %r13
movq %rdi, %r14
movapd %xmm13, 0x40(%rsp)
movapd %xmm14, 0x30(%rsp)
movapd %xmm6, 0x20(%rsp)
callq 0x3140
movapd 0x20(%rsp), %xmm6
movapd 0x30(%rsp), %xmm14
movapd 0x40(%rsp), %xmm13
movq %r14, %rdi
movq %r13, %rsi
movq %r12, %rdx
movq %r15, %r8
movq %rbx, %rcx
movq 0xa0(%rsp), %r11
movq %rbp, %r9
movsd 0x8(%rsp), %xmm12
movq 0xa8(%rsp), %rbx
movapd 0x50(%rsp), %xmm1
movsd 0x10(%rsp), %xmm10
movsd 0x18(%rsp), %xmm2
mulsd %xmm0, %xmm6
movsd (%r11), %xmm11
movsd (%rdi), %xmm0
movapd 0xf72(%rip), %xmm9      # 0x8020
movapd %xmm6, %xmm3
xorpd %xmm9, %xmm3
movapd %xmm11, %xmm4
cmpltsd %xmm0, %xmm4
andpd %xmm4, %xmm3
andnpd %xmm6, %xmm4
orpd %xmm3, %xmm4
movsd (%rdx), %xmm5
movapd %xmm4, %xmm3
subsd %xmm5, %xmm3
addsd %xmm3, %xmm14
addsd %xmm4, %xmm3
addsd %xmm1, %xmm3
divsd %xmm3, %xmm14
movapd %xmm11, %xmm3
subsd %xmm0, %xmm3
movsd (%rsi), %xmm4
subsd %xmm12, %xmm4
divsd %xmm3, %xmm4
addsd %xmm5, %xmm4
divsd %xmm4, %xmm5
movsd 0xf57(%rip), %xmm4      # 0x8068
mulsd %xmm4, %xmm5
unpcklpd %xmm5, %xmm14           # xmm14 = xmm14[0],xmm5[0]
unpcklpd %xmm3, %xmm3            # xmm3 = xmm3[0,0]
mulpd %xmm14, %xmm3
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
addpd %xmm0, %xmm3
movapd %xmm3, %xmm5
subpd %xmm0, %xmm5
xorpd %xmm5, %xmm9
maxpd %xmm5, %xmm9
movapd %xmm9, %xmm0
unpckhpd %xmm9, %xmm0            # xmm0 = xmm0[1],xmm9[1]
movapd %xmm3, %xmm5
unpckhpd %xmm3, %xmm5            # xmm5 = xmm5[1],xmm3[1]
subsd %xmm3, %xmm5
mulsd %xmm4, %xmm5
addsd %xmm3, %xmm5
cmpltsd %xmm0, %xmm9
andpd %xmm9, %xmm3
andnpd %xmm5, %xmm9
orpd %xmm3, %xmm9
movb $0x1, (%rbx)
pushq $0x1
popq %rax
movb $0x1, %r10b
jmp 0x73c2
movapd 0xe9a(%rip), %xmm7      # 0x8020
xorpd %xmm1, %xmm7
maxsd %xmm1, %xmm7
ucomisd %xmm7, %xmm5
jbe 0x747a
subsd %xmm12, %xmm3
mulsd 0x124b(%rip), %xmm3     # 0x83f0
divsd %xmm4, %xmm3
addsd %xmm14, %xmm3
addsd %xmm1, %xmm3
movapd 0xe66(%rip), %xmm4      # 0x8020
movapd %xmm3, %xmm6
xorpd %xmm4, %xmm6
maxsd %xmm3, %xmm6
maxsd %xmm6, %xmm5
maxsd %xmm5, %xmm7
movapd %xmm3, %xmm5
divsd %xmm7, %xmm5
mulsd %xmm5, %xmm5
movapd %xmm1, %xmm6
divsd %xmm7, %xmm6
divsd %xmm7, %xmm0
mulsd %xmm6, %xmm0
addsd %xmm5, %xmm0
xorpd %xmm5, %xmm5
maxsd %xmm5, %xmm0
sqrtsd %xmm0, %xmm0
mulsd %xmm7, %xmm0
movapd %xmm0, %xmm6
xorpd %xmm4, %xmm6
ucomisd %xmm6, %xmm0
jne 0x7212
jnp 0x750a
movapd %xmm9, %xmm7
cmpltsd %xmm11, %xmm7
movapd %xmm7, %xmm8
andnpd %xmm0, %xmm8
andpd %xmm6, %xmm7
orpd %xmm8, %xmm7
movapd %xmm14, %xmm0
subsd %xmm1, %xmm0
addsd %xmm7, %xmm0
addsd %xmm7, %xmm0
subsd %xmm1, %xmm7
addsd %xmm7, %xmm3
divsd %xmm0, %xmm3
ucomisd %xmm3, %xmm5
jbe 0x750a
movapd %xmm9, %xmm0
subsd %xmm11, %xmm0
mulsd %xmm0, %xmm3
addsd %xmm11, %xmm3
jmp 0x751a
movsd %xmm2, 0x18(%rsp)
movsd %xmm10, 0x10(%rsp)
movapd %xmm1, 0x50(%rsp)
movsd %xmm12, 0x8(%rsp)
movq %r9, %rbp
movq %rcx, %r13
movq %r8, %r15
movq %rdx, %r12
movq %rsi, %rbx
movq %rdi, %r14
movapd %xmm13, 0x40(%rsp)
movapd %xmm14, 0x30(%rsp)
movapd %xmm7, 0x20(%rsp)
callq 0x3140
movapd 0x20(%rsp), %xmm7
movapd 0x30(%rsp), %xmm14
movapd 0x40(%rsp), %xmm13
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
movq %r15, %r8
movq %r13, %rcx
movq 0xa0(%rsp), %r11
movq %rbp, %r9
movsd 0x8(%rsp), %xmm12
movq 0xa8(%rsp), %rbx
movapd 0x50(%rsp), %xmm1
movsd 0x10(%rsp), %xmm10
movsd 0x18(%rsp), %xmm2
mulsd %xmm0, %xmm7
movsd (%r11), %xmm11
movsd (%rdi), %xmm0
movapd 0xd07(%rip), %xmm3      # 0x8020
movapd %xmm7, %xmm5
xorpd %xmm3, %xmm5
movapd %xmm0, %xmm4
cmpltsd %xmm11, %xmm4
andpd %xmm4, %xmm5
andnpd %xmm7, %xmm4
orpd %xmm5, %xmm4
movapd %xmm4, %xmm6
subsd %xmm1, %xmm6
addsd %xmm6, %xmm14
addsd %xmm4, %xmm6
movsd (%rdx), %xmm4
addsd %xmm4, %xmm6
subsd %xmm11, %xmm0
movapd %xmm1, %xmm5
subsd %xmm4, %xmm5
unpcklpd %xmm5, %xmm6            # xmm6 = xmm6[0],xmm5[0]
unpcklpd %xmm1, %xmm14           # xmm14 = xmm14[0],xmm1[0]
divpd %xmm6, %xmm14
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
mulpd %xmm14, %xmm0
movapd %xmm11, %xmm5
unpcklpd %xmm11, %xmm5           # xmm5 = xmm5[0],xmm11[0]
addpd %xmm5, %xmm0
movapd %xmm0, %xmm4
subpd %xmm5, %xmm4
xorpd %xmm4, %xmm3
maxpd %xmm4, %xmm3
movapd %xmm3, %xmm9
unpckhpd %xmm3, %xmm9            # xmm9 = xmm9[1],xmm3[1]
cmpltsd %xmm3, %xmm9
movapd %xmm9, %xmm3
andpd %xmm0, %xmm3
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
andnpd %xmm0, %xmm9
orpd %xmm3, %xmm9
movb $0x1, (%rbx)
pushq $0x2
popq %rax
xorl %r10d, %r10d
ucomisd (%rsi), %xmm12
jbe 0x73d6
movsd %xmm11, (%rcx)
movq %r8, %rsi
movq %r9, %rdx
jmp 0x7405
xorpd %xmm0, %xmm0
ucomisd %xmm13, %xmm0
jbe 0x7400
movsd (%rdi), %xmm0
movsd %xmm0, (%rcx)
movsd (%rsi), %xmm0
movsd %xmm0, (%r8)
movsd (%rdx), %xmm0
movsd %xmm0, (%r9)
movsd (%r11), %xmm11
movsd %xmm11, (%rdi)
movsd %xmm12, (%rsi)
movsd %xmm1, (%rdx)
minsd %xmm10, %xmm9
maxsd %xmm2, %xmm9
movsd %xmm9, (%r11)
andb (%rbx), %r10b
cmpb $0x1, %r10b
jne 0x746b
movsd (%rcx), %xmm1
movsd (%rdi), %xmm3
movapd %xmm1, %xmm0
subsd %xmm3, %xmm0
mulsd 0xfaa(%rip), %xmm0      # 0x83e8
addsd %xmm3, %xmm0
xorl %ecx, %ecx
ucomisd %xmm0, %xmm9
seta %cl
xorl %edx, %edx
ucomisd %xmm9, %xmm0
seta %dl
ucomisd %xmm3, %xmm1
cmoval %edx, %ecx
testb %cl, %cl
jne 0x7466
movapd %xmm0, %xmm9
movsd %xmm9, (%r11)
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testb %r10b, %r10b
je 0x7578
movapd %xmm12, %xmm5
subsd (%r8), %xmm5
mulsd 0xf5b(%rip), %xmm5      # 0x83f0
movsd (%rcx), %xmm0
subsd %xmm11, %xmm0
divsd %xmm0, %xmm5
movsd (%r9), %xmm4
addsd %xmm4, %xmm5
addsd %xmm1, %xmm5
movapd 0xb69(%rip), %xmm0      # 0x8020
movapd %xmm5, %xmm3
xorpd %xmm0, %xmm3
maxsd %xmm5, %xmm3
xorpd %xmm4, %xmm0
maxsd %xmm4, %xmm0
maxsd %xmm3, %xmm0
maxsd %xmm0, %xmm7
movapd %xmm5, %xmm0
divsd %xmm7, %xmm0
mulsd %xmm0, %xmm0
movapd %xmm1, %xmm3
divsd %xmm7, %xmm3
divsd %xmm7, %xmm4
mulsd %xmm3, %xmm4
subsd %xmm4, %xmm0
xorpd %xmm3, %xmm3
ucomisd %xmm3, %xmm0
jb 0x75aa
sqrtsd %xmm0, %xmm0
jmp 0x763d
ucomisd %xmm9, %xmm11
movapd %xmm10, %xmm3
ja 0x751a
movapd %xmm2, %xmm3
movapd %xmm1, %xmm0
subsd %xmm14, %xmm0
movapd %xmm1, %xmm5
divsd %xmm0, %xmm5
subsd %xmm11, %xmm9
mulsd %xmm5, %xmm9
addsd %xmm11, %xmm9
movapd %xmm11, %xmm5
subsd %xmm3, %xmm5
movapd %xmm5, %xmm0
xorpd %xmm4, %xmm0
maxsd %xmm5, %xmm0
movapd %xmm11, %xmm5
subsd %xmm9, %xmm5
xorpd %xmm5, %xmm4
maxsd %xmm5, %xmm4
pushq $0x3
popq %rax
testb %r10b, %r10b
je 0x7593
movb $0x1, %r10b
ucomisd %xmm0, %xmm4
jbe 0x73c2
jmp 0x75a0
pushq $0x4
popq %rax
xorl %r10d, %r10d
ucomisd %xmm9, %xmm11
jbe 0x769d
movapd %xmm10, %xmm9
jmp 0x73c2
movb $0x1, %r10b
ucomisd %xmm4, %xmm0
jbe 0x73c2
movapd %xmm3, %xmm9
jmp 0x73c2
movsd %xmm2, 0x18(%rsp)
movsd %xmm10, 0x10(%rsp)
movapd %xmm1, 0x50(%rsp)
movsd %xmm12, 0x8(%rsp)
movq %r9, %rbp
movq %rcx, %rbx
movq %r8, %r15
movq %rdx, %r12
movq %rsi, %r13
movq %rdi, %r14
movapd %xmm13, 0x40(%rsp)
movapd %xmm7, 0x30(%rsp)
movapd %xmm5, 0x20(%rsp)
callq 0x3140
movapd 0x20(%rsp), %xmm5
movapd 0x30(%rsp), %xmm7
movapd 0x40(%rsp), %xmm13
movq %r14, %rdi
movq %r13, %rsi
movq %r12, %rdx
movq %r15, %r8
movq %rbx, %rcx
movq 0xa0(%rsp), %r11
movq %rbp, %r9
movsd 0x8(%rsp), %xmm12
movq 0xa8(%rsp), %rbx
movapd 0x50(%rsp), %xmm1
movsd 0x10(%rsp), %xmm10
movsd 0x18(%rsp), %xmm2
mulsd %xmm7, %xmm0
movsd (%r11), %xmm11
movsd (%rcx), %xmm9
movapd 0x9cd(%rip), %xmm3      # 0x8020
xorpd %xmm0, %xmm3
movapd %xmm9, %xmm4
cmpltsd %xmm11, %xmm4
andpd %xmm4, %xmm3
andnpd %xmm0, %xmm4
orpd %xmm3, %xmm4
movapd %xmm4, %xmm0
subsd %xmm1, %xmm0
addsd %xmm0, %xmm5
addsd %xmm4, %xmm0
addsd (%r9), %xmm0
divsd %xmm0, %xmm5
subsd %xmm11, %xmm9
mulsd %xmm5, %xmm9
addsd %xmm11, %xmm9
pushq $0x4
jmp 0x73be
movapd %xmm2, %xmm9
jmp 0x73c2
nop