// File: /workspace/github_cpp_makefile_star2_O1/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %r9d, %r14d
movq %rcx, %rbx
movl %esi, %r12d
movq %rdi, %r15
xorpd %xmm1, %xmm1
xorpd %xmm0, %xmm0
cmpl $0x2, %edx
jl 0x718f2
leal -0x2(%rdx), %eax
imull %r14d, %eax
addl %edx, %eax
decl %eax
cltq
movsd (%r15,%rax,8), %xmm0
leal -0x1(%rdx), %eax
imull %r14d, %eax
leal (%rax,%rdx), %ecx
decl %ecx
movslq %ecx, %rcx
movsd (%r15,%rcx,8), %xmm4
addl %edx, %eax
cltq
movsd (%r15,%rax,8), %xmm2
leal 0x1(%r14), %eax
imull %edx, %eax
cltq
movapd %xmm4, %xmm3
mulsd %xmm2, %xmm3
unpcklpd %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0]
mulpd %xmm0, %xmm0
movhpd (%r15,%rax,8), %xmm4    # xmm4 = xmm4[0],mem[0]
mulpd %xmm4, %xmm4
addpd %xmm0, %xmm4
movapd %xmm4, %xmm5
unpckhpd %xmm4, %xmm5            # xmm5 = xmm5[1],xmm4[1]
subsd %xmm5, %xmm4
mulsd 0x306e4(%rip), %xmm4    # 0xa2030
mulsd %xmm3, %xmm3
movapd %xmm4, %xmm0
mulsd %xmm4, %xmm0
addsd %xmm3, %xmm0
ucomisd %xmm1, %xmm0
jb 0x71968
sqrtsd %xmm0, %xmm0
jmp 0x71983
movapd %xmm4, 0x10(%rsp)
movapd %xmm5, (%rsp)
callq 0xe340
movapd (%rsp), %xmm5
movapd 0x10(%rsp), %xmm4
addsd %xmm4, %xmm5
movapd 0x30691(%rip), %xmm2    # 0xa2020
xorpd %xmm0, %xmm2
xorpd %xmm1, %xmm1
xorpd %xmm3, %xmm3
cmpltsd %xmm4, %xmm3
andpd %xmm3, %xmm2
andnpd %xmm0, %xmm3
orpd %xmm2, %xmm3
addsd %xmm5, %xmm3
movl %r14d, %r13d
imull %r12d, %r13d
leal (%r12,%r13), %eax
cltq
movsd (%r15,%rax,8), %xmm5
leal 0x1(%r12), %ebp
leal 0x1(%r13,%r12), %eax
cltq
movapd %xmm5, %xmm6
mulsd %xmm5, %xmm6
mulsd (%r15,%rax,8), %xmm5
subsd %xmm3, %xmm6
movapd %xmm5, %xmm2
mulsd %xmm5, %xmm2
movapd %xmm6, %xmm0
mulsd %xmm6, %xmm0
addsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jb 0x71a01
sqrtsd %xmm0, %xmm0
jmp 0x71a1c
movapd %xmm5, 0x10(%rsp)
movsd %xmm6, (%rsp)
callq 0xe340
movsd (%rsp), %xmm6
movapd 0x10(%rsp), %xmm5
divsd %xmm0, %xmm6
divsd %xmm0, %xmm5
movapd 0x305f4(%rip), %xmm0    # 0xa2020
xorpd %xmm5, %xmm0
movslq %r12d, %rcx
addl $0x2, %r12d
movslq %r14d, %rax
movslq %ebp, %rsi
movslq %r12d, %rdx
movq %rax, %rdi
imulq %rcx, %rdi
shlq $0x3, %rsi
leaq (%rsi,%rdi,8), %rsi
leaq (,%rax,8), %rdi
leaq 0x8(,%rax,8), %r8
imulq %rcx, %r8
movsd (%r15,%r8), %xmm1
movsd (%r15,%rsi), %xmm2
movapd %xmm5, %xmm3
mulsd %xmm2, %xmm3
movapd %xmm6, %xmm4
mulsd %xmm1, %xmm4
addsd %xmm3, %xmm4
movsd %xmm4, (%r15,%r8)
mulsd %xmm6, %xmm2
mulsd %xmm0, %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, (%r15,%rsi)
incq %rcx
addq %rdi, %r15
cmpq %rdx, %rcx
jl 0x71a63
testl %r14d, %r14d
jle 0x71afb
imull %r14d, %ebp
movslq %r13d, %rdx
movslq %ebp, %rcx
leaq (%rbx,%rcx,8), %rcx
leaq (%rbx,%rdx,8), %rdx
xorl %esi, %esi
movsd (%rdx,%rsi,8), %xmm1
movsd (%rcx,%rsi,8), %xmm2
movapd %xmm5, %xmm3
mulsd %xmm2, %xmm3
movapd %xmm6, %xmm4
mulsd %xmm1, %xmm4
addsd %xmm3, %xmm4
movsd %xmm4, (%rdx,%rsi,8)
mulsd %xmm6, %xmm2
mulsd %xmm0, %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, (%rcx,%rsi,8)
incq %rsi
cmpq %rsi, %rax
jne 0x71abf
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq