// File: istellartech[P]OpenTsiolkovsky/src/../lib/Eigen/src/Geometry/arch/Geometry_SSE.h
// Function: Eigen::internal::quat_product<1, Eigen::Quaternion<double, 0>, Eigen::Quaternion<double, 0>, double, 1>::run(Eigen::QuaternionBase<Eigen::Quaternion<double, 0>> const&, Eigen::QuaternionBase<Eigen::Quaternion<double, 0>> const&)
static inline Quaternion<double> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
  {
  const Packet2d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0));

  Quaternion<double> res;

  const double* a = _a.coeffs().data();
  Packet2d b_xy = _b.coeffs().template packet<Aligned>(0);
  Packet2d b_zw = _b.coeffs().template packet<Aligned>(2);
  Packet2d a_xx = pset1<Packet2d>(a[0]);
  Packet2d a_yy = pset1<Packet2d>(a[1]);
  Packet2d a_zz = pset1<Packet2d>(a[2]);
  Packet2d a_ww = pset1<Packet2d>(a[3]);

  // two temporaries:
  Packet2d t1, t2;

  /*
   * t1 = ww*xy + yy*zw
   * t2 = zz*xy - xx*zw
   * res.xy = t1 +/- swap(t2)
   */
  t1 = padd(pmul(a_ww, b_xy), pmul(a_yy, b_zw));
  t2 = psub(pmul(a_zz, b_xy), pmul(a_xx, b_zw));
#ifdef EIGEN_VECTORIZE_SSE3
  EIGEN_UNUSED_VARIABLE(mask)
  pstore(&res.x(), _mm_addsub_pd(t1, preverse(t2)));
#else
  pstore(&res.x(), padd(t1, pxor(mask,preverse(t2))));
#endif
  
  /*
   * t1 = ww*zw - yy*xy
   * t2 = zz*zw + xx*xy
   * res.zw = t1 -/+ swap(t2) = swap( swap(t1) +/- t2)
   */
  t1 = psub(pmul(a_ww, b_zw), pmul(a_yy, b_xy));
  t2 = padd(pmul(a_zz, b_zw), pmul(a_xx, b_xy));
#ifdef EIGEN_VECTORIZE_SSE3
  EIGEN_UNUSED_VARIABLE(mask)
  pstore(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2)));
#else
  pstore(&res.z(), psub(t1, pxor(mask,preverse(t2))));
#endif

  return res;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x1e8(%rbp)
movq %rdi, %rax
movq %rax, -0x1d8(%rbp)
movq %rdi, -0x38(%rbp)
movq %rsi, -0x40(%rbp)
movq %rdx, -0x48(%rbp)
movl $0x0, -0x4(%rbp)
movl $0x0, -0x8(%rbp)
movl $0x80000000, -0xc(%rbp) # imm = 0x80000000
movl $0x0, -0x10(%rbp)
movd -0x4(%rbp), %xmm0
movd -0x8(%rbp), %xmm1
punpckldq %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
movd -0xc(%rbp), %xmm2
movd -0x10(%rbp), %xmm0
punpckldq %xmm2, %xmm0    # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
punpcklqdq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0]
movdqa %xmm0, -0x20(%rbp)
movdqa -0x20(%rbp), %xmm0
movdqa %xmm0, -0x30(%rbp)
movdqa -0x30(%rbp), %xmm0
movapd %xmm0, -0x60(%rbp)
callq 0x1dbc0
movq -0x40(%rbp), %rdi
callq 0x27430
movq %rax, %rdi
callq 0x36f30
movq %rax, -0x68(%rbp)
movq -0x48(%rbp), %rdi
callq 0x27430
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x36f50
movapd %xmm0, -0x80(%rbp)
movq -0x48(%rbp), %rdi
callq 0x27430
movq %rax, %rdi
movl $0x2, %esi
callq 0x36f50
movapd %xmm0, -0x90(%rbp)
movq -0x68(%rbp), %rdi
callq 0x29520
movapd %xmm0, -0xa0(%rbp)
movq -0x68(%rbp), %rdi
addq $0x8, %rdi
callq 0x29520
movapd %xmm0, -0xb0(%rbp)
movq -0x68(%rbp), %rdi
addq $0x10, %rdi
callq 0x29520
movapd %xmm0, -0xc0(%rbp)
movq -0x68(%rbp), %rdi
addq $0x18, %rdi
callq 0x29520
movapd %xmm0, -0xd0(%rbp)
leaq -0xd0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x36fd0
movapd %xmm0, -0x100(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x36fd0
movapd %xmm0, -0x110(%rbp)
leaq -0x100(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x36f90
movapd %xmm0, -0xe0(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x36fd0
movapd %xmm0, -0x120(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x36fd0
movapd %xmm0, -0x130(%rbp)
leaq -0x120(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x37010
movq -0x1e8(%rbp), %rdi
movapd %xmm0, -0xf0(%rbp)
callq 0x37050
movq %rax, -0x1f0(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x370c0
movapd %xmm0, -0x160(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x37080
movapd %xmm0, -0x150(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x36f90
movq -0x1f0(%rbp), %rdi
movapd %xmm0, -0x140(%rbp)
leaq -0x140(%rbp), %rsi
callq 0x9260
leaq -0xd0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x36fd0
movapd %xmm0, -0x170(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x36fd0
movapd %xmm0, -0x180(%rbp)
leaq -0x170(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0x37010
movapd %xmm0, -0xe0(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x36fd0
movapd %xmm0, -0x190(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x36fd0
movapd %xmm0, -0x1a0(%rbp)
leaq -0x190(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0x36f90
movq -0x1e8(%rbp), %rdi
movapd %xmm0, -0xf0(%rbp)
callq 0x370e0
movq %rax, -0x1e0(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x370c0
movapd %xmm0, -0x1d0(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x37080
movapd %xmm0, -0x1c0(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x37010
movq -0x1e0(%rbp), %rdi
movapd %xmm0, -0x1b0(%rbp)
leaq -0x1b0(%rbp), %rsi
callq 0x9260
movq -0x1d8(%rbp), %rax
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)