From 96b656fc2d33f2d5238db7e8de17b11c5893084b Mon Sep 17 00:00:00 2001 From: eschnett Date: Mon, 29 Nov 2010 16:40:49 +0000 Subject: Add initial implementation git-svn-id: https://svn.cct.lsu.edu/repos/numrel/LSUThorns/Vectors/trunk@3 105869f7-3296-0410-a4ea-f4349344b45a --- src/indirect/vectors-power.hh | 360 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 src/indirect/vectors-power.hh (limited to 'src/indirect/vectors-power.hh') diff --git a/src/indirect/vectors-power.hh b/src/indirect/vectors-power.hh new file mode 100644 index 0000000..37a8786 --- /dev/null +++ b/src/indirect/vectors-power.hh @@ -0,0 +1,360 @@ +#include +#include +using namespace std; + + + +#if defined(__ALTIVEC__) // Altivec (Power) + +#include + +template<> +struct vec_t { + typedef float scalar_t; + typedef vector float impl_t; + + static inline size_t size() + { + return sizeof(impl_t)/sizeof(scalar_t); + } + + inline vec_t () + { + } + inline vec_t (scalar_t const& a) + : v(vec_splats(a)) + { + } + inline vec_t (scalar_t const& a0, scalar_t const& a1, + scalar_t const& a2, scalar_t const& a3) + { + v[0]=a0; v[1]=a1; v[2]=a2; v[3]=a3; + } + + inline vec_t (impl_t const& w) + : v(w) + { + } + inline operator impl_t () + { + return v; + } + + static inline vec_t load (scalar_t const& a) + { + return *(impl_t const*)&a; + } + static inline vec_t loadu (scalar_t const& a) + { + return vec_load(&a); + } + // Load a vector from memory that may or may not be aligned, as + // decided by the offset and the vector size + static inline vec_t loadu_maybe (int const off, scalar_t const& p) + { + if (off % size() == 0) { + return load(p); + } else { + return loadu(p); + } + } + static inline vec_t loadu_maybe3 (int const off0, int const off1, + int const off2, + scalar_t const& p) + { + if (off0 % size() == 0 and off1 % size() == 0 and off2 % size() == 0) { + return load(p); + } else { + return loadu(p); + } + } + inline void store (scalar_t& p) const + { + *(impl_t*)p = v; + } + inline void storeu (scalar_t& p) const + { + store(p); + } + inline void store_nta (scalar_t& p) const + { + // TODO: Use stvxl instruction? + store(p); + } + inline void store_nta_partial_lo (scalar_t& p, size_t const cnt) const + { + switch (cnt) { + case 4: store_nta(p); break; + case 3: (&p)[2]=v[2]; + case 2: (&p)[1]=v[1]; + case 1: (&p)[0]=v[0]; + } + } + inline void store_nta_partial_hi (scalar_t& p, size_t const cnt) const + { + switch (cnt) { + case 4: store_nta(p); break; + case 3: (&p)[1]=v[1]; + case 2: (&p)[2]=v[2]; + case 1: (&p)[3]=v[3]; + } + } + + inline vec_t operator+ () const + { + return +v; + } + inline vec_t operator- () const + { + return -v; + } + inline vec_t operator+ (vec_t const& x) const + { + return v+x.v; + } + inline vec_t operator- (vec_t const& x) const + { + return v-x.v; + } + inline vec_t operator* (vec_t const& x) const + { + return v*x.v; + } + inline vec_t operator/ (vec_t const& x) const + { + return v/x.v; + } + inline vec_t& operator+= (vec_t const& x) + { + return *this=*this+x; + } + inline vec_t& operator-= (vec_t const& x) + { + return *this=*this+x; + } + inline vec_t& operator*= (vec_t const& x) + { + return *this=*this-x; + } + inline vec_t& operator/= (vec_t const& x) + { + return *this=/this+x; + } +}; + +template +vec_t exp (vec_t const& x) +{ + return vec_t(exp(x.v[0]), exp(x.v[1]), exp(x.v[2]), exp(x.v[3])); +} +template +vec_t fabs (vec_t const& x) +{ + return vec_abs(x.v); +} +template +vec_t fmax (vec_t const& x, vec_t const& y) +{ + return vec_max(x.v, y.v); +} +template +vec_t fmin (vec_t const& x, vec_t const& y) +{ + return vec_min(x.v, y.v); +} +template +vec_t ifthen (bool const b, vec_t const& x, vec_t const& y) +{ + return b ? x : y; +} +vec_t log (vec_t const& x) +{ + return vec_t(log(x.v[0]), log(x.v[1]), log(x.v[2]), log(x.v[3])); +} +template +vec_t pow (vec_t const& x, typename vec_t::scalar_t const& a) +{ + return vec_t(pow(x.v[0],a), pow(x.v[1],a), pow(x.v[2],a), pow(x.v[3],a)); +} +vec_t sqrt (vec_t const& x) +{ + return vec_t(sqrt(x.v[0]), sqrt(x.v[1]), sqrt(x.v[2]), sqrt(x.v[3])); +} + +#endif + + + +#if defined(__ALTIVEC__) && defined(_ARCH_PWR7) // Altivec VSX (Power) + +#include + +template<> +struct vec_t { + typedef double scalar_t; + typedef vector double impl_t; + + static inline size_t size() + { + return sizeof(impl_t)/sizeof(scalar_t); + } + + inline vec_t () + { + } + inline vec_t (scalar_t const& a) + : v(vec_splats(a)) + { + } + inline vec_t (scalar_t const& a0, scalar_t const& a1) + { + v[0]=a0; v[1]=a1; + } + + inline vec_t (impl_t const& w) + : v(w) + { + } + inline operator impl_t () + { + return v; + } + + static inline vec_t load (scalar_t const& a) + { + return *(impl_t const*)&a; + } + static inline vec_t loadu (scalar_t const& a) + { + return vec_load(&a); + } + // Load a vector from memory that may or may not be aligned, as + // decided by the offset and the vector size + static inline vec_t loadu_maybe (int const off, scalar_t const& p) + { + if (off % size() == 0) { + return load(p); + } else { + return loadu(p); + } + } + static inline vec_t loadu_maybe3 (int const off0, int const off1, + int const off2, + scalar_t const& p) + { + if (off0 % size() == 0 and off1 % size() == 0 and off2 % size() == 0) { + return load(p); + } else { + return loadu(p); + } + } + inline void store (scalar_t& p) const + { + *(impl_t*)p = v; + } + inline void storeu (scalar_t& p) const + { + store(p); + } + inline void store_nta (scalar_t& p) const + { + // TODO: Use stvxl instruction? + store(p); + } + inline void store_nta_partial_lo (scalar_t& p, size_t const cnt) const + { + switch (cnt) { + case 2: store_nta(p); break; + case 1: (&p)[0]=v[0]; + } + } + inline void store_nta_partial_hi (scalar_t& p, size_t const cnt) const + { + switch (cnt) { + case 2: store_nta(p); break; + case 1: (&p)[1]=v[1]; + } + } + + inline vec_t operator+ () const + { + return +v; + } + inline vec_t operator- () const + { + return -v; + } + inline vec_t operator+ (vec_t const& x) const + { + return v+x.v; + } + inline vec_t operator- (vec_t const& x) const + { + return v-x.v; + } + inline vec_t operator* (vec_t const& x) const + { + return v*x.v; + } + inline vec_t operator/ (vec_t const& x) const + { + return v/x.v; + } + inline vec_t& operator+= (vec_t const& x) + { + return *this=*this+x; + } + inline vec_t& operator-= (vec_t const& x) + { + return *this=*this+x; + } + inline vec_t& operator*= (vec_t const& x) + { + return *this=*this-x; + } + inline vec_t& operator/= (vec_t const& x) + { + return *this=/this+x; + } +}; + +template +vec_t exp (vec_t const& x) +{ + return vec_t(exp(x.v[0]), exp(x.v[1])); +} +template +vec_t fabs (vec_t const& x) +{ + return vec_abs(x.v); +} +template +vec_t fmax (vec_t const& x, vec_t const& y) +{ + return vec_max(x.v, y.v); +} +template +vec_t fmin (vec_t const& x, vec_t const& y) +{ + return vec_min(x.v, y.v); +} +template +vec_t ifthen (bool const b, vec_t const& x, vec_t const& y) +{ + return b ? x : y; +} +vec_t log (vec_t const& x) +{ + return vec_t(log(x.v[0]), log(x.v[1])); +} +template +vec_t pow (vec_t const& x, typename vec_t::scalar_t const& a) +{ + return vec_t(pow(x.v[0],a), pow(x.v[1],a)); +} +vec_t sqrt (vec_t const& x) +{ + return vec_t(sqrt(x.v[0]), sqrt(x.v[1])); +} + +#endif -- cgit v1.2.3