#undef isnan
#endif
+namespace AliRoot {
namespace Vc
{
namespace AVX
typedef Vc::Memory<Vector<T>, Size> Memory;
#ifdef VC_PASSING_VECTOR_BY_VALUE_IS_BROKEN
typedef const Vector<T> &AsArg;
+ typedef const VectorType &VectorTypeArg;
#else
typedef Vector<T> AsArg;
+ typedef VectorType VectorTypeArg;
#endif
protected:
typedef VectorHelper<T> HT;
// cast any m256/m128 to VectorType
- static inline VectorType INTRINSIC _cast(__m128 v) { return avx_cast<VectorType>(v); }
- static inline VectorType INTRINSIC _cast(__m128i v) { return avx_cast<VectorType>(v); }
- static inline VectorType INTRINSIC _cast(__m128d v) { return avx_cast<VectorType>(v); }
- static inline VectorType INTRINSIC _cast(__m256 v) { return avx_cast<VectorType>(v); }
- static inline VectorType INTRINSIC _cast(__m256i v) { return avx_cast<VectorType>(v); }
- static inline VectorType INTRINSIC _cast(__m256d v) { return avx_cast<VectorType>(v); }
-
+ static Vc_INTRINSIC VectorType _cast(param128 v) { return avx_cast<VectorType>(v); }
+ static Vc_INTRINSIC VectorType _cast(param128i v) { return avx_cast<VectorType>(v); }
+ static Vc_INTRINSIC VectorType _cast(param128d v) { return avx_cast<VectorType>(v); }
+ static Vc_INTRINSIC VectorType _cast(param256 v) { return avx_cast<VectorType>(v); }
+ static Vc_INTRINSIC VectorType _cast(param256i v) { return avx_cast<VectorType>(v); }
+ static Vc_INTRINSIC VectorType _cast(param256d v) { return avx_cast<VectorType>(v); }
+
+#ifdef VC_UNCONDITIONAL_AVX2_INTRINSICS
+ typedef Common::VectorMemoryUnion<VectorType, EntryType, typename VectorType::Base> StorageType;
+#else
typedef Common::VectorMemoryUnion<VectorType, EntryType> StorageType;
+#endif
StorageType d;
public:
///////////////////////////////////////////////////////////////////////////////////////////
// uninitialized
- inline Vector() {}
+ Vc_ALWAYS_INLINE Vector() {}
///////////////////////////////////////////////////////////////////////////////////////////
// constants
- explicit Vector(VectorSpecialInitializerZero::ZEnum);
- explicit Vector(VectorSpecialInitializerOne::OEnum);
- explicit Vector(VectorSpecialInitializerIndexesFromZero::IEnum);
- static Vector Zero();
- static Vector One();
- static Vector IndexesFromZero();
- static Vector Random();
+ explicit Vc_ALWAYS_INLINE_L Vector(VectorSpecialInitializerZero::ZEnum) Vc_ALWAYS_INLINE_R;
+ explicit Vc_ALWAYS_INLINE_L Vector(VectorSpecialInitializerOne::OEnum) Vc_ALWAYS_INLINE_R;
+ explicit Vc_ALWAYS_INLINE_L Vector(VectorSpecialInitializerIndexesFromZero::IEnum) Vc_ALWAYS_INLINE_R;
+ static Vc_INTRINSIC_L Vc_CONST_L Vector Zero() Vc_INTRINSIC_R Vc_CONST_R;
+ static Vc_INTRINSIC_L Vc_CONST_L Vector One() Vc_INTRINSIC_R Vc_CONST_R;
+ static Vc_INTRINSIC_L Vc_CONST_L Vector IndexesFromZero() Vc_INTRINSIC_R Vc_CONST_R;
+ static Vc_ALWAYS_INLINE_L Vector Random() Vc_ALWAYS_INLINE_R;
///////////////////////////////////////////////////////////////////////////////////////////
// internal: required to enable returning objects of VectorType
- inline Vector(const VectorType &x) : d(x) {}
+ Vc_ALWAYS_INLINE Vector(VectorTypeArg x) : d(x) {}
+#ifdef VC_UNCONDITIONAL_AVX2_INTRINSICS
+ Vc_ALWAYS_INLINE Vector(typename VectorType::Base x) : d(x) {}
+#endif
///////////////////////////////////////////////////////////////////////////////////////////
// static_cast / copy ctor
- template<typename T2> explicit Vector(Vector<T2> x);
+ template<typename T2> explicit Vector(VC_ALIGNED_PARAMETER(Vector<T2>) x);
// implicit cast
- template<typename OtherT> inline INTRINSIC_L Vector &operator=(const Vector<OtherT> &x) INTRINSIC_R;
+ template<typename OtherT> Vc_INTRINSIC_L Vector &operator=(const Vector<OtherT> &x) Vc_INTRINSIC_R;
// copy assignment
- inline Vector &operator=(AsArg v) { d.v() = v.d.v(); return *this; }
+ Vc_ALWAYS_INLINE Vector &operator=(AsArg v) { d.v() = v.d.v(); return *this; }
///////////////////////////////////////////////////////////////////////////////////////////
// broadcast
- explicit Vector(EntryType a);
- template<typename TT> inline INTRINSIC Vector(TT x, VC_EXACT_TYPE(TT, EntryType, void *) = 0) : d(HT::set(x)) {}
- inline Vector &operator=(EntryType a) { d.v() = HT::set(a); return *this; }
+ explicit Vc_ALWAYS_INLINE_L Vector(EntryType a) Vc_ALWAYS_INLINE_R;
+ template<typename TT> Vc_INTRINSIC Vector(TT x, VC_EXACT_TYPE(TT, EntryType, void *) = 0) : d(HT::set(x)) {}
+ Vc_ALWAYS_INLINE Vector &operator=(EntryType a) { d.v() = HT::set(a); return *this; }
///////////////////////////////////////////////////////////////////////////////////////////
// load ctors
- explicit inline INTRINSIC_L
- Vector(const EntryType *x) INTRINSIC_R;
- template<typename Alignment> inline INTRINSIC_L
- Vector(const EntryType *x, Alignment align) INTRINSIC_R;
- template<typename OtherT> explicit inline INTRINSIC_L
- Vector(const OtherT *x) INTRINSIC_R;
- template<typename OtherT, typename Alignment> inline INTRINSIC_L
- Vector(const OtherT *x, Alignment align) INTRINSIC_R;
+ explicit Vc_INTRINSIC_L
+ Vector(const EntryType *x) Vc_INTRINSIC_R;
+ template<typename Alignment> Vc_INTRINSIC_L
+ Vector(const EntryType *x, Alignment align) Vc_INTRINSIC_R;
+ template<typename OtherT> explicit Vc_INTRINSIC_L
+ Vector(const OtherT *x) Vc_INTRINSIC_R;
+ template<typename OtherT, typename Alignment> Vc_INTRINSIC_L
+ Vector(const OtherT *x, Alignment align) Vc_INTRINSIC_R;
///////////////////////////////////////////////////////////////////////////////////////////
// load member functions
- inline INTRINSIC_L
- void load(const EntryType *mem) INTRINSIC_R;
- template<typename Alignment> inline INTRINSIC_L
- void load(const EntryType *mem, Alignment align) INTRINSIC_R;
- template<typename OtherT> inline INTRINSIC_L
- void load(const OtherT *mem) INTRINSIC_R;
- template<typename OtherT, typename Alignment> inline INTRINSIC_L
- void load(const OtherT *mem, Alignment align) INTRINSIC_R;
+ Vc_INTRINSIC_L
+ void load(const EntryType *mem) Vc_INTRINSIC_R;
+ template<typename Alignment> Vc_INTRINSIC_L
+ void load(const EntryType *mem, Alignment align) Vc_INTRINSIC_R;
+ template<typename OtherT> Vc_INTRINSIC_L
+ void load(const OtherT *mem) Vc_INTRINSIC_R;
+ template<typename OtherT, typename Alignment> Vc_INTRINSIC_L
+ void load(const OtherT *mem, Alignment align) Vc_INTRINSIC_R;
///////////////////////////////////////////////////////////////////////////////////////////
// expand/merge 1 float_v <=> 2 double_v XXX rationale? remove it for release? XXX
///////////////////////////////////////////////////////////////////////////////////////////
// zeroing
- inline void setZero();
- inline void setZero(const Mask &k);
+ Vc_INTRINSIC_L void setZero() Vc_INTRINSIC_R;
+ Vc_INTRINSIC_L void setZero(const Mask &k) Vc_INTRINSIC_R;
- void setQnan();
- void setQnan(MaskArg k);
+ Vc_INTRINSIC_L void setQnan() Vc_INTRINSIC_R;
+ Vc_INTRINSIC_L void setQnan(MaskArg k) Vc_INTRINSIC_R;
///////////////////////////////////////////////////////////////////////////////////////////
// stores
- inline void store(EntryType *mem) const;
- inline void store(EntryType *mem, const Mask &mask) const;
- template<typename A> inline void store(EntryType *mem, A align) const;
- template<typename A> inline void store(EntryType *mem, const Mask &mask, A align) const;
+ Vc_INTRINSIC_L void store(EntryType *mem) const Vc_INTRINSIC_R;
+ Vc_INTRINSIC_L void store(EntryType *mem, const Mask &mask) const Vc_INTRINSIC_R;
+ template<typename A> Vc_INTRINSIC_L void store(EntryType *mem, A align) const Vc_INTRINSIC_R;
+ template<typename A> Vc_INTRINSIC_L void store(EntryType *mem, const Mask &mask, A align) const Vc_INTRINSIC_R;
///////////////////////////////////////////////////////////////////////////////////////////
// swizzles
- inline const Vector<T> INTRINSIC_L CONST_L &abcd() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L cdab() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L badc() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L aaaa() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L bbbb() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L cccc() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L dddd() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L bcad() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L bcda() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L dabc() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L acbd() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L dbca() const INTRINSIC_R CONST_R;
- inline const Vector<T> INTRINSIC_L CONST_L dcba() const INTRINSIC_R CONST_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> &abcd() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> cdab() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> badc() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> aaaa() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> bbbb() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> cccc() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> dddd() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> bcad() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> bcda() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> dabc() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> acbd() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> dbca() const Vc_INTRINSIC_R Vc_PURE_R;
+ Vc_INTRINSIC_L Vc_PURE_L const Vector<T> dcba() const Vc_INTRINSIC_R Vc_PURE_R;
///////////////////////////////////////////////////////////////////////////////////////////
// gathers
template<typename IndexT> Vector(const EntryType *mem, const IndexT *indexes);
- template<typename IndexT> Vector(const EntryType *mem, Vector<IndexT> indexes);
+ template<typename IndexT> Vector(const EntryType *mem, VC_ALIGNED_PARAMETER(Vector<IndexT>) indexes);
template<typename IndexT> Vector(const EntryType *mem, const IndexT *indexes, MaskArg mask);
- template<typename IndexT> Vector(const EntryType *mem, Vector<IndexT> indexes, MaskArg mask);
- template<typename S1, typename IT> Vector(const S1 *array, const EntryType S1::* member1, IT indexes);
- template<typename S1, typename IT> Vector(const S1 *array, const EntryType S1::* member1, IT indexes, MaskArg mask);
- template<typename S1, typename S2, typename IT> Vector(const S1 *array, const S2 S1::* member1, const EntryType S2::* member2, IT indexes);
- template<typename S1, typename S2, typename IT> Vector(const S1 *array, const S2 S1::* member1, const EntryType S2::* member2, IT indexes, MaskArg mask);
- template<typename S1, typename IT1, typename IT2> Vector(const S1 *array, const EntryType *const S1::* ptrMember1, IT1 outerIndexes, IT2 innerIndexes);
- template<typename S1, typename IT1, typename IT2> Vector(const S1 *array, const EntryType *const S1::* ptrMember1, IT1 outerIndexes, IT2 innerIndexes, MaskArg mask);
- template<typename Index> void gather(const EntryType *mem, Index indexes);
- template<typename Index> void gather(const EntryType *mem, Index indexes, MaskArg mask);
+ template<typename IndexT> Vector(const EntryType *mem, VC_ALIGNED_PARAMETER(Vector<IndexT>) indexes, MaskArg mask);
+ template<typename S1, typename IT> Vector(const S1 *array, const EntryType S1::* member1, VC_ALIGNED_PARAMETER(IT) indexes);
+ template<typename S1, typename IT> Vector(const S1 *array, const EntryType S1::* member1, VC_ALIGNED_PARAMETER(IT) indexes, MaskArg mask);
+ template<typename S1, typename S2, typename IT> Vector(const S1 *array, const S2 S1::* member1, const EntryType S2::* member2, VC_ALIGNED_PARAMETER(IT) indexes);
+ template<typename S1, typename S2, typename IT> Vector(const S1 *array, const S2 S1::* member1, const EntryType S2::* member2, VC_ALIGNED_PARAMETER(IT) indexes, MaskArg mask);
+ template<typename S1, typename IT1, typename IT2> Vector(const S1 *array, const EntryType *const S1::* ptrMember1, VC_ALIGNED_PARAMETER(IT1) outerIndexes, VC_ALIGNED_PARAMETER(IT2) innerIndexes);
+ template<typename S1, typename IT1, typename IT2> Vector(const S1 *array, const EntryType *const S1::* ptrMember1, VC_ALIGNED_PARAMETER(IT1) outerIndexes, VC_ALIGNED_PARAMETER(IT2) innerIndexes, MaskArg mask);
+ template<typename Index> void gather(const EntryType *mem, VC_ALIGNED_PARAMETER(Index) indexes);
+ template<typename Index> void gather(const EntryType *mem, VC_ALIGNED_PARAMETER(Index) indexes, MaskArg mask);
#ifdef VC_USE_SET_GATHERS
- template<typename IT> void gather(const EntryType *mem, Vector<IT> indexes, MaskArg mask);
+ template<typename IT> void gather(const EntryType *mem, VC_ALIGNED_PARAMETER(Vector<IT>) indexes, MaskArg mask);
#endif
- template<typename S1, typename IT> void gather(const S1 *array, const EntryType S1::* member1, IT indexes);
- template<typename S1, typename IT> void gather(const S1 *array, const EntryType S1::* member1, IT indexes, MaskArg mask);
- template<typename S1, typename S2, typename IT> void gather(const S1 *array, const S2 S1::* member1, const EntryType S2::* member2, IT indexes);
- template<typename S1, typename S2, typename IT> void gather(const S1 *array, const S2 S1::* member1, const EntryType S2::* member2, IT indexes, MaskArg mask);
- template<typename S1, typename IT1, typename IT2> void gather(const S1 *array, const EntryType *const S1::* ptrMember1, IT1 outerIndexes, IT2 innerIndexes);
- template<typename S1, typename IT1, typename IT2> void gather(const S1 *array, const EntryType *const S1::* ptrMember1, IT1 outerIndexes, IT2 innerIndexes, MaskArg mask);
+ template<typename S1, typename IT> void gather(const S1 *array, const EntryType S1::* member1, VC_ALIGNED_PARAMETER(IT) indexes);
+ template<typename S1, typename IT> void gather(const S1 *array, const EntryType S1::* member1, VC_ALIGNED_PARAMETER(IT) indexes, MaskArg mask);
+ template<typename S1, typename S2, typename IT> void gather(const S1 *array, const S2 S1::* member1, const EntryType S2::* member2, VC_ALIGNED_PARAMETER(IT) indexes);
+ template<typename S1, typename S2, typename IT> void gather(const S1 *array, const S2 S1::* member1, const EntryType S2::* member2, VC_ALIGNED_PARAMETER(IT) indexes, MaskArg mask);
+ template<typename S1, typename IT1, typename IT2> void gather(const S1 *array, const EntryType *const S1::* ptrMember1, VC_ALIGNED_PARAMETER(IT1) outerIndexes, VC_ALIGNED_PARAMETER(IT2) innerIndexes);
+ template<typename S1, typename IT1, typename IT2> void gather(const S1 *array, const EntryType *const S1::* ptrMember1, VC_ALIGNED_PARAMETER(IT1) outerIndexes, VC_ALIGNED_PARAMETER(IT2) innerIndexes, MaskArg mask);
///////////////////////////////////////////////////////////////////////////////////////////
// scatters
- template<typename Index> void scatter(EntryType *mem, Index indexes) const;
- template<typename Index> void scatter(EntryType *mem, Index indexes, MaskArg mask) const;
- template<typename S1, typename IT> void scatter(S1 *array, EntryType S1::* member1, IT indexes) const;
- template<typename S1, typename IT> void scatter(S1 *array, EntryType S1::* member1, IT indexes, MaskArg mask) const;
- template<typename S1, typename S2, typename IT> void scatter(S1 *array, S2 S1::* member1, EntryType S2::* member2, IT indexes) const;
- template<typename S1, typename S2, typename IT> void scatter(S1 *array, S2 S1::* member1, EntryType S2::* member2, IT indexes, MaskArg mask) const;
- template<typename S1, typename IT1, typename IT2> void scatter(S1 *array, EntryType *S1::* ptrMember1, IT1 outerIndexes, IT2 innerIndexes) const;
- template<typename S1, typename IT1, typename IT2> void scatter(S1 *array, EntryType *S1::* ptrMember1, IT1 outerIndexes, IT2 innerIndexes, MaskArg mask) const;
+ template<typename Index> void scatter(EntryType *mem, VC_ALIGNED_PARAMETER(Index) indexes) const;
+ template<typename Index> void scatter(EntryType *mem, VC_ALIGNED_PARAMETER(Index) indexes, MaskArg mask) const;
+ template<typename S1, typename IT> void scatter(S1 *array, EntryType S1::* member1, VC_ALIGNED_PARAMETER(IT) indexes) const;
+ template<typename S1, typename IT> void scatter(S1 *array, EntryType S1::* member1, VC_ALIGNED_PARAMETER(IT) indexes, MaskArg mask) const;
+ template<typename S1, typename S2, typename IT> void scatter(S1 *array, S2 S1::* member1, EntryType S2::* member2, VC_ALIGNED_PARAMETER(IT) indexes) const;
+ template<typename S1, typename S2, typename IT> void scatter(S1 *array, S2 S1::* member1, EntryType S2::* member2, VC_ALIGNED_PARAMETER(IT) indexes, MaskArg mask) const;
+ template<typename S1, typename IT1, typename IT2> void scatter(S1 *array, EntryType *S1::* ptrMember1, VC_ALIGNED_PARAMETER(IT1) outerIndexes, VC_ALIGNED_PARAMETER(IT2) innerIndexes) const;
+ template<typename S1, typename IT1, typename IT2> void scatter(S1 *array, EntryType *S1::* ptrMember1, VC_ALIGNED_PARAMETER(IT1) outerIndexes, VC_ALIGNED_PARAMETER(IT2) innerIndexes, MaskArg mask) const;
///////////////////////////////////////////////////////////////////////////////////////////
//prefix
- inline Vector ALWAYS_INLINE &operator++() { data() = VectorHelper<T>::add(data(), VectorHelper<T>::one()); return *this; }
+ Vc_ALWAYS_INLINE Vector &operator++() { data() = VectorHelper<T>::add(data(), VectorHelper<T>::one()); return *this; }
+ Vc_ALWAYS_INLINE Vector &operator--() { data() = VectorHelper<T>::sub(data(), VectorHelper<T>::one()); return *this; }
//postfix
- inline Vector ALWAYS_INLINE operator++(int) { const Vector<T> r = *this; data() = VectorHelper<T>::add(data(), VectorHelper<T>::one()); return r; }
+ Vc_ALWAYS_INLINE Vector operator++(int) { const Vector<T> r = *this; data() = VectorHelper<T>::add(data(), VectorHelper<T>::one()); return r; }
+ Vc_ALWAYS_INLINE Vector operator--(int) { const Vector<T> r = *this; data() = VectorHelper<T>::sub(data(), VectorHelper<T>::one()); return r; }
- inline Common::AliasingEntryHelper<StorageType> INTRINSIC operator[](int index) {
+ Vc_INTRINSIC Common::AliasingEntryHelper<StorageType> operator[](size_t index) {
#if defined(VC_GCC) && VC_GCC >= 0x40300 && VC_GCC < 0x40400
- ::Vc::Warnings::_operator_bracket_warning();
+ ::AliRoot::Vc::Warnings::_operator_bracket_warning();
#endif
return d.m(index);
}
- inline EntryType ALWAYS_INLINE operator[](int index) const {
+ Vc_ALWAYS_INLINE EntryType operator[](size_t index) const {
return d.m(index);
}
- inline Vector ALWAYS_INLINE operator~() const { return VectorHelper<VectorType>::andnot_(data(), VectorHelper<VectorType>::allone()); }
- inline Vector<typename NegateTypeHelper<T>::Type> operator-() const;
+ Vc_ALWAYS_INLINE Vector operator~() const { return VectorHelper<VectorType>::andnot_(data(), VectorHelper<VectorType>::allone()); }
+ Vc_ALWAYS_INLINE_L Vc_PURE_L Vector<typename NegateTypeHelper<T>::Type> operator-() const Vc_ALWAYS_INLINE_R Vc_PURE_R;
+ Vc_INTRINSIC Vc_PURE Vector operator+() const { return *this; }
#define OP1(fun) \
- inline Vector fun() const { return Vector<T>(VectorHelper<T>::fun(data())); } \
- inline Vector &fun##_eq() { data() = VectorHelper<T>::fun(data()); return *this; }
+ Vc_ALWAYS_INLINE Vector fun() const { return Vector<T>(VectorHelper<T>::fun(data())); } \
+ Vc_ALWAYS_INLINE Vector &fun##_eq() { data() = VectorHelper<T>::fun(data()); return *this; }
OP1(sqrt)
OP1(abs)
#undef OP1
#define OP(symbol, fun) \
- inline Vector ALWAYS_INLINE &operator symbol##=(const Vector<T> &x) { data() = VectorHelper<T>::fun(data(), x.data()); return *this; } \
- inline Vector ALWAYS_INLINE &operator symbol##=(EntryType x) { return operator symbol##=(Vector(x)); } \
- inline Vector ALWAYS_INLINE operator symbol(const Vector<T> &x) const { return Vector<T>(VectorHelper<T>::fun(data(), x.data())); } \
- template<typename TT> inline VC_EXACT_TYPE(TT, EntryType, Vector) ALWAYS_INLINE operator symbol(TT x) const { return operator symbol(Vector(x)); }
+ Vc_ALWAYS_INLINE Vector &operator symbol##=(const Vector<T> &x) { data() = VectorHelper<T>::fun(data(), x.data()); return *this; } \
+ Vc_ALWAYS_INLINE Vector &operator symbol##=(EntryType x) { return operator symbol##=(Vector(x)); } \
+ Vc_ALWAYS_INLINE Vector operator symbol(const Vector<T> &x) const { return Vector<T>(VectorHelper<T>::fun(data(), x.data())); } \
+ template<typename TT> Vc_ALWAYS_INLINE VC_EXACT_TYPE(TT, EntryType, Vector) operator symbol(TT x) const { return operator symbol(Vector(x)); }
OP(+, add)
OP(-, sub)
OP(*, mul)
#undef OP
inline Vector &operator/=(EntryType x);
- template<typename TT> inline PURE_L VC_EXACT_TYPE(TT, EntryType, Vector) operator/(TT x) const PURE_R;
+ template<typename TT> inline Vc_PURE_L VC_EXACT_TYPE(TT, EntryType, Vector) operator/(TT x) const Vc_PURE_R;
inline Vector &operator/=(const Vector<T> &x);
- inline Vector operator/ (const Vector<T> &x) const;
+ inline Vc_PURE_L Vector operator/ (const Vector<T> &x) const Vc_PURE_R;
// bitwise ops
#define OP_VEC(op) \
- inline Vector<T> ALWAYS_INLINE_L &operator op##=(AsArg x) ALWAYS_INLINE_R; \
- inline Vector<T> ALWAYS_INLINE_L operator op (AsArg x) const ALWAYS_INLINE_R;
+ Vc_ALWAYS_INLINE_L Vector<T> &operator op##=(AsArg x) Vc_ALWAYS_INLINE_R; \
+ Vc_ALWAYS_INLINE_L Vc_PURE_L Vector<T> operator op (AsArg x) const Vc_ALWAYS_INLINE_R Vc_PURE_R;
#define OP_ENTRY(op) \
- inline ALWAYS_INLINE Vector<T> &operator op##=(EntryType x) { return operator op##=(Vector(x)); } \
- template<typename TT> inline ALWAYS_INLINE VC_EXACT_TYPE(TT, EntryType, Vector) operator op(TT x) const { return operator op(Vector(x)); }
+ Vc_ALWAYS_INLINE Vector<T> &operator op##=(EntryType x) { return operator op##=(Vector(x)); } \
+ template<typename TT> Vc_ALWAYS_INLINE Vc_PURE VC_EXACT_TYPE(TT, EntryType, Vector) operator op(TT x) const { return operator op(Vector(x)); }
VC_ALL_BINARY(OP_VEC)
VC_ALL_BINARY(OP_ENTRY)
VC_ALL_SHIFTS(OP_VEC)
#undef OP_VEC
#undef OP_ENTRY
- inline Vector<T> ALWAYS_INLINE_L &operator>>=(int x) ALWAYS_INLINE_R;
- inline Vector<T> ALWAYS_INLINE_L &operator<<=(int x) ALWAYS_INLINE_R;
- inline Vector<T> ALWAYS_INLINE_L operator>>(int x) const ALWAYS_INLINE_R;
- inline Vector<T> ALWAYS_INLINE_L operator<<(int x) const ALWAYS_INLINE_R;
+ Vc_ALWAYS_INLINE_L Vector<T> &operator>>=(int x) Vc_ALWAYS_INLINE_R;
+ Vc_ALWAYS_INLINE_L Vector<T> &operator<<=(int x) Vc_ALWAYS_INLINE_R;
+ Vc_ALWAYS_INLINE_L Vector<T> operator>>(int x) const Vc_ALWAYS_INLINE_R;
+ Vc_ALWAYS_INLINE_L Vector<T> operator<<(int x) const Vc_ALWAYS_INLINE_R;
#define OPcmp(symbol, fun) \
- inline Mask ALWAYS_INLINE operator symbol(AsArg x) const { return VectorHelper<T>::fun(data(), x.data()); } \
- template<typename TT> inline VC_EXACT_TYPE(TT, EntryType, Mask) ALWAYS_INLINE operator symbol(TT x) const { return operator symbol(Vector(x)); }
+ Vc_ALWAYS_INLINE Mask operator symbol(AsArg x) const { return VectorHelper<T>::fun(data(), x.data()); } \
+ template<typename TT> Vc_ALWAYS_INLINE VC_EXACT_TYPE(TT, EntryType, Mask) operator symbol(TT x) const { return operator symbol(Vector(x)); }
OPcmp(==, cmpeq)
OPcmp(!=, cmpneq)
OPcmp(<, cmplt)
OPcmp(<=, cmple)
#undef OPcmp
+ Vc_INTRINSIC_L Vc_PURE_L Mask isNegative() const Vc_PURE_R Vc_INTRINSIC_R;
- inline void multiplyAndAdd(const Vector<T> &factor, const Vector<T> &summand) {
- VectorHelper<T>::multiplyAndAdd(data(), factor, summand);
+ Vc_ALWAYS_INLINE void fusedMultiplyAdd(const Vector<T> &factor, const Vector<T> &summand) {
+ VectorHelper<T>::fma(data(), factor.data(), summand.data());
}
- inline void assign( const Vector<T> &v, const Mask &mask ) {
+ Vc_ALWAYS_INLINE void assign( const Vector<T> &v, const Mask &mask ) {
const VectorType k = avx_cast<VectorType>(mask.data());
data() = VectorHelper<VectorType>::blend(data(), v.data(), k);
}
- template<typename V2> inline V2 staticCast() const { return V2(*this); }
- template<typename V2> inline V2 reinterpretCast() const { return avx_cast<typename V2::VectorType>(data()); }
+ template<typename V2> Vc_ALWAYS_INLINE V2 staticCast() const { return V2(*this); }
+ template<typename V2> Vc_ALWAYS_INLINE V2 reinterpretCast() const { return avx_cast<typename V2::VectorType>(data()); }
- inline WriteMaskedVector<T> ALWAYS_INLINE operator()(const Mask &k) { return WriteMaskedVector<T>(this, k); }
+ Vc_ALWAYS_INLINE WriteMaskedVector<T> operator()(const Mask &k) { return WriteMaskedVector<T>(this, k); }
/**
* \return \p true This vector was completely filled. m2 might be 0 or != 0. You still have
//return VectorHelper<T>::pack(data(), m1.data, v2.data(), m2.data);
//}
- inline VectorType &data() { return d.v(); }
- inline const VectorType &data() const { return d.v(); }
+ Vc_ALWAYS_INLINE VectorType &data() { return d.v(); }
+ Vc_ALWAYS_INLINE const VectorType data() const { return d.v(); }
- inline EntryType min() const { return VectorHelper<T>::min(data()); }
- inline EntryType max() const { return VectorHelper<T>::max(data()); }
- inline EntryType product() const { return VectorHelper<T>::mul(data()); }
- inline EntryType sum() const { return VectorHelper<T>::add(data()); }
- inline EntryType min(MaskArg m) const;
- inline EntryType max(MaskArg m) const;
- inline EntryType product(MaskArg m) const;
- inline EntryType sum(MaskArg m) const;
+ Vc_ALWAYS_INLINE EntryType min() const { return VectorHelper<T>::min(data()); }
+ Vc_ALWAYS_INLINE EntryType max() const { return VectorHelper<T>::max(data()); }
+ Vc_ALWAYS_INLINE EntryType product() const { return VectorHelper<T>::mul(data()); }
+ Vc_ALWAYS_INLINE EntryType sum() const { return VectorHelper<T>::add(data()); }
+ Vc_ALWAYS_INLINE_L EntryType min(MaskArg m) const Vc_ALWAYS_INLINE_R;
+ Vc_ALWAYS_INLINE_L EntryType max(MaskArg m) const Vc_ALWAYS_INLINE_R;
+ Vc_ALWAYS_INLINE_L EntryType product(MaskArg m) const Vc_ALWAYS_INLINE_R;
+ Vc_ALWAYS_INLINE_L EntryType sum(MaskArg m) const Vc_ALWAYS_INLINE_R;
- inline Vector sorted() const { return SortHelper<T>::sort(data()); }
+ Vc_INTRINSIC_L Vector shifted(int amount) const Vc_INTRINSIC_R;
+ Vc_INTRINSIC_L Vector rotated(int amount) const Vc_INTRINSIC_R;
+ Vc_ALWAYS_INLINE Vector sorted() const { return SortHelper<T>::sort(data()); }
template<typename F> void callWithValuesSorted(F &f) {
EntryType value = d.m(0);
}
}
- template<typename F> inline void INTRINSIC call(const F &f) const {
+ template<typename F> Vc_INTRINSIC void call(const F &f) const {
for_all_vector_entries(i,
f(EntryType(d.m(i)));
);
}
- template<typename F> inline void INTRINSIC call(F &f) const {
+ template<typename F> Vc_INTRINSIC void call(F &f) const {
for_all_vector_entries(i,
f(EntryType(d.m(i)));
);
}
- template<typename F> inline void INTRINSIC call(const F &f, const Mask &mask) const {
+ template<typename F> Vc_INTRINSIC void call(const F &f, const Mask &mask) const {
Vc_foreach_bit(size_t i, mask) {
f(EntryType(d.m(i)));
}
}
- template<typename F> inline void INTRINSIC call(F &f, const Mask &mask) const {
+ template<typename F> Vc_INTRINSIC void call(F &f, const Mask &mask) const {
Vc_foreach_bit(size_t i, mask) {
f(EntryType(d.m(i)));
}
}
- template<typename F> inline Vector<T> INTRINSIC apply(const F &f) const {
+ template<typename F> Vc_INTRINSIC Vector<T> apply(const F &f) const {
Vector<T> r;
for_all_vector_entries(i,
r.d.m(i) = f(EntryType(d.m(i)));
);
return r;
}
- template<typename F> inline Vector<T> INTRINSIC apply(F &f) const {
+ template<typename F> Vc_INTRINSIC Vector<T> apply(F &f) const {
Vector<T> r;
for_all_vector_entries(i,
r.d.m(i) = f(EntryType(d.m(i)));
return r;
}
- template<typename F> inline Vector<T> INTRINSIC apply(const F &f, const Mask &mask) const {
+ template<typename F> Vc_INTRINSIC Vector<T> apply(const F &f, const Mask &mask) const {
Vector<T> r(*this);
Vc_foreach_bit (size_t i, mask) {
r.d.m(i) = f(EntryType(r.d.m(i)));
}
return r;
}
- template<typename F> inline Vector<T> INTRINSIC apply(F &f, const Mask &mask) const {
+ template<typename F> Vc_INTRINSIC Vector<T> apply(F &f, const Mask &mask) const {
Vector<T> r(*this);
Vc_foreach_bit (size_t i, mask) {
r.d.m(i) = f(EntryType(r.d.m(i)));
return r;
}
- template<typename IndexT> inline void INTRINSIC fill(EntryType (&f)(IndexT)) {
+ template<typename IndexT> Vc_INTRINSIC void fill(EntryType (&f)(IndexT)) {
for_all_vector_entries(i,
d.m(i) = f(i);
);
}
- inline void INTRINSIC fill(EntryType (&f)()) {
+ Vc_INTRINSIC void fill(EntryType (&f)()) {
for_all_vector_entries(i,
d.m(i) = f();
);
}
- inline INTRINSIC_L Vector copySign(AsArg reference) const INTRINSIC_R;
- inline INTRINSIC_L Vector exponent() const INTRINSIC_R;
+ Vc_INTRINSIC_L Vector copySign(AsArg reference) const Vc_INTRINSIC_R;
+ Vc_INTRINSIC_L Vector exponent() const Vc_INTRINSIC_R;
};
typedef Vector<double> double_v;
template<typename T> class SwizzledVector : public Vector<T> {};
-static inline int_v min(const int_v &x, const int_v &y) { return _mm256_min_epi32(x.data(), y.data()); }
-static inline uint_v min(const uint_v &x, const uint_v &y) { return _mm256_min_epu32(x.data(), y.data()); }
-static inline short_v min(const short_v &x, const short_v &y) { return _mm_min_epi16(x.data(), y.data()); }
-static inline ushort_v min(const ushort_v &x, const ushort_v &y) { return _mm_min_epu16(x.data(), y.data()); }
-static inline float_v min(const float_v &x, const float_v &y) { return _mm256_min_ps(x.data(), y.data()); }
-static inline sfloat_v min(const sfloat_v &x, const sfloat_v &y) { return _mm256_min_ps(x.data(), y.data()); }
-static inline double_v min(const double_v &x, const double_v &y) { return _mm256_min_pd(x.data(), y.data()); }
-static inline int_v max(const int_v &x, const int_v &y) { return _mm256_max_epi32(x.data(), y.data()); }
-static inline uint_v max(const uint_v &x, const uint_v &y) { return _mm256_max_epu32(x.data(), y.data()); }
-static inline short_v max(const short_v &x, const short_v &y) { return _mm_max_epi16(x.data(), y.data()); }
-static inline ushort_v max(const ushort_v &x, const ushort_v &y) { return _mm_max_epu16(x.data(), y.data()); }
-static inline float_v max(const float_v &x, const float_v &y) { return _mm256_max_ps(x.data(), y.data()); }
-static inline sfloat_v max(const sfloat_v &x, const sfloat_v &y) { return _mm256_max_ps(x.data(), y.data()); }
-static inline double_v max(const double_v &x, const double_v &y) { return _mm256_max_pd(x.data(), y.data()); }
-
- template<typename T> static inline Vector<T> sqrt (const Vector<T> &x) { return VectorHelper<T>::sqrt(x.data()); }
- template<typename T> static inline Vector<T> rsqrt(const Vector<T> &x) { return VectorHelper<T>::rsqrt(x.data()); }
- template<typename T> static inline Vector<T> abs (const Vector<T> &x) { return VectorHelper<T>::abs(x.data()); }
- template<typename T> static inline Vector<T> reciprocal(const Vector<T> &x) { return VectorHelper<T>::reciprocal(x.data()); }
- template<typename T> static inline Vector<T> round(const Vector<T> &x) { return VectorHelper<T>::round(x.data()); }
-
- template<typename T> static inline typename Vector<T>::Mask isfinite(const Vector<T> &x) { return VectorHelper<T>::isFinite(x.data()); }
- template<typename T> static inline typename Vector<T>::Mask isnan(const Vector<T> &x) { return VectorHelper<T>::isNaN(x.data()); }
+static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y) { return _mm256_min_epi32(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE uint_v min(const uint_v &x, const uint_v &y) { return _mm256_min_epu32(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE short_v min(const short_v &x, const short_v &y) { return _mm_min_epi16(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE ushort_v min(const ushort_v &x, const ushort_v &y) { return _mm_min_epu16(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE float_v min(const float_v &x, const float_v &y) { return _mm256_min_ps(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE sfloat_v min(const sfloat_v &x, const sfloat_v &y) { return _mm256_min_ps(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE double_v min(const double_v &x, const double_v &y) { return _mm256_min_pd(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y) { return _mm256_max_epi32(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE uint_v max(const uint_v &x, const uint_v &y) { return _mm256_max_epu32(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE short_v max(const short_v &x, const short_v &y) { return _mm_max_epi16(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE ushort_v max(const ushort_v &x, const ushort_v &y) { return _mm_max_epu16(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE float_v max(const float_v &x, const float_v &y) { return _mm256_max_ps(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE sfloat_v max(const sfloat_v &x, const sfloat_v &y) { return _mm256_max_ps(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE double_v max(const double_v &x, const double_v &y) { return _mm256_max_pd(x.data(), y.data()); }
+
+ template<typename T> static Vc_ALWAYS_INLINE Vector<T> sqrt (const Vector<T> &x) { return VectorHelper<T>::sqrt(x.data()); }
+ template<typename T> static Vc_ALWAYS_INLINE Vector<T> rsqrt(const Vector<T> &x) { return VectorHelper<T>::rsqrt(x.data()); }
+ template<typename T> static Vc_ALWAYS_INLINE Vector<T> abs (const Vector<T> &x) { return VectorHelper<T>::abs(x.data()); }
+ template<typename T> static Vc_ALWAYS_INLINE Vector<T> reciprocal(const Vector<T> &x) { return VectorHelper<T>::reciprocal(x.data()); }
+ template<typename T> static Vc_ALWAYS_INLINE Vector<T> round(const Vector<T> &x) { return VectorHelper<T>::round(x.data()); }
+
+ template<typename T> static Vc_ALWAYS_INLINE typename Vector<T>::Mask isfinite(const Vector<T> &x) { return VectorHelper<T>::isFinite(x.data()); }
+ template<typename T> static Vc_ALWAYS_INLINE typename Vector<T>::Mask isnan(const Vector<T> &x) { return VectorHelper<T>::isNaN(x.data()); }
#include "forceToRegisters.tcc"
} // namespace AVX
} // namespace Vc
+} // namespace AliRoot
#include "vector.tcc"
#include "math.h"