// File: /workspace/github_cpp_makefile_star2_O2/srajangarg[P]raytracer/src/core/Algebra3.hpp
// Function: Mat4::inverse() const
inline Mat4 Mat4::inverse() const    // Gauss-Jordan elimination with partial pivoting
{
  Mat4 a(*this),          // As a evolves from original mat into identity
       b(identity3D());   // b evolves from identity into inverse(a)
  int i, j, i1;

  // Loop over cols of a from left to right, eliminating above and below diag
  for (j=0; j<4; j++)   // Find largest pivot in column j among rows j..3
  {
    i1 = j;         // Row with largest pivot candidate
    for (i=j+1; i<4; i++)
      if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
        i1 = i;

    // Swap rows i1 and j in a and b to put pivot on diagonal
    swap(a.v[i1], a.v[j]);
    swap(b.v[i1], b.v[j]);

    // Scale row j to have a unit diagonal
    if (a.v[j].n[j]==0.)
      ALG3_ERROR("Mat4::inverse: singular matrix; can't invert\n");

    b.v[j] /= a.v[j].n[j];
    a.v[j] /= a.v[j].n[j];

    // Eliminate off-diagonal elems in col j of a, doing identical ops to b
    for (i=0; i<4; i++)
      if (i!=j)
      {
        b.v[i] -= a.v[i].n[j]*b.v[j];
        a.v[i] -= a.v[i].n[j]*a.v[j];
      }
  }

  return b;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rdi, %r14
leaq 0x68(%rsp), %rdi
callq 0x1e5b8
movq %r14, %rdi
callq 0x6138
pushq $-0x3
popq %rdx
leaq 0x88(%rsp), %rcx
movq $0x0, 0x8(%rsp)
xorl %r15d, %r15d
movq %r14, 0x10(%rsp)
cmpq $0x4, %r15
je 0x1e296
leaq (%rsp,%r15,8), %rax
addq $0x68, %rax
movq %rcx, 0x20(%rsp)
movq %rdx, 0x28(%rsp)
movl %r15d, %esi
movslq %esi, %rbx
testq %rdx, %rdx
je 0x1e14c
movsd (%rcx), %xmm0
movapd 0x3937(%rip), %xmm2     # 0x21a60
andpd %xmm2, %xmm0
shlq $0x5, %rbx
movsd (%rax,%rbx), %xmm1
andpd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1e143
leal 0x4(%rdx), %esi
incq %rdx
addq $0x20, %rcx
jmp 0x1e115
shlq $0x5, %rbx
leaq (%rsp,%rbx), %rdi
addq $0x68, %rdi
movq %r15, %r13
shlq $0x5, %r13
leaq (%rsp,%r13), %r12
addq $0x68, %r12
movq %r12, %rsi
callq 0x1e657
addq %r14, %rbx
addq %r14, %r13
movq %rbx, %rdi
movq %r13, %rsi
callq 0x1e657
movsd (%r12,%r15,8), %xmm0
ucomisd 0x3772(%rip), %xmm0     # 0x21900
jne 0x1e196
jnp 0x1e2ab
leaq 0x1(%r15), %rax
movq %rax, 0x18(%rsp)
movq %r13, %rdi
callq 0x1e68c
movsd (%r12,%r15,8), %xmm0
movq %r12, 0x30(%rsp)
movq %r12, %rdi
callq 0x1e68c
leaq 0x68(%rsp), %rbp
movq %r14, %rbx
xorl %r14d, %r14d
movq %r15, 0x38(%rsp)
cmpq $0x4, %r14
je 0x1e270
cmpq %r14, %r15
je 0x1e260
movupd (%r13), %xmm0
movq 0x8(%rsp), %r15
movsd (%rbp,%r15), %xmm1
unpcklpd %xmm1, %xmm1            # xmm1 = xmm1[0,0]
mulpd %xmm1, %xmm0
movapd %xmm0, 0x40(%rsp)
movupd 0x10(%r13), %xmm0
mulpd %xmm1, %xmm0
movapd %xmm0, 0x50(%rsp)
movq %rbx, %rdi
movq %r13, %r12
leaq 0x40(%rsp), %r13
movq %r13, %rsi
callq 0x1e6ba
movq 0x30(%rsp), %rax
movupd (%rax), %xmm0
movsd (%rbp,%r15), %xmm1
movq 0x38(%rsp), %r15
unpcklpd %xmm1, %xmm1            # xmm1 = xmm1[0,0]
mulpd %xmm1, %xmm0
movapd %xmm0, 0x40(%rsp)
movupd 0x10(%rax), %xmm0
mulpd %xmm1, %xmm0
movapd %xmm0, 0x50(%rsp)
movq %rbp, %rdi
movq %r13, %rsi
movq %r12, %r13
callq 0x1e6ba
incq %r14
addq $0x20, %rbx
addq $0x20, %rbp
jmp 0x1e1ca
movq 0x28(%rsp), %rdx
incq %rdx
movq 0x20(%rsp), %rcx
addq $0x28, %rcx
addq $0x8, 0x8(%rsp)
movq 0x18(%rsp), %r15
movq 0x10(%rsp), %r14
jmp 0x1e0f6
movq %r14, %rax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x50bb(%rip), %rdi      # 0x2336d
leaq 0x3506(%rip), %rsi      # 0x217bf
leaq 0x50b3(%rip), %rcx      # 0x23373
movl $0x4fc, %edx            # imm = 0x4FC
callq 0x4210