10 #ifndef EIGEN_COMPLEX_ALTIVEC_H
11 #define EIGEN_COMPLEX_ALTIVEC_H
17 static Packet4ui p4ui_CONJ_XOR = vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_ZERO_);
18 static Packet16uc p16uc_COMPLEX_RE = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 2), 8);
19 static Packet16uc p16uc_COMPLEX_IM = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 1), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);
20 static Packet16uc p16uc_COMPLEX_REV = vec_sld(p16uc_REVERSE, p16uc_REVERSE, 8);
21 static Packet16uc p16uc_COMPLEX_REV2 = vec_sld(p16uc_FORWARD, p16uc_FORWARD, 8);
22 static Packet16uc p16uc_PSET_HI = (Packet16uc) vec_mergeh((Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 1));
23 static Packet16uc p16uc_PSET_LO = (Packet16uc) vec_mergeh((Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 2), (Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 3));
28 EIGEN_STRONG_INLINE Packet2cf() {}
29 EIGEN_STRONG_INLINE
explicit Packet2cf(
const Packet4f& a) : v(a) {}
33 template<>
struct packet_traits<std::complex<float> > : default_packet_traits
35 typedef Packet2cf type;
54 template<>
struct unpacket_traits<Packet2cf> {
typedef std::complex<float> type;
enum {size=2}; };
56 template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(
const std::complex<float>& from)
60 if((ptrdiff_t(&from) % 16) == 0)
61 res.v = pload<Packet4f>((
const float *)&from);
63 res.v = ploadu<Packet4f>((
const float *)&from);
64 res.v = vec_perm(res.v, res.v, p16uc_PSET_HI);
68 template<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(
const Packet2cf& a,
const Packet2cf& b) {
return Packet2cf(vec_add(a.v,b.v)); }
69 template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(
const Packet2cf& a,
const Packet2cf& b) {
return Packet2cf(vec_sub(a.v,b.v)); }
70 template<> EIGEN_STRONG_INLINE Packet2cf pnegate(
const Packet2cf& a) {
return Packet2cf(pnegate(a.v)); }
71 template<> EIGEN_STRONG_INLINE Packet2cf pconj(
const Packet2cf& a) {
return Packet2cf((Packet4f)vec_xor((Packet4ui)a.v, p4ui_CONJ_XOR)); }
73 template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(
const Packet2cf& a,
const Packet2cf& b)
78 v1 = vec_perm(a.v, a.v, p16uc_COMPLEX_RE);
80 v2 = vec_perm(a.v, a.v, p16uc_COMPLEX_IM);
82 v1 = vec_madd(v1, b.v, p4f_ZERO);
84 v2 = vec_madd(v2, b.v, p4f_ZERO);
85 v2 = (Packet4f) vec_xor((Packet4ui)v2, p4ui_CONJ_XOR);
87 v2 = vec_perm(v2, v2, p16uc_COMPLEX_REV);
89 return Packet2cf(vec_add(v1, v2));
92 template<> EIGEN_STRONG_INLINE Packet2cf pand <Packet2cf>(
const Packet2cf& a,
const Packet2cf& b) {
return Packet2cf(vec_and(a.v,b.v)); }
93 template<> EIGEN_STRONG_INLINE Packet2cf por <Packet2cf>(
const Packet2cf& a,
const Packet2cf& b) {
return Packet2cf(vec_or(a.v,b.v)); }
94 template<> EIGEN_STRONG_INLINE Packet2cf pxor <Packet2cf>(
const Packet2cf& a,
const Packet2cf& b) {
return Packet2cf(vec_xor(a.v,b.v)); }
95 template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(
const Packet2cf& a,
const Packet2cf& b) {
return Packet2cf(vec_and(a.v, vec_nor(b.v,b.v))); }
97 template<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(
const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD
return Packet2cf(pload<Packet4f>((
const float*)from)); }
98 template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(
const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD
return Packet2cf(ploadu<Packet4f>((
const float*)from)); }
100 template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(
const std::complex<float>* from)
102 return pset1<Packet2cf>(*from);
105 template<> EIGEN_STRONG_INLINE
void pstore <std::complex<float> >(std::complex<float> * to,
const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((
float*)to, from.v); }
106 template<> EIGEN_STRONG_INLINE
void pstoreu<std::complex<float> >(std::complex<float> * to,
const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((
float*)to, from.v); }
108 template<> EIGEN_STRONG_INLINE
void prefetch<std::complex<float> >(
const std::complex<float> * addr) { vec_dstt((
float *)addr, DST_CTRL(2,2,32), DST_CHAN); }
110 template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(
const Packet2cf& a)
112 std::complex<float> EIGEN_ALIGN16 res[2];
113 pstore((
float *)&res, a.v);
118 template<> EIGEN_STRONG_INLINE Packet2cf preverse(
const Packet2cf& a)
121 rev_a = vec_perm(a.v, a.v, p16uc_COMPLEX_REV2);
122 return Packet2cf(rev_a);
125 template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(
const Packet2cf& a)
128 b = (Packet4f) vec_sld(a.v, a.v, 8);
130 return pfirst(Packet2cf(b));
133 template<> EIGEN_STRONG_INLINE Packet2cf preduxp<Packet2cf>(
const Packet2cf* vecs)
137 b1 = (Packet4f) vec_sld(vecs[0].v, vecs[1].v, 8);
138 b2 = (Packet4f) vec_sld(vecs[1].v, vecs[0].v, 8);
139 b2 = (Packet4f) vec_sld(b2, b2, 8);
142 return Packet2cf(b2);
145 template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(
const Packet2cf& a)
149 b = (Packet4f) vec_sld(a.v, a.v, 8);
150 prod = pmul(a, Packet2cf(b));
156 struct palign_impl<Offset,Packet2cf>
158 static EIGEN_STRONG_INLINE
void run(Packet2cf& first,
const Packet2cf& second)
162 first.v = vec_sld(first.v, second.v, 8);
167 template<>
struct conj_helper<Packet2cf, Packet2cf, false,true>
169 EIGEN_STRONG_INLINE Packet2cf pmadd(
const Packet2cf& x,
const Packet2cf& y,
const Packet2cf& c)
const
170 {
return padd(pmul(x,y),c); }
172 EIGEN_STRONG_INLINE Packet2cf pmul(
const Packet2cf& a,
const Packet2cf& b)
const
174 return internal::pmul(a, pconj(b));
178 template<>
struct conj_helper<Packet2cf, Packet2cf, true,false>
180 EIGEN_STRONG_INLINE Packet2cf pmadd(
const Packet2cf& x,
const Packet2cf& y,
const Packet2cf& c)
const
181 {
return padd(pmul(x,y),c); }
183 EIGEN_STRONG_INLINE Packet2cf pmul(
const Packet2cf& a,
const Packet2cf& b)
const
185 return internal::pmul(pconj(a), b);
189 template<>
struct conj_helper<Packet2cf, Packet2cf, true,true>
191 EIGEN_STRONG_INLINE Packet2cf pmadd(
const Packet2cf& x,
const Packet2cf& y,
const Packet2cf& c)
const
192 {
return padd(pmul(x,y),c); }
194 EIGEN_STRONG_INLINE Packet2cf pmul(
const Packet2cf& a,
const Packet2cf& b)
const
196 return pconj(internal::pmul(a, b));
200 template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(
const Packet2cf& a,
const Packet2cf& b)
203 Packet2cf res = conj_helper<Packet2cf,Packet2cf,false,true>().pmul(a,b);
204 Packet4f s = vec_madd(b.v, b.v, p4f_ZERO);
205 return Packet2cf(pdiv(res.v, vec_add(s,vec_perm(s, s, p16uc_COMPLEX_REV))));
208 template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(
const Packet2cf& x)
210 return Packet2cf(vec_perm(x.v, x.v, p16uc_COMPLEX_REV));
217 #endif // EIGEN_COMPLEX_ALTIVEC_H