10#ifndef EIGEN_PACKET_MATH_ALTIVEC_H
11#define EIGEN_PACKET_MATH_ALTIVEC_H
17#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
18#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 4
21#ifndef EIGEN_HAS_SINGLE_INSTRUCTION_MADD
22#define EIGEN_HAS_SINGLE_INSTRUCTION_MADD
26#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS
27#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 32
30typedef __vector
float Packet4f;
31typedef __vector
int Packet4i;
32typedef __vector
unsigned int Packet4ui;
33typedef __vector __bool
int Packet4bi;
34typedef __vector
short int Packet8i;
35typedef __vector
unsigned char Packet16uc;
39#define _EIGEN_DECLARE_CONST_FAST_Packet4f(NAME,X) \
40 Packet4f p4f_##NAME = {X, X, X, X}
42#define _EIGEN_DECLARE_CONST_FAST_Packet4i(NAME,X) \
43 Packet4i p4i_##NAME = vec_splat_s32(X)
45#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \
46 Packet4f p4f_##NAME = pset1<Packet4f>(X)
48#define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \
49 Packet4i p4i_##NAME = pset1<Packet4i>(X)
51#define _EIGEN_DECLARE_CONST_Packet2d(NAME,X) \
52 Packet2d p2d_##NAME = pset1<Packet2d>(X)
54#define _EIGEN_DECLARE_CONST_Packet2l(NAME,X) \
55 Packet2l p2l_##NAME = pset1<Packet2l>(X)
57#define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \
58 const Packet4f p4f_##NAME = reinterpret_cast<Packet4f>(pset1<Packet4i>(X))
61#define DST_CTRL(size, count, stride) (((size) << 24) | ((count) << 16) | (stride))
62#define __UNPACK_TYPE__(PACKETNAME) typename unpacket_traits<PACKETNAME>::type
65static _EIGEN_DECLARE_CONST_FAST_Packet4f(ZERO, 0);
66static _EIGEN_DECLARE_CONST_FAST_Packet4i(ZERO, 0);
67static _EIGEN_DECLARE_CONST_FAST_Packet4i(ONE,1);
68static _EIGEN_DECLARE_CONST_FAST_Packet4i(MINUS16,-16);
69static _EIGEN_DECLARE_CONST_FAST_Packet4i(MINUS1,-1);
70static Packet4f p4f_MZERO = (Packet4f) vec_sl((Packet4ui)p4i_MINUS1, (Packet4ui)p4i_MINUS1);
72static Packet4f p4f_ONE = vec_ctf(p4i_ONE, 0);
75static Packet4ui p4ui_SIGN = {0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u};
76static Packet4ui p4ui_PREV0DOT5 = {0x3EFFFFFFu, 0x3EFFFFFFu, 0x3EFFFFFFu, 0x3EFFFFFFu};
78static Packet4f p4f_COUNTDOWN = { 0.0, 1.0, 2.0, 3.0 };
79static Packet4i p4i_COUNTDOWN = { 0, 1, 2, 3 };
81static Packet16uc p16uc_REVERSE32 = { 12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3 };
82static Packet16uc p16uc_DUPLICATE32_HI = { 0,1,2,3, 0,1,2,3, 4,5,6,7, 4,5,6,7 };
87static Packet16uc p16uc_FORWARD = vec_lvsl(0, (
float*)0);
89static Packet16uc p16uc_REVERSE64 = { 8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7 };
91static Packet16uc p16uc_PSET32_WODD = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 2), 8);
92static Packet16uc p16uc_PSET32_WEVEN = vec_sld(p16uc_DUPLICATE32_HI, (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);
93static Packet16uc p16uc_HALF64_0_16 = vec_sld((Packet16uc)p4i_ZERO, vec_splat((Packet16uc) vec_abs(p4i_MINUS16), 3), 8);
95static Packet16uc p16uc_FORWARD = p16uc_REVERSE32;
96static Packet16uc p16uc_REVERSE64 = { 8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7 };
97static Packet16uc p16uc_PSET32_WODD = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 1), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);
98static Packet16uc p16uc_PSET32_WEVEN = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 2), 8);
99static Packet16uc p16uc_HALF64_0_16 = vec_sld(vec_splat((Packet16uc) vec_abs(p4i_MINUS16), 0), (Packet16uc)p4i_ZERO, 8);
102static Packet16uc p16uc_PSET64_HI = (Packet16uc) vec_mergeh((Packet4ui)p16uc_PSET32_WODD, (Packet4ui)p16uc_PSET32_WEVEN);
103static Packet16uc p16uc_PSET64_LO = (Packet16uc) vec_mergel((Packet4ui)p16uc_PSET32_WODD, (Packet4ui)p16uc_PSET32_WEVEN);
104static Packet16uc p16uc_TRANSPOSE64_HI = p16uc_PSET64_HI + p16uc_HALF64_0_16;
105static Packet16uc p16uc_TRANSPOSE64_LO = p16uc_PSET64_LO + p16uc_HALF64_0_16;
107static Packet16uc p16uc_COMPLEX32_REV = vec_sld(p16uc_REVERSE32, p16uc_REVERSE32, 8);
110static Packet16uc p16uc_COMPLEX32_REV2 = vec_sld(p16uc_FORWARD, p16uc_FORWARD, 8);
112static Packet16uc p16uc_COMPLEX32_REV2 = vec_sld(p16uc_PSET64_HI, p16uc_PSET64_LO, 8);
115#if EIGEN_HAS_BUILTIN(__builtin_prefetch) || EIGEN_COMP_GNUC
116 #define EIGEN_PPC_PREFETCH(ADDR) __builtin_prefetch(ADDR);
118 #define EIGEN_PPC_PREFETCH(ADDR) asm( " dcbt [%[addr]]\n" :: [addr] "r" (ADDR) : "cc" );
121template<>
struct packet_traits<float> : default_packet_traits
123 typedef Packet4f type;
124 typedef Packet4f half;
160template<>
struct packet_traits<int> : default_packet_traits
162 typedef Packet4i type;
163 typedef Packet4i half;
179template<>
struct unpacket_traits<Packet4f> {
typedef float type;
enum {size=4, alignment=
Aligned16};
typedef Packet4f half; };
180template<>
struct unpacket_traits<Packet4i> {
typedef int type;
enum {size=4, alignment=
Aligned16};
typedef Packet4i half; };
182inline std::ostream & operator <<(std::ostream & s,
const Packet16uc & v)
189 for (
int i=0; i< 16; i++)
190 s << (
int)vt.n[i] <<
", ";
194inline std::ostream & operator <<(std::ostream & s,
const Packet4f & v)
201 s << vt.n[0] <<
", " << vt.n[1] <<
", " << vt.n[2] <<
", " << vt.n[3];
205inline std::ostream & operator <<(std::ostream & s,
const Packet4i & v)
212 s << vt.n[0] <<
", " << vt.n[1] <<
", " << vt.n[2] <<
", " << vt.n[3];
216inline std::ostream & operator <<(std::ostream & s,
const Packet4ui & v)
223 s << vt.n[0] <<
", " << vt.n[1] <<
", " << vt.n[2] <<
", " << vt.n[3];
227template <
typename Packet,
typename Scalar>
228EIGEN_STRONG_INLINE Packet pload_common(
const Scalar* from)
232 EIGEN_UNUSED_VARIABLE(from);
233 EIGEN_DEBUG_ALIGNED_LOAD
234 return vec_ld(0, from);
238template<> EIGEN_STRONG_INLINE Packet4f pload<Packet4f>(
const float* from)
240 return pload_common<Packet4f, float>(from);
243template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(
const int* from)
245 return pload_common<Packet4i, int>(from);
248template <
typename Packet>
249EIGEN_STRONG_INLINE
void pstore_common(__UNPACK_TYPE__(Packet)* to,
const Packet& from){
252 EIGEN_UNUSED_VARIABLE(to);
253 EIGEN_DEBUG_ALIGNED_STORE
255 vec_xst(from, 0, to);
261template<> EIGEN_STRONG_INLINE
void pstore<float>(
float* to,
const Packet4f& from)
263 pstore_common<Packet4f>(to, from);
266template<> EIGEN_STRONG_INLINE
void pstore<int>(
int* to,
const Packet4i& from)
268 pstore_common<Packet4i>(to, from);
271template<
typename Packet>
272EIGEN_STRONG_INLINE Packet pset1_size4(
const __UNPACK_TYPE__(Packet)& from)
274 Packet v = {from, from, from, from};
278template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(
const float& from) {
279 return pset1_size4<Packet4f>(from);
282template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(
const int& from) {
283 return pset1_size4<Packet4i>(from);
286template<
typename Packet> EIGEN_STRONG_INLINE
void
287pbroadcast4_common(
const __UNPACK_TYPE__(Packet) *a,
288 Packet& a0, Packet& a1, Packet& a2, Packet& a3)
290 a3 = pload<Packet>(a);
291 a0 = vec_splat(a3, 0);
292 a1 = vec_splat(a3, 1);
293 a2 = vec_splat(a3, 2);
294 a3 = vec_splat(a3, 3);
297template<> EIGEN_STRONG_INLINE
void
298pbroadcast4<Packet4f>(
const float *a,
299 Packet4f& a0, Packet4f& a1, Packet4f& a2, Packet4f& a3)
301 pbroadcast4_common<Packet4f>(a, a0, a1, a2, a3);
303template<> EIGEN_STRONG_INLINE
void
304pbroadcast4<Packet4i>(
const int *a,
305 Packet4i& a0, Packet4i& a1, Packet4i& a2, Packet4i& a3)
307 pbroadcast4_common<Packet4i>(a, a0, a1, a2, a3);
310template<
typename Packet> EIGEN_DEVICE_FUNC
inline Packet pgather_common(
const __UNPACK_TYPE__(Packet)* from,
Index stride)
312 EIGEN_ALIGN16 __UNPACK_TYPE__(Packet) a[4];
313 a[0] = from[0*stride];
314 a[1] = from[1*stride];
315 a[2] = from[2*stride];
316 a[3] = from[3*stride];
317 return pload<Packet>(a);
320template<> EIGEN_DEVICE_FUNC
inline Packet4f pgather<float, Packet4f>(
const float* from,
Index stride)
322 return pgather_common<Packet4f>(from, stride);
325template<> EIGEN_DEVICE_FUNC
inline Packet4i pgather<int, Packet4i>(
const int* from,
Index stride)
327 return pgather_common<Packet4i>(from, stride);
330template<
typename Packet> EIGEN_DEVICE_FUNC
inline void pscatter_size4(__UNPACK_TYPE__(Packet)* to,
const Packet& from,
Index stride)
332 EIGEN_ALIGN16 __UNPACK_TYPE__(Packet) a[4];
333 pstore<__UNPACK_TYPE__(Packet)>(a, from);
340template<> EIGEN_DEVICE_FUNC
inline void pscatter<float, Packet4f>(
float* to,
const Packet4f& from,
Index stride)
342 pscatter_size4<Packet4f>(to, from, stride);
345template<> EIGEN_DEVICE_FUNC
inline void pscatter<int, Packet4i>(
int* to,
const Packet4i& from,
Index stride)
347 pscatter_size4<Packet4i>(to, from, stride);
350template<> EIGEN_STRONG_INLINE Packet4f plset<Packet4f>(
const float& a) {
return pset1<Packet4f>(a) + p4f_COUNTDOWN; }
351template<> EIGEN_STRONG_INLINE Packet4i plset<Packet4i>(
const int& a) {
return pset1<Packet4i>(a) + p4i_COUNTDOWN; }
353template<> EIGEN_STRONG_INLINE Packet4f padd<Packet4f>(
const Packet4f& a,
const Packet4f& b) {
return a + b; }
354template<> EIGEN_STRONG_INLINE Packet4i padd<Packet4i>(
const Packet4i& a,
const Packet4i& b) {
return a + b; }
356template<> EIGEN_STRONG_INLINE Packet4f psub<Packet4f>(
const Packet4f& a,
const Packet4f& b) {
return a - b; }
357template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(
const Packet4i& a,
const Packet4i& b) {
return a - b; }
359template<> EIGEN_STRONG_INLINE Packet4f pnegate(
const Packet4f& a) {
return p4f_ZERO - a; }
360template<> EIGEN_STRONG_INLINE Packet4i pnegate(
const Packet4i& a) {
return p4i_ZERO - a; }
362template<> EIGEN_STRONG_INLINE Packet4f pconj(
const Packet4f& a) {
return a; }
363template<> EIGEN_STRONG_INLINE Packet4i pconj(
const Packet4i& a) {
return a; }
365template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(
const Packet4f& a,
const Packet4f& b) {
return vec_madd(a,b, p4f_MZERO); }
366template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(
const Packet4i& a,
const Packet4i& b) {
return a * b; }
368template<> EIGEN_STRONG_INLINE Packet4f pdiv<Packet4f>(
const Packet4f& a,
const Packet4f& b)
371 Packet4f t, y_0, y_1;
377 t = vec_nmsub(y_0, b, p4f_ONE);
378 y_1 = vec_madd(y_0, t, y_0);
380 return vec_madd(a, y_1, p4f_MZERO);
382 return vec_div(a, b);
386template<> EIGEN_STRONG_INLINE Packet4i pdiv<Packet4i>(
const Packet4i& ,
const Packet4i& )
387{ eigen_assert(
false &&
"packet integer division are not supported by AltiVec");
388 return pset1<Packet4i>(0);
392template<> EIGEN_STRONG_INLINE Packet4f pmadd(
const Packet4f& a,
const Packet4f& b,
const Packet4f& c) {
return vec_madd(a,b,c); }
393template<> EIGEN_STRONG_INLINE Packet4i pmadd(
const Packet4i& a,
const Packet4i& b,
const Packet4i& c) {
return a*b + c; }
395template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(
const Packet4f& a,
const Packet4f& b)
399 __asm__ (
"xvcmpgesp %x0,%x1,%x2\n\txxsel %x0,%x1,%x2,%x0" :
"=&wa" (ret) :
"wa" (a),
"wa" (b));
402 return vec_min(a, b);
405template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(
const Packet4i& a,
const Packet4i& b) {
return vec_min(a, b); }
407template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(
const Packet4f& a,
const Packet4f& b)
411 __asm__ (
"xvcmpgtsp %x0,%x2,%x1\n\txxsel %x0,%x1,%x2,%x0" :
"=&wa" (ret) :
"wa" (a),
"wa" (b));
414 return vec_max(a, b);
417template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(
const Packet4i& a,
const Packet4i& b) {
return vec_max(a, b); }
419template<> EIGEN_STRONG_INLINE Packet4f pand<Packet4f>(
const Packet4f& a,
const Packet4f& b) {
return vec_and(a, b); }
420template<> EIGEN_STRONG_INLINE Packet4i pand<Packet4i>(
const Packet4i& a,
const Packet4i& b) {
return vec_and(a, b); }
422template<> EIGEN_STRONG_INLINE Packet4f por<Packet4f>(
const Packet4f& a,
const Packet4f& b) {
return vec_or(a, b); }
423template<> EIGEN_STRONG_INLINE Packet4i por<Packet4i>(
const Packet4i& a,
const Packet4i& b) {
return vec_or(a, b); }
425template<> EIGEN_STRONG_INLINE Packet4f pxor<Packet4f>(
const Packet4f& a,
const Packet4f& b) {
return vec_xor(a, b); }
426template<> EIGEN_STRONG_INLINE Packet4i pxor<Packet4i>(
const Packet4i& a,
const Packet4i& b) {
return vec_xor(a, b); }
428template<> EIGEN_STRONG_INLINE Packet4f pandnot<Packet4f>(
const Packet4f& a,
const Packet4f& b) {
return vec_and(a, vec_nor(b, b)); }
429template<> EIGEN_STRONG_INLINE Packet4i pandnot<Packet4i>(
const Packet4i& a,
const Packet4i& b) {
return vec_and(a, vec_nor(b, b)); }
431template<> EIGEN_STRONG_INLINE Packet4f pround<Packet4f>(
const Packet4f& a)
433 Packet4f t = vec_add(
reinterpret_cast<Packet4f
>(vec_or(vec_and(
reinterpret_cast<Packet4ui
>(a), p4ui_SIGN), p4ui_PREV0DOT5)), a);
437 __asm__(
"xvrspiz %x0, %x1\n\t"
441 __asm__(
"vrfiz %0, %1\n\t"
448template<> EIGEN_STRONG_INLINE Packet4f pceil<Packet4f>(
const Packet4f& a) {
return vec_ceil(a); }
449template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(
const Packet4f& a) {
return vec_floor(a); }
451template<
typename Packet> EIGEN_STRONG_INLINE Packet ploadu_common(
const __UNPACK_TYPE__(Packet)* from)
453 EIGEN_DEBUG_UNALIGNED_LOAD
454 Packet16uc mask = vec_lvsl(0, from);
455 Packet16uc MSQ = vec_ld(0, (
unsigned char *)from);
456 Packet16uc LSQ = vec_ld(15, (
unsigned char *)from);
458 return (Packet) vec_perm(MSQ, LSQ, mask);
461template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(
const float* from)
463 return ploadu_common<Packet4f>(from);
465template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(
const int* from)
467 return ploadu_common<Packet4i>(from);
470template<
typename Packet> EIGEN_STRONG_INLINE Packet ploaddup_common(
const __UNPACK_TYPE__(Packet)* from)
473 if((std::ptrdiff_t(from) % 16) == 0) p = pload<Packet>(from);
474 else p = ploadu<Packet>(from);
475 return vec_perm(p, p, p16uc_DUPLICATE32_HI);
477template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(
const float* from)
479 return ploaddup_common<Packet4f>(from);
481template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(
const int* from)
483 return ploaddup_common<Packet4i>(from);
486template<
typename Packet> EIGEN_STRONG_INLINE
void pstoreu_common(__UNPACK_TYPE__(Packet)* to,
const Packet& from)
488 EIGEN_DEBUG_UNALIGNED_STORE
490 vec_xst(from, 0, to);
494 Packet16uc MSQ, LSQ, edges;
495 Packet16uc edgeAlign, align;
497 MSQ = vec_ld(0, (
unsigned char *)to);
498 LSQ = vec_ld(15, (
unsigned char *)to);
499 edgeAlign = vec_lvsl(0, to);
500 edges=vec_perm(LSQ,MSQ,edgeAlign);
501 align = vec_lvsr( 0, to );
502 MSQ = vec_perm(edges,(Packet16uc)from,align);
503 LSQ = vec_perm((Packet16uc)from,edges,align);
504 vec_st( LSQ, 15, (
unsigned char *)to );
505 vec_st( MSQ, 0, (
unsigned char *)to );
508template<> EIGEN_STRONG_INLINE
void pstoreu<float>(
float* to,
const Packet4f& from)
510 pstoreu_common<Packet4f>(to, from);
512template<> EIGEN_STRONG_INLINE
void pstoreu<int>(
int* to,
const Packet4i& from)
514 pstoreu_common<Packet4i>(to, from);
517template<> EIGEN_STRONG_INLINE
void prefetch<float>(
const float* addr) { EIGEN_PPC_PREFETCH(addr); }
518template<> EIGEN_STRONG_INLINE
void prefetch<int>(
const int* addr) { EIGEN_PPC_PREFETCH(addr); }
520template<> EIGEN_STRONG_INLINE
float pfirst<Packet4f>(
const Packet4f& a) { EIGEN_ALIGN16
float x; vec_ste(a, 0, &x);
return x; }
521template<> EIGEN_STRONG_INLINE
int pfirst<Packet4i>(
const Packet4i& a) { EIGEN_ALIGN16
int x; vec_ste(a, 0, &x);
return x; }
523template<> EIGEN_STRONG_INLINE Packet4f preverse(
const Packet4f& a)
525 return reinterpret_cast<Packet4f
>(vec_perm(
reinterpret_cast<Packet16uc
>(a),
reinterpret_cast<Packet16uc
>(a), p16uc_REVERSE32));
527template<> EIGEN_STRONG_INLINE Packet4i preverse(
const Packet4i& a)
529 return reinterpret_cast<Packet4i
>(vec_perm(
reinterpret_cast<Packet16uc
>(a),
reinterpret_cast<Packet16uc
>(a), p16uc_REVERSE32)); }
531template<> EIGEN_STRONG_INLINE Packet4f pabs(
const Packet4f& a) {
return vec_abs(a); }
532template<> EIGEN_STRONG_INLINE Packet4i pabs(
const Packet4i& a) {
return vec_abs(a); }
534template<> EIGEN_STRONG_INLINE
float predux<Packet4f>(
const Packet4f& a)
537 b = vec_sld(a, a, 8);
539 b = vec_sld(sum, sum, 4);
544template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(
const Packet4f* vecs)
546 Packet4f v[4], sum[4];
551 v[0] = vec_mergeh(vecs[0], vecs[2]);
552 v[1] = vec_mergel(vecs[0], vecs[2]);
553 v[2] = vec_mergeh(vecs[1], vecs[3]);
554 v[3] = vec_mergel(vecs[1], vecs[3]);
556 sum[0] = vec_mergeh(v[0], v[2]);
557 sum[1] = vec_mergel(v[0], v[2]);
558 sum[2] = vec_mergeh(v[1], v[3]);
559 sum[3] = vec_mergel(v[1], v[3]);
563 sum[0] = sum[0] + sum[1];
565 sum[1] = sum[2] + sum[3];
567 sum[0] = sum[0] + sum[1];
572template<> EIGEN_STRONG_INLINE
int predux<Packet4i>(
const Packet4i& a)
575 sum = vec_sums(a, p4i_ZERO);
577 sum = vec_sld(sum, p4i_ZERO, 12);
579 sum = vec_sld(p4i_ZERO, sum, 4);
584template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(
const Packet4i* vecs)
586 Packet4i v[4], sum[4];
591 v[0] = vec_mergeh(vecs[0], vecs[2]);
592 v[1] = vec_mergel(vecs[0], vecs[2]);
593 v[2] = vec_mergeh(vecs[1], vecs[3]);
594 v[3] = vec_mergel(vecs[1], vecs[3]);
596 sum[0] = vec_mergeh(v[0], v[2]);
597 sum[1] = vec_mergel(v[0], v[2]);
598 sum[2] = vec_mergeh(v[1], v[3]);
599 sum[3] = vec_mergel(v[1], v[3]);
603 sum[0] = sum[0] + sum[1];
605 sum[1] = sum[2] + sum[3];
607 sum[0] = sum[0] + sum[1];
614template<> EIGEN_STRONG_INLINE
float predux_mul<Packet4f>(
const Packet4f& a)
617 prod = pmul(a, vec_sld(a, a, 8));
618 return pfirst(pmul(prod, vec_sld(prod, prod, 4)));
621template<> EIGEN_STRONG_INLINE
int predux_mul<Packet4i>(
const Packet4i& a)
623 EIGEN_ALIGN16
int aux[4];
625 return aux[0] * aux[1] * aux[2] * aux[3];
629template<
typename Packet> EIGEN_STRONG_INLINE
630__UNPACK_TYPE__(Packet) predux_min4(
const Packet& a)
633 b = vec_min(a, vec_sld(a, a, 8));
634 res = vec_min(b, vec_sld(b, b, 4));
639template<> EIGEN_STRONG_INLINE
float predux_min<Packet4f>(
const Packet4f& a)
641 return predux_min4<Packet4f>(a);
644template<> EIGEN_STRONG_INLINE
int predux_min<Packet4i>(
const Packet4i& a)
646 return predux_min4<Packet4i>(a);
649template<
typename Packet> EIGEN_STRONG_INLINE __UNPACK_TYPE__(Packet) predux_max4(
const Packet& a)
652 b = vec_max(a, vec_sld(a, a, 8));
653 res = vec_max(b, vec_sld(b, b, 4));
657template<> EIGEN_STRONG_INLINE
float predux_max<Packet4f>(
const Packet4f& a)
659 return predux_max4<Packet4f>(a);
662template<> EIGEN_STRONG_INLINE
int predux_max<Packet4i>(
const Packet4i& a)
664 return predux_max4<Packet4i>(a);
668struct palign_impl<Offset,Packet4f>
670 static EIGEN_STRONG_INLINE
void run(Packet4f& first,
const Packet4f& second)
673 switch (Offset % 4) {
675 first = vec_sld(first, second, 4);
break;
677 first = vec_sld(first, second, 8);
break;
679 first = vec_sld(first, second, 12);
break;
682 switch (Offset % 4) {
684 first = vec_sld(second, first, 12);
break;
686 first = vec_sld(second, first, 8);
break;
688 first = vec_sld(second, first, 4);
break;
695struct palign_impl<Offset,Packet4i>
697 static EIGEN_STRONG_INLINE
void run(Packet4i& first,
const Packet4i& second)
700 switch (Offset % 4) {
702 first = vec_sld(first, second, 4);
break;
704 first = vec_sld(first, second, 8);
break;
706 first = vec_sld(first, second, 12);
break;
709 switch (Offset % 4) {
711 first = vec_sld(second, first, 12);
break;
713 first = vec_sld(second, first, 8);
break;
715 first = vec_sld(second, first, 4);
break;
722EIGEN_DEVICE_FUNC
inline void ptranpose_common(PacketBlock<T, 4>& kernel) {
724 t0 = vec_mergeh(kernel.packet[0], kernel.packet[2]);
725 t1 = vec_mergel(kernel.packet[0], kernel.packet[2]);
726 t2 = vec_mergeh(kernel.packet[1], kernel.packet[3]);
727 t3 = vec_mergel(kernel.packet[1], kernel.packet[3]);
728 kernel.packet[0] = vec_mergeh(t0, t2);
729 kernel.packet[1] = vec_mergel(t0, t2);
730 kernel.packet[2] = vec_mergeh(t1, t3);
731 kernel.packet[3] = vec_mergel(t1, t3);
734EIGEN_DEVICE_FUNC
inline void ptranspose(PacketBlock<Packet4f, 4>& kernel) { ptranpose_common<Packet4f>(kernel); }
736EIGEN_DEVICE_FUNC
inline void ptranspose(PacketBlock<Packet4i, 4>& kernel) { ptranpose_common<Packet4i>(kernel); }
738template<
typename Packet> EIGEN_STRONG_INLINE
739Packet pblend4(
const Selector<4>& ifPacket,
const Packet& thenPacket,
const Packet& elsePacket) {
740 Packet4ui select = { ifPacket.select[0], ifPacket.select[1], ifPacket.select[2], ifPacket.select[3] };
741 Packet4ui mask =
reinterpret_cast<Packet4ui
>(vec_cmpeq(
reinterpret_cast<Packet4ui
>(select),
reinterpret_cast<Packet4ui
>(p4i_ONE)));
742 return vec_sel(elsePacket, thenPacket, mask);
745template<> EIGEN_STRONG_INLINE Packet4i pblend(
const Selector<4>& ifPacket,
const Packet4i& thenPacket,
const Packet4i& elsePacket) {
746 return pblend4<Packet4i>(ifPacket, thenPacket, elsePacket);
749template<> EIGEN_STRONG_INLINE Packet4f pblend(
const Selector<4>& ifPacket,
const Packet4f& thenPacket,
const Packet4f& elsePacket) {
750 return pblend4<Packet4f>(ifPacket, thenPacket, elsePacket);
756typedef __vector
double Packet2d;
757typedef __vector
unsigned long long Packet2ul;
758typedef __vector
long long Packet2l;
760typedef Packet2ul Packet2bl;
762typedef __vector __bool
long Packet2bl;
765static Packet2l p2l_ONE = { 1, 1 };
766static Packet2l p2l_ZERO =
reinterpret_cast<Packet2l
>(p4i_ZERO);
767static Packet2d p2d_ONE = { 1.0, 1.0 };
768static Packet2d p2d_ZERO =
reinterpret_cast<Packet2d
>(p4f_ZERO);
769static Packet2d p2d_MZERO = { -0.0, -0.0 };
770static Packet2ul p2ul_SIGN = {0x8000000000000000ull, 0x8000000000000000ull};
771static Packet2ul p2ul_PREV0DOT5 = {0x3FDFFFFFFFFFFFFFull, 0x3FDFFFFFFFFFFFFFull};
774static Packet2d p2d_COUNTDOWN =
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4f
>(p2d_ZERO),
reinterpret_cast<Packet4f
>(p2d_ONE), 8));
776static Packet2d p2d_COUNTDOWN =
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4f
>(p2d_ONE),
reinterpret_cast<Packet4f
>(p2d_ZERO), 8));
779template<
int index> Packet2d vec_splat_dbl(Packet2d& a)
781 return vec_splat(a, index);
784template<>
struct packet_traits<double> : default_packet_traits
786 typedef Packet2d type;
787 typedef Packet2d half;
819template<>
struct unpacket_traits<Packet2d> {
typedef double type;
enum {size=2, alignment=
Aligned16};
typedef Packet2d half; };
821inline std::ostream & operator <<(std::ostream & s,
const Packet2l & v)
828 s << vt.n[0] <<
", " << vt.n[1];
832inline std::ostream & operator <<(std::ostream & s,
const Packet2d & v)
839 s << vt.n[0] <<
", " << vt.n[1];
844template<> EIGEN_STRONG_INLINE Packet2d pload<Packet2d>(
const double* from)
846 EIGEN_DEBUG_ALIGNED_LOAD
847 return vec_xl(0,
const_cast<double *
>(from));
850template<> EIGEN_STRONG_INLINE
void pstore<double>(
double* to,
const Packet2d& from)
852 EIGEN_DEBUG_ALIGNED_STORE
853 vec_xst(from, 0, to);
856template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(
const double& from) {
857 Packet2d v = {from, from};
861template<> EIGEN_STRONG_INLINE
void
862pbroadcast4<Packet2d>(
const double *a,
863 Packet2d& a0, Packet2d& a1, Packet2d& a2, Packet2d& a3)
866 a0 = pset1<Packet2d>(a[0]);
867 a1 = pset1<Packet2d>(a[1]);
868 a2 = pset1<Packet2d>(a[2]);
869 a3 = pset1<Packet2d>(a[3]);
872template<> EIGEN_DEVICE_FUNC
inline Packet2d pgather<double, Packet2d>(
const double* from,
Index stride)
874 EIGEN_ALIGN16
double af[2];
875 af[0] = from[0*stride];
876 af[1] = from[1*stride];
877 return pload<Packet2d>(af);
879template<> EIGEN_DEVICE_FUNC
inline void pscatter<double, Packet2d>(
double* to,
const Packet2d& from,
Index stride)
881 EIGEN_ALIGN16
double af[2];
882 pstore<double>(af, from);
883 to[0*stride] = af[0];
884 to[1*stride] = af[1];
887template<> EIGEN_STRONG_INLINE Packet2d plset<Packet2d>(
const double& a) {
return pset1<Packet2d>(a) + p2d_COUNTDOWN; }
889template<> EIGEN_STRONG_INLINE Packet2d padd<Packet2d>(
const Packet2d& a,
const Packet2d& b) {
return a + b; }
891template<> EIGEN_STRONG_INLINE Packet2d psub<Packet2d>(
const Packet2d& a,
const Packet2d& b) {
return a - b; }
893template<> EIGEN_STRONG_INLINE Packet2d pnegate(
const Packet2d& a)
895#ifdef __POWER8_VECTOR__
898 return vec_xor(a, p2d_MZERO);
902template<> EIGEN_STRONG_INLINE Packet2d pconj(
const Packet2d& a) {
return a; }
904template<> EIGEN_STRONG_INLINE Packet2d pmul<Packet2d>(
const Packet2d& a,
const Packet2d& b) {
return vec_madd(a,b,p2d_MZERO); }
905template<> EIGEN_STRONG_INLINE Packet2d pdiv<Packet2d>(
const Packet2d& a,
const Packet2d& b) {
return vec_div(a,b); }
908template<> EIGEN_STRONG_INLINE Packet2d pmadd(
const Packet2d& a,
const Packet2d& b,
const Packet2d& c) {
return vec_madd(a, b, c); }
910template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(
const Packet2d& a,
const Packet2d& b)
913 __asm__ (
"xvcmpgedp %x0,%x1,%x2\n\txxsel %x0,%x1,%x2,%x0" :
"=&wa" (ret) :
"wa" (a),
"wa" (b));
917template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(
const Packet2d& a,
const Packet2d& b)
920 __asm__ (
"xvcmpgtdp %x0,%x2,%x1\n\txxsel %x0,%x1,%x2,%x0" :
"=&wa" (ret) :
"wa" (a),
"wa" (b));
924template<> EIGEN_STRONG_INLINE Packet2d pand<Packet2d>(
const Packet2d& a,
const Packet2d& b) {
return vec_and(a, b); }
926template<> EIGEN_STRONG_INLINE Packet2d por<Packet2d>(
const Packet2d& a,
const Packet2d& b) {
return vec_or(a, b); }
928template<> EIGEN_STRONG_INLINE Packet2d pxor<Packet2d>(
const Packet2d& a,
const Packet2d& b) {
return vec_xor(a, b); }
930template<> EIGEN_STRONG_INLINE Packet2d pandnot<Packet2d>(
const Packet2d& a,
const Packet2d& b) {
return vec_and(a, vec_nor(b, b)); }
932template<> EIGEN_STRONG_INLINE Packet2d pround<Packet2d>(
const Packet2d& a)
934 Packet2d t = vec_add(
reinterpret_cast<Packet2d
>(vec_or(vec_and(
reinterpret_cast<Packet2ul
>(a), p2ul_SIGN), p2ul_PREV0DOT5)), a);
937 __asm__(
"xvrdpiz %x0, %x1\n\t"
943template<> EIGEN_STRONG_INLINE Packet2d pceil<Packet2d>(
const Packet2d& a) {
return vec_ceil(a); }
944template<> EIGEN_STRONG_INLINE Packet2d pfloor<Packet2d>(
const Packet2d& a) {
return vec_floor(a); }
946template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(
const double* from)
948 EIGEN_DEBUG_UNALIGNED_LOAD
949 return vec_xl(0,
const_cast<double*
>(from));
952template<> EIGEN_STRONG_INLINE Packet2d ploaddup<Packet2d>(
const double* from)
955 if((std::ptrdiff_t(from) % 16) == 0) p = pload<Packet2d>(from);
956 else p = ploadu<Packet2d>(from);
957 return vec_splat_dbl<0>(p);
960template<> EIGEN_STRONG_INLINE
void pstoreu<double>(
double* to,
const Packet2d& from)
962 EIGEN_DEBUG_UNALIGNED_STORE
963 vec_xst(from, 0, to);
966template<> EIGEN_STRONG_INLINE
void prefetch<double>(
const double* addr) { EIGEN_PPC_PREFETCH(addr); }
968template<> EIGEN_STRONG_INLINE
double pfirst<Packet2d>(
const Packet2d& a) { EIGEN_ALIGN16
double x[2]; pstore<double>(x, a);
return x[0]; }
970template<> EIGEN_STRONG_INLINE Packet2d preverse(
const Packet2d& a)
972 return reinterpret_cast<Packet2d
>(vec_perm(
reinterpret_cast<Packet16uc
>(a),
reinterpret_cast<Packet16uc
>(a), p16uc_REVERSE64));
974template<> EIGEN_STRONG_INLINE Packet2d pabs(
const Packet2d& a) {
return vec_abs(a); }
976template<> EIGEN_STRONG_INLINE
double predux<Packet2d>(
const Packet2d& a)
979 b =
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4f
>(a),
reinterpret_cast<Packet4f
>(a), 8));
981 return pfirst<Packet2d>(sum);
984template<> EIGEN_STRONG_INLINE Packet2d preduxp<Packet2d>(
const Packet2d* vecs)
987 v[0] = vecs[0] +
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4f
>(vecs[0]),
reinterpret_cast<Packet4f
>(vecs[0]), 8));
988 v[1] = vecs[1] +
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4f
>(vecs[1]),
reinterpret_cast<Packet4f
>(vecs[1]), 8));
991 sum =
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4f
>(v[0]),
reinterpret_cast<Packet4f
>(v[1]), 8));
993 sum =
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4f
>(v[1]),
reinterpret_cast<Packet4f
>(v[0]), 8));
1000template<> EIGEN_STRONG_INLINE
double predux_mul<Packet2d>(
const Packet2d& a)
1002 return pfirst(pmul(a,
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4ui
>(a),
reinterpret_cast<Packet4ui
>(a), 8))));
1006template<> EIGEN_STRONG_INLINE
double predux_min<Packet2d>(
const Packet2d& a)
1008 return pfirst(pmin(a,
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4ui
>(a),
reinterpret_cast<Packet4ui
>(a), 8))));
1012template<> EIGEN_STRONG_INLINE
double predux_max<Packet2d>(
const Packet2d& a)
1014 return pfirst(pmax(a,
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4ui
>(a),
reinterpret_cast<Packet4ui
>(a), 8))));
1018struct palign_impl<Offset,Packet2d>
1020 static EIGEN_STRONG_INLINE
void run(Packet2d& first,
const Packet2d& second)
1024 first =
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4ui
>(first),
reinterpret_cast<Packet4ui
>(second), 8));
1026 first =
reinterpret_cast<Packet2d
>(vec_sld(
reinterpret_cast<Packet4ui
>(second),
reinterpret_cast<Packet4ui
>(first), 8));
1031EIGEN_DEVICE_FUNC
inline void
1032ptranspose(PacketBlock<Packet2d,2>& kernel) {
1034 t0 = vec_perm(kernel.packet[0], kernel.packet[1], p16uc_TRANSPOSE64_HI);
1035 t1 = vec_perm(kernel.packet[0], kernel.packet[1], p16uc_TRANSPOSE64_LO);
1036 kernel.packet[0] = t0;
1037 kernel.packet[1] = t1;
1040template<> EIGEN_STRONG_INLINE Packet2d pblend(
const Selector<2>& ifPacket,
const Packet2d& thenPacket,
const Packet2d& elsePacket) {
1041 Packet2l select = { ifPacket.select[0], ifPacket.select[1] };
1042 Packet2bl mask =
reinterpret_cast<Packet2bl
>( vec_cmpeq(
reinterpret_cast<Packet2d
>(select),
reinterpret_cast<Packet2d
>(p2l_ONE)) );
1043 return vec_sel(elsePacket, thenPacket, mask);
@ Aligned16
Definition Constants.h:230
Namespace containing all symbols from the Eigen library.
Definition A05_PortingFrom2To3.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:65