Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:25:51

0001 /*  This file is part of the Vc library. {{{
0002 Copyright © 2012-2015 Matthias Kretz <kretz@kde.org>
0003 
0004 Redistribution and use in source and binary forms, with or without
0005 modification, are permitted provided that the following conditions are met:
0006     * Redistributions of source code must retain the above copyright
0007       notice, this list of conditions and the following disclaimer.
0008     * Redistributions in binary form must reproduce the above copyright
0009       notice, this list of conditions and the following disclaimer in the
0010       documentation and/or other materials provided with the distribution.
0011     * Neither the names of contributing organizations nor the
0012       names of its contributors may be used to endorse or promote products
0013       derived from this software without specific prior written permission.
0014 
0015 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
0016 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0017 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0018 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
0019 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0020 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0021 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0022 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0023 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0024 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0025 
0026 }}}*/
0027 
0028 #ifndef VC_COMMON_TYPES_H_
0029 #define VC_COMMON_TYPES_H_
0030 
0031 #ifdef Vc_CHECK_ALIGNMENT
0032 #include <cstdlib>
0033 #include <cstdio>
0034 #endif
0035 
0036 #include <ratio>
0037 #include "../global.h"
0038 #include "../traits/type_traits.h"
0039 #include "permutation.h"
0040 
0041 namespace Vc_VERSIONED_NAMESPACE
0042 {
0043 ///\addtogroup Utilities
0044 ///@{
0045 
0046 /// \internal Allow writing \c size_t without the `std::` prefix.
0047 using std::size_t;
0048 
0049 /// long long shorthand
0050 using llong = long long;
0051 /// unsigned long long shorthand
0052 using ullong = unsigned long long;
0053 /// unsigned long shorthand
0054 using ulong = unsigned long;
0055 /// unsigned int shorthand
0056 using uint = unsigned int;
0057 /// unsigned short shorthand
0058 using ushort = unsigned short;
0059 /// unsigned char shorthand
0060 using uchar = unsigned char;
0061 /// signed char shorthand
0062 using schar = signed char;
0063 
0064 /**\internal
0065  * Tag type for explicit zero-initialization
0066  */
0067 struct VectorSpecialInitializerZero {};
0068 /**\internal
0069  * Tag type for explicit one-initialization
0070  */
0071 struct VectorSpecialInitializerOne {};
0072 /**\internal
0073  * Tag type for explicit "iota-initialization"
0074  */
0075 struct VectorSpecialInitializerIndexesFromZero {};
0076 
0077 /**
0078  * The special object \p Vc::Zero can be used to construct Vector and Mask objects
0079  * initialized to zero/\c false.
0080  */
0081 constexpr VectorSpecialInitializerZero Zero = {};
0082 /**
0083  * The special object \p Vc::One can be used to construct Vector and Mask objects
0084  * initialized to one/\c true.
0085  */
0086 constexpr VectorSpecialInitializerOne One = {};
0087 /**
0088  * The special object \p Vc::IndexesFromZero can be used to construct Vector objects
0089  * initialized to values 0, 1, 2, 3, 4, ...
0090  */
0091 constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero = {};
0092 ///@}
0093 
0094 namespace Detail
0095 {
0096 template<typename T> struct MayAliasImpl {
0097 #ifdef Vc_ICC
0098 #pragma warning(disable:2621)
0099 #endif
0100 #ifdef __GNUC__
0101 #pragma GCC diagnostic push
0102 #pragma GCC diagnostic ignored "-Wattributes"
0103 #endif
0104     typedef T type Vc_MAY_ALIAS;
0105 #ifdef __GNUC__
0106 #pragma GCC diagnostic pop
0107 #endif
0108 #ifdef Vc_ICC
0109 #pragma warning(enable:2621)
0110 #endif
0111 };
0112 //template<size_t Bytes> struct MayAlias<MaskBool<Bytes>> { typedef MaskBool<Bytes> type; };
0113 }  // namespace Detail
0114 /**\internal
0115  * Helper MayAlias<T> that turns T into the type to be used for an aliasing pointer. This
0116  * adds the may_alias attribute to T (with compilers that support it). But for MaskBool this
0117  * attribute is already part of the type and applying it a second times leads to warnings/errors,
0118  * therefore MaskBool is simply forwarded as is.
0119  */
0120 template <typename T> using MayAlias = typename Detail::MayAliasImpl<T>::type;
0121 
0122 template <class To, class From> MayAlias<To> &aliasing_cast(From &x)
0123 {
0124     return *reinterpret_cast<MayAlias<To> *>(&x);
0125 }
0126 template <class To, class From> const MayAlias<To> &aliasing_cast(const From &x)
0127 {
0128     return *reinterpret_cast<const MayAlias<To> *>(&x);
0129 }
0130 
0131 template <class To, class From> MayAlias<To> *aliasing_cast(From *x)
0132 {
0133     return reinterpret_cast<MayAlias<To> *>(x);
0134 }
0135 template <class To, class From> const MayAlias<To> *aliasing_cast(const From *x)
0136 {
0137     return reinterpret_cast<const MayAlias<To> *>(x);
0138 }
0139 
0140 /**\internal
0141  * This enumeration lists all possible operators in C++.
0142  *
0143  * The assignment and compound assignment enumerators are used with the conditional_assign
0144  * implementation.
0145  */
0146 enum class Operator : char {
0147     Assign,
0148     Multiply,
0149     MultiplyAssign,
0150     Divide,
0151     DivideAssign,
0152     Remainder,
0153     RemainderAssign,
0154     Plus,
0155     PlusAssign,
0156     Minus,
0157     MinusAssign,
0158     RightShift,
0159     RightShiftAssign,
0160     LeftShift,
0161     LeftShiftAssign,
0162     And,
0163     AndAssign,
0164     Xor,
0165     XorAssign,
0166     Or,
0167     OrAssign,
0168     PreIncrement,
0169     PostIncrement,
0170     PreDecrement,
0171     PostDecrement,
0172     LogicalAnd,
0173     LogicalOr,
0174     Comma,
0175     UnaryPlus,
0176     UnaryMinus,
0177     UnaryNot,
0178     UnaryOnesComplement,
0179     CompareEqual,
0180     CompareNotEqual,
0181     CompareLess,
0182     CompareGreater,
0183     CompareLessEqual,
0184     CompareGreaterEqual
0185 };
0186 
0187 // forward declaration for Vc::array in <Vc/array>
0188 template <typename T, std::size_t N> struct array;
0189 // forward declaration for Vc::span in <Vc/span>
0190 namespace Common {
0191 template <typename T, std::ptrdiff_t N> class span;
0192 }
0193 
0194 /* TODO: add type for half-float, something along these lines:
0195 class half_float
0196 {
0197     uint16_t data;
0198 public:
0199     constexpr half_float() : data(0) {}
0200     constexpr half_float(const half_float &) = default;
0201     constexpr half_float(half_float &&) = default;
0202     constexpr half_float &operator=(const half_float &) = default;
0203 
0204     constexpr explicit half_float(float);
0205     constexpr explicit half_float(double);
0206     constexpr explicit half_float(int);
0207     constexpr explicit half_float(unsigned int);
0208 
0209     explicit operator float       () const;
0210     explicit operator double      () const;
0211     explicit operator int         () const;
0212     explicit operator unsigned int() const;
0213 
0214     bool operator==(half_float rhs) const;
0215     bool operator!=(half_float rhs) const;
0216     bool operator>=(half_float rhs) const;
0217     bool operator<=(half_float rhs) const;
0218     bool operator> (half_float rhs) const;
0219     bool operator< (half_float rhs) const;
0220 
0221     half_float operator+(half_float rhs) const;
0222     half_float operator-(half_float rhs) const;
0223     half_float operator*(half_float rhs) const;
0224     half_float operator/(half_float rhs) const;
0225 };
0226 */
0227 
0228 // TODO: the following doesn't really belong into the toplevel Vc namespace.
0229 #ifndef Vc_CHECK_ALIGNMENT
0230 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *){}
0231 #else
0232 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *ptr)
0233 {
0234     const size_t s = alignof(_T);
0235     if((reinterpret_cast<size_t>(ptr) & ((s ^ (s & (s - 1))) - 1)) != 0) {
0236         fprintf(stderr, "A vector with incorrect alignment has just been created. Look at the stacktrace to find the guilty object.\n");
0237         abort();
0238     }
0239 }
0240 #endif
0241 
0242 namespace Common
0243 {
0244 // defined in common/simdarrayhelper.h
0245 template <typename T, std::size_t Pieces, std::size_t Index> struct Segment;
0246 
0247 /**
0248  * \internal
0249  *
0250  * Helper interface to make m_indexes in InterleavedMemoryAccessBase behave like an integer vector.
0251  * Only that the entries are successive entries from the given start index.
0252  */
0253 template<size_t StructSize> class SuccessiveEntries
0254 {
0255 #ifdef Vc_MSVC
0256     // scatterinterleavedmemory fails with garbage values in m_first if size_type is a
0257     // 64-bit integer type. Using a 32-bit type seems to work around the miscompilation.
0258     using size_type = unsigned;
0259 #else
0260     using size_type = size_t;
0261 #endif
0262     const size_type m_first;
0263 
0264 public:
0265     typedef SuccessiveEntries AsArg;
0266     Vc_INTRINSIC SuccessiveEntries(size_type first) : m_first(first) {}
0267     Vc_INTRINSIC Vc_PURE size_type operator[](size_type offset) const
0268     {
0269         return m_first + offset * StructSize;
0270     }
0271     Vc_INTRINSIC Vc_PURE size_type data() const { return m_first; }
0272     Vc_INTRINSIC Vc_PURE SuccessiveEntries operator+(const SuccessiveEntries &rhs) const
0273     {
0274         return SuccessiveEntries(m_first + rhs.m_first);
0275     }
0276     Vc_INTRINSIC Vc_PURE SuccessiveEntries operator*(const SuccessiveEntries &rhs) const
0277     {
0278         return SuccessiveEntries(m_first * rhs.m_first);
0279     }
0280     Vc_INTRINSIC Vc_PURE SuccessiveEntries operator<<(size_type x) const
0281     {
0282         return {m_first << x};
0283     }
0284 
0285     friend Vc_INTRINSIC SuccessiveEntries &internal_data(SuccessiveEntries &x)
0286     {
0287         return x;
0288     }
0289     friend Vc_INTRINSIC const SuccessiveEntries &internal_data(const SuccessiveEntries &x)
0290     {
0291         return x;
0292     }
0293 };
0294 
0295 // declaration for functions in common/malloc.h
0296 template <std::size_t alignment>
0297 Vc_INTRINSIC_L void *aligned_malloc(std::size_t n) Vc_INTRINSIC_R;
0298 Vc_ALWAYS_INLINE_L void free(void *p) Vc_ALWAYS_INLINE_R;
0299 
0300 /**\internal
0301  * Central definition of the type combinations that convert implicitly.
0302  */
0303 template <typename Mask, typename T, typename U>
0304 using enable_if_mask_converts_implicitly =
0305     enable_if<(!std::is_same<Mask, Traits::decay<U>>::value &&  // that'd be the copy ctor
0306                Traits::is_simd_mask<U>::value && !Traits::isSimdMaskArray<U>::value &&
0307                Traits::is_implicit_cast_allowed_mask<
0308                    Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value)>;
0309 /**\internal
0310  * Central definition of the type combinations that only convert explicitly.
0311  */
0312 template <typename T, typename U>
0313 using enable_if_mask_converts_explicitly = enable_if<(
0314     Traits::isSimdMaskArray<U>::value ||
0315     (Traits::is_simd_mask<U>::value &&
0316      !Traits::is_implicit_cast_allowed_mask<
0317          Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value))>;
0318 
0319 /**\internal
0320  * Tag type for overloading on the width (\VSize{T}) of a vector.
0321  */
0322 template <typename T> using WidthT = std::integral_constant<std::size_t, sizeof(T)>;
0323 
0324 // forward declaration of MaskBool in common/maskbool.h
0325 template <std::size_t Bytes> class MaskBool;
0326 
0327 // forward declaration of SubscriptOperation in common/subscript.h
0328 template <typename T, typename IndexVector, typename Scale, bool>
0329 class SubscriptOperation;
0330 
0331 /**
0332  * \internal
0333  * Helper type to pass along the two arguments for a gather operation.
0334  *
0335  * \tparam IndexVector  Normally an integer SIMD vector, but an array or std::vector also
0336  *                      works (though often not as efficient).
0337  */
0338 template <class T, class IndexVector, int Scale = 1>
0339 struct GatherArguments {
0340     static_assert(std::is_same<T, remove_cvref_t<T>>::value && !std::is_pointer<T>::value,
0341                   "GatherArguments expects an cv unqualified non-ref/ptr type");
0342     const IndexVector indexes;
0343     const T *const address;
0344 };
0345 template <int Scale, class T, class I>
0346 GatherArguments<T, I, Scale> make_gather(const T *m, const I &i)
0347 {
0348     return {i, m};
0349 }
0350 
0351 /**
0352  * \internal
0353  * Helper type to pass along the two arguments for a scatter operation.
0354  *
0355  * \tparam IndexVector  Normally an integer SIMD vector, but an array or std::vector also
0356  *                      works (though often not as efficient).
0357  */
0358 template <typename T, typename IndexVector> struct ScatterArguments
0359 {
0360     const IndexVector indexes;
0361     T *const address;
0362 };
0363 
0364 /**\internal
0365  * Break the recursion of the function below.
0366  */
0367 template <typename I, I Begin, I End, typename F>
0368 Vc_INTRINSIC enable_if<(Begin >= End), void> unrolled_loop(F &&)
0369 {
0370 }
0371 
0372 /**\internal
0373  * Force the code in the lambda \p f to be called with indexes starting from \p Begin up
0374  * to (excluding) \p End to be called without compare and jump instructions (i.e. an
0375  * unrolled loop).
0376  */
0377 template <typename I, I Begin, I End, typename F>
0378 Vc_INTRINSIC Vc_FLATTEN enable_if<(Begin < End), void> unrolled_loop(F &&f)
0379 {
0380     f(Begin);
0381     unrolled_loop<I, Begin + 1, End>(f);
0382 }
0383 
0384 /**\internal
0385  * Small simplification of the unrolled_loop call for ranges from 0 to \p Size using
0386  * std::size_t as the index type.
0387  */
0388 template <std::size_t Size, typename F> Vc_INTRINSIC void for_all_vector_entries(F &&f)
0389 {
0390     unrolled_loop<std::size_t, 0u, Size>(std::forward<F>(f));
0391 }
0392 
0393 }  // namespace Common
0394 }  // namespace Vc
0395 
0396 #include "vector.h"
0397 #include "mask.h"
0398 #include "memoryfwd.h"
0399 
0400 #endif // VC_COMMON_TYPES_H_
0401 
0402 // vim: foldmethod=marker