1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_COMPLEX_ALTIVEC_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_COMPLEX_ALTIVEC_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstatic Packet4ui  p4ui_CONJ_XOR = vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_ZERO_);//{ 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstatic Packet16uc p16uc_COMPLEX_RE   = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 2), 8);//{ 0,1,2,3, 0,1,2,3, 8,9,10,11, 8,9,10,11 };
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstatic Packet16uc p16uc_COMPLEX_IM   = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 1), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);//{ 4,5,6,7, 4,5,6,7, 12,13,14,15, 12,13,14,15 };
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstatic Packet16uc p16uc_COMPLEX_REV  = vec_sld(p16uc_REVERSE, p16uc_REVERSE, 8);//{ 4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11 };
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstatic Packet16uc p16uc_COMPLEX_REV2 = vec_sld(p16uc_FORWARD, p16uc_FORWARD, 8);//{ 8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7 };
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstatic Packet16uc p16uc_PSET_HI = (Packet16uc) vec_mergeh((Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 1));//{ 0,1,2,3, 4,5,6,7, 0,1,2,3, 4,5,6,7 };
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstatic Packet16uc p16uc_PSET_LO = (Packet16uc) vec_mergeh((Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 2), (Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 3));//{ 8,9,10,11, 12,13,14,15, 8,9,10,11, 12,13,14,15 };
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//---------- float ----------
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct Packet2cf
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Packet2cf() {}
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {}
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet4f  v;
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct packet_traits<std::complex<float> >  : default_packet_traits
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Packet2cf type;
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Vectorizable = 1,
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    AlignedOnScalar = 1,
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    size = 2,
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasAdd    = 1,
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasSub    = 1,
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasMul    = 1,
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasDiv    = 1,
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasNegate = 1,
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasAbs    = 0,
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasAbs2   = 0,
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasMin    = 0,
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasMax    = 0,
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasSetLinear = 0
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct unpacket_traits<Packet2cf> { typedef std::complex<float> type; enum {size=2}; };
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>&  from)
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet2cf res;
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  /* On AltiVec we cannot load 64-bit registers, so wa have to take care of alignment */
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if((ptrdiff_t(&from) % 16) == 0)
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    res.v = pload<Packet4f>((const float *)&from);
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    res.v = ploadu<Packet4f>((const float *)&from);
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  res.v = vec_perm(res.v, res.v, p16uc_PSET_HI);
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return res;
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_add(a.v,b.v)); }
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_sub(a.v,b.v)); }
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate(a.v)); }
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) { return Packet2cf((Packet4f)vec_xor((Packet4ui)a.v, p4ui_CONJ_XOR)); }
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet4f v1, v2;
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // Permute and multiply the real parts of a and b
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  v1 = vec_perm(a.v, a.v, p16uc_COMPLEX_RE);
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // Get the imaginary parts of a
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  v2 = vec_perm(a.v, a.v, p16uc_COMPLEX_IM);
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // multiply a_re * b
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  v1 = vec_madd(v1, b.v, p4f_ZERO);
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // multiply a_im * b and get the conjugate result
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  v2 = vec_madd(v2, b.v, p4f_ZERO);
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  v2 = (Packet4f) vec_xor((Packet4ui)v2, p4ui_CONJ_XOR);
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // permute back to a proper order
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  v2 = vec_perm(v2, v2, p16uc_COMPLEX_REV);
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return Packet2cf(vec_add(v1, v2));
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pand   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_and(a.v,b.v)); }
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf por    <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_or(a.v,b.v)); }
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pxor   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_xor(a.v,b.v)); }
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_and(a.v, vec_nor(b.v,b.v))); }
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>((const float*)from)); }
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>((const float*)from)); }
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>*     from)
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return pset1<Packet2cf>(*from);
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); }
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); }
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> *   addr) { vec_dstt((float *)addr, DST_CTRL(2,2,32), DST_CHAN); }
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE std::complex<float>  pfirst<Packet2cf>(const Packet2cf& a)
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  std::complex<float> EIGEN_ALIGN16 res[2];
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  pstore((float *)&res, a.v);
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return res[0];
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a)
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet4f rev_a;
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  rev_a = vec_perm(a.v, a.v, p16uc_COMPLEX_REV2);
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return Packet2cf(rev_a);
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a)
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet4f b;
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  b = (Packet4f) vec_sld(a.v, a.v, 8);
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  b = padd(a.v, b);
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return pfirst(Packet2cf(b));
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf preduxp<Packet2cf>(const Packet2cf* vecs)
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet4f b1, b2;
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  b1 = (Packet4f) vec_sld(vecs[0].v, vecs[1].v, 8);
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  b2 = (Packet4f) vec_sld(vecs[1].v, vecs[0].v, 8);
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  b2 = (Packet4f) vec_sld(b2, b2, 8);
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  b2 = padd(b1, b2);
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return Packet2cf(b2);
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a)
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet4f b;
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet2cf prod;
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  b = (Packet4f) vec_sld(a.v, a.v, 8);
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  prod = pmul(a, Packet2cf(b));
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return pfirst(prod);
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Offset>
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct palign_impl<Offset,Packet2cf>
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second)
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if (Offset==1)
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      first.v = vec_sld(first.v, second.v, 8);
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct conj_helper<Packet2cf, Packet2cf, false,true>
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return padd(pmul(x,y),c); }
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return internal::pmul(a, pconj(b));
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct conj_helper<Packet2cf, Packet2cf, true,false>
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return padd(pmul(x,y),c); }
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return internal::pmul(pconj(a), b);
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct conj_helper<Packet2cf, Packet2cf, true,true>
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  { return padd(pmul(x,y),c); }
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return pconj(internal::pmul(a, b));
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // TODO optimize it for AltiVec
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet2cf res = conj_helper<Packet2cf,Packet2cf,false,true>().pmul(a,b);
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Packet4f s = vec_madd(b.v, b.v, p4f_ZERO);
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return Packet2cf(pdiv(res.v, vec_add(s,vec_perm(s, s, p16uc_COMPLEX_REV))));
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& x)
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return Packet2cf(vec_perm(x.v, x.v, p16uc_COMPLEX_REV));
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_COMPLEX_ALTIVEC_H
218