// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/RNBasics/RNSvd.cpp
// Function: gaps::golub_kahn_svd_rot(double*, int, int, double*, int, int, int)
void golub_kahn_svd_rot(RNScalar * b,int p,int q,RNScalar * v,int m,int n,int min)
{
    RNScalar t11, t12, t22;
    RNScalar uu;
    RNScalar b11, b12;
    RNScalar dm,fm,dn,fn;
    RNScalar hypot,cos,sin;
    RNScalar d, s, y, z;

    /* grab the last diagonal and superdiagonal elements of b22 */
    fm = (q-2) < 0 ? 0 : REF2D(b,m,n,q-2,q-1);
    dm = REF2D(b,m,n,q-1,q-1);	fn = REF2D(b,m,n,q-1,q);
				dn = REF2D(b,m,n,q,q);

    /* create the trailing 2x2 submatrix of T = b22^t b22 */
    t11 = dm*dm + fm * fm;
    t12 = dm * fn;		t22 = dn * dn + fn * fn;

    /* find the eigenvalues of the T matrix.
    **
    ** The quadratic equation for the eigenvalues has coefficients:
    ** a = 1
    ** b = -(t11+t22)
    ** c = t11 t22 - t12 t12
    **
    ** b^2 - 4ac = (t11^2 + t22^2 + 2 t11 t12) - 4 t11 t22 + 4 t12 t12
    **           = (t11 - t22)^2 + 4 t12 t12
    **
    ** sqrt(b^2-4ac) = sqrt((t11 - t22)^2 + 4 t12 t12) -- use "pythag()"
    **
    ** using quadratic formula, we have the eigenvalues:
    ** (u1,u2) = .5 (t11 + t22 +/- pythag(...))
    **         = t22 + .5 (t11 - t22 +/- pythag(...))
    **
    ** We propogate the .5 into the pythag term, yielding golub's equation 8.2-2
    ** for the "wilkinson shift".
    ** [Note:  Golub says to use (t22 + d - signum(d) s) to find the eigenvalue
    ** closer to t22.  He's right.  ]
    **/
    d = ((RNScalar) 0.5)*(t11 - t22);
    s = fhypot (d,t12);
    uu = t22 + d + ((d > 0) ? -s : s);

    /* grab the leading 2x1 of b */
    b11 = REF2D(b,m,n,p,p);	b12 = REF2D(b,m,n,p,p+1);

    /* make the leading 2x1 submatrix of T */
    t11 = b11 * b11;
    t12 = b11 * b12;

    /* calculate the rotation that would zero the off-diagonal term of the
    ** shifted matrix T - uu I
    */
    y = t11 - uu;
    z = t12;
    hypot = fhypot (y,z);
    cos = y / hypot;
    sin = z / hypot;

    /* perform the rotation on B.  This sprays some glop into the upper-left
    ** subdiagonal element.
    */
    rotate_cols(p,p+1,cos,sin,b,p,2,m,n);
    /* accumulate the rotation into the rows of v */
    rotate_rows(p,p+1,cos,sin,v,0,n,min,n);
}

// Assembly:
cmpl $0x1, %edx
jg 0x708f0
leal -0x1(%rdx), %eax
xorpd %xmm1, %xmm1
jmp 0x7090a
leal -0x2(%rdx), %r8d
imull %r9d, %r8d
leal -0x1(%rdx), %eax
addl %edx, %r8d
decl %r8d
movslq %r8d, %r8
movsd (%rdi,%r8,8), %xmm1
pushq %r14
pushq %rbx
movl %eax, %r8d
imull %r9d, %r8d
addl %r8d, %eax
cltq
movsd (%rdi,%rax,8), %xmm0
addl %edx, %r8d
movslq %r8d, %rax
movsd (%rdi,%rax,8), %xmm3
leal 0x1(%r9), %eax
imull %edx, %eax
cltq
movapd %xmm0, %xmm2
mulsd %xmm3, %xmm2
unpcklpd %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0]
movhpd (%rdi,%rax,8), %xmm0    # xmm0 = xmm0[0],mem[0]
mulpd %xmm1, %xmm1
mulpd %xmm0, %xmm0
addpd %xmm1, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
subsd %xmm1, %xmm0
mulsd 0x316cd(%rip), %xmm0    # 0xa2030
mulsd %xmm2, %xmm2
addsd %xmm0, %xmm1
xorpd %xmm3, %xmm3
cmpltsd %xmm0, %xmm3
mulsd %xmm0, %xmm0
addsd %xmm2, %xmm0
sqrtsd %xmm0, %xmm4
movapd 0x31698(%rip), %xmm0    # 0xa2020
movapd %xmm3, %xmm2
andnpd %xmm4, %xmm2
xorpd %xmm0, %xmm4
andpd %xmm3, %xmm4
orpd %xmm2, %xmm4
addsd %xmm1, %xmm4
movl %r9d, %eax
imull %esi, %eax
leal (%rax,%rsi), %edx
movslq %edx, %rdx
movsd (%rdi,%rdx,8), %xmm1
leal 0x1(%rsi), %r8d
leal 0x1(%rax,%rsi), %edx
movslq %edx, %rdx
movapd %xmm1, %xmm2
mulsd %xmm1, %xmm2
subsd %xmm4, %xmm2
mulsd (%rdi,%rdx,8), %xmm1
movapd %xmm1, %xmm3
mulsd %xmm1, %xmm3
movapd %xmm2, %xmm4
mulsd %xmm2, %xmm4
addsd %xmm3, %xmm4
xorps %xmm3, %xmm3
sqrtsd %xmm4, %xmm3
divsd %xmm3, %xmm2
divsd %xmm3, %xmm1
xorpd %xmm1, %xmm0
movslq %esi, %r10
addl $0x2, %esi
movslq %r9d, %rdx
movslq %esi, %rsi
movq %rdx, %r11
imulq %r10, %r11
shlq $0x3, %r11
leaq (%r11,%r10,8), %r11
addq $0x8, %r11
leaq (,%rdx,8), %rbx
leaq 0x8(,%rdx,8), %r14
imulq %r10, %r14
movsd (%rdi,%r14), %xmm3
movsd (%rdi,%r11), %xmm4
movapd %xmm1, %xmm5
mulsd %xmm4, %xmm5
movapd %xmm2, %xmm6
mulsd %xmm3, %xmm6
addsd %xmm5, %xmm6
movsd %xmm6, (%rdi,%r14)
mulsd %xmm2, %xmm4
mulsd %xmm0, %xmm3
addsd %xmm4, %xmm3
movsd %xmm3, (%rdi,%r11)
incq %r10
addq %rbx, %rdi
cmpq %rsi, %r10
jl 0x70a27
testl %r9d, %r9d
popq %rbx
popq %r14
jle 0x70ac1
imull %r9d, %r8d
cltq
movslq %r8d, %rsi
leaq (%rcx,%rax,8), %rax
leaq (%rcx,%rsi,8), %rcx
xorl %esi, %esi
movsd (%rax,%rsi,8), %xmm3
movsd (%rcx,%rsi,8), %xmm4
movapd %xmm1, %xmm5
mulsd %xmm4, %xmm5
movapd %xmm2, %xmm6
mulsd %xmm3, %xmm6
addsd %xmm5, %xmm6
movsd %xmm6, (%rax,%rsi,8)
mulsd %xmm2, %xmm4
mulsd %xmm0, %xmm3
addsd %xmm4, %xmm3
movsd %xmm3, (%rcx,%rsi,8)
incq %rsi
cmpq %rsi, %rdx
jne 0x70a85
retq