Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:25:42

0001 /*  This file is part of the Vc library. {{{
0002 Copyright © 2009-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_SCALAR_MATH_H_
0029 #define VC_SCALAR_MATH_H_
0030 
0031 #include <cstdlib>
0032 #include "macros.h"
0033 
0034 namespace Vc_VERSIONED_NAMESPACE
0035 {
0036 // copysign {{{1
0037 Vc_INTRINSIC Scalar::float_v copysign(Scalar::float_v mag, Scalar::float_v sign)
0038 {
0039     union {
0040         float f;
0041         unsigned int i;
0042     } value, s;
0043     value.f = mag.data();
0044     s.f = sign.data();
0045     value.i = (s.i & 0x80000000u) | (value.i & 0x7fffffffu);
0046     return Scalar::float_v{value.f};
0047 }
0048 Vc_INTRINSIC Vc_CONST Scalar::double_v copysign(Scalar::double_v mag,
0049                                                 Scalar::double_v sign)
0050 {
0051     union {
0052         double f;
0053         unsigned long long i;
0054     } value, s;
0055     value.f = mag.data();
0056     s.f = sign.data();
0057     value.i = (s.i & 0x8000000000000000ull) | (value.i & 0x7fffffffffffffffull);
0058     return Scalar::double_v{value.f};
0059 }
0060 
0061 // }}}1
0062 
0063 #define Vc_MINMAX(V)                                                                     \
0064     static Vc_ALWAYS_INLINE Scalar::V min(const Scalar::V &x, const Scalar::V &y)        \
0065     {                                                                                    \
0066         return Scalar::V(std::min(x.data(), y.data()));                                  \
0067     }                                                                                    \
0068     static Vc_ALWAYS_INLINE Scalar::V max(const Scalar::V &x, const Scalar::V &y)        \
0069     {                                                                                    \
0070         return Scalar::V(std::max(x.data(), y.data()));                                  \
0071     }
0072 Vc_ALL_VECTOR_TYPES(Vc_MINMAX);
0073 #undef Vc_MINMAX
0074 
0075 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> sqrt (const Scalar::Vector<T> &x)
0076 {
0077     return Scalar::Vector<T>(std::sqrt(x.data()));
0078 }
0079 
0080 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> rsqrt(const Scalar::Vector<T> &x)
0081 {
0082     const typename Vector<T, VectorAbi::Scalar>::EntryType one = 1; return Scalar::Vector<T>(one / std::sqrt(x.data()));
0083 }
0084 
0085 template <typename T,
0086           typename = enable_if<std::is_same<T, double>::value || std::is_same<T, float>::value ||
0087                                std::is_same<T, int>::value>>
0088 Vc_ALWAYS_INLINE Vc_PURE Scalar::Vector<T> abs(Scalar::Vector<T> x)
0089 {
0090     return std::abs(x.data());
0091 }
0092 
0093 Vc_ALWAYS_INLINE Vc_PURE Scalar::Vector<short> abs(Scalar::Vector<short> x)
0094 {
0095     return std::abs(static_cast<int>(x.data()));
0096 }
0097 
0098 template<typename T> static Vc_ALWAYS_INLINE void sincos(const Scalar::Vector<T> &x, Scalar::Vector<T> *sin, Scalar::Vector<T> *cos)
0099 {
0100 #if defined(_WIN32) || defined(__APPLE__)
0101     sin->data() = std::sin(x.data());
0102     cos->data() = std::cos(x.data());
0103 #elif Vc_HAS_BUILTIN(__builtin_sincosf) || defined Vc_GCC
0104     __builtin_sincosf(x.data(), &sin->data(), &cos->data());
0105 #else
0106     sincosf(x.data(), &sin->data(), &cos->data());
0107 #endif
0108 }
0109 
0110 template<> Vc_ALWAYS_INLINE void sincos(const Scalar::Vector<double> &x, Scalar::Vector<double> *sin, Scalar::Vector<double> *cos)
0111 {
0112 #if defined(_WIN32) || defined(__APPLE__)
0113     sin->data() = std::sin(x.data());
0114     cos->data() = std::cos(x.data());
0115 #elif Vc_HAS_BUILTIN(__builtin_sincos) || defined Vc_GCC
0116     __builtin_sincos(x.data(), &sin->data(), &cos->data());
0117 #else
0118     ::sincos(x.data(), &sin->data(), &cos->data());
0119 #endif
0120 }
0121 
0122 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> sin  (const Scalar::Vector<T> &x)
0123 {
0124     return Scalar::Vector<T>(std::sin(x.data()));
0125 }
0126 
0127 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> asin (const Scalar::Vector<T> &x)
0128 {
0129     return Scalar::Vector<T>(std::asin(x.data()));
0130 }
0131 
0132 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> cos  (const Scalar::Vector<T> &x)
0133 {
0134     return Scalar::Vector<T>(std::cos(x.data()));
0135 }
0136 
0137 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> log  (const Scalar::Vector<T> &x)
0138 {
0139     return Scalar::Vector<T>(std::log(x.data()));
0140 }
0141 
0142 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> log10(const Scalar::Vector<T> &x)
0143 {
0144     return Scalar::Vector<T>(std::log10(x.data()));
0145 }
0146 
0147 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> log2(const Scalar::Vector<T> &x)
0148 {
0149     return Scalar::Vector<T>(std::log2(x.data()));
0150 }
0151 
0152 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> exp (const Scalar::Vector<T> &x)
0153 {
0154     return Scalar::Vector<T>(std::exp(x.data()));
0155 }
0156 
0157 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> atan (const Scalar::Vector<T> &x)
0158 {
0159     return Scalar::Vector<T>(std::atan( x.data() ));
0160 }
0161 
0162 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> atan2(const Scalar::Vector<T> &x, const Scalar::Vector<T> &y)
0163 {
0164     return Scalar::Vector<T>(std::atan2( x.data(), y.data() ));
0165 }
0166 
0167 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> trunc(const Scalar::Vector<T> &x)
0168 {
0169     return std::trunc(x.data());
0170 }
0171 
0172 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> floor(const Scalar::Vector<T> &x)
0173 {
0174     return Scalar::Vector<T>(std::floor(x.data()));
0175 }
0176 
0177 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> ceil(const Scalar::Vector<T> &x)
0178 {
0179     return Scalar::Vector<T>(std::ceil(x.data()));
0180 }
0181 
0182 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> round(const Scalar::Vector<T> &x)
0183 {
0184     return x;
0185 }
0186 
0187 namespace
0188 {
0189     template<typename T> bool _realIsEvenHalf(T x) {
0190         const T two = 2;
0191         const T half = 0.5;
0192         const T f = std::floor(x * half) * two;
0193         return (x - f) == half;
0194     }
0195 } // namespace
0196 template<> Vc_ALWAYS_INLINE Scalar::Vector<float>  round(const Scalar::Vector<float>  &x)
0197 {
0198     return Scalar::float_v(std::floor(x.data() + 0.5f) - (_realIsEvenHalf(x.data()) ? 1.f : 0.f));
0199 }
0200 
0201 template<> Vc_ALWAYS_INLINE Scalar::Vector<double> round(const Scalar::Vector<double> &x)
0202 {
0203     return Scalar::double_v(std::floor(x.data() + 0.5 ) - (_realIsEvenHalf(x.data()) ? 1.  : 0. ));
0204 }
0205 
0206 template<typename T> static Vc_ALWAYS_INLINE Scalar::Vector<T> reciprocal(const Scalar::Vector<T> &x)
0207 {
0208     const typename Vector<T, VectorAbi::Scalar>::EntryType one = 1; return Scalar::Vector<T>(one / x.data());
0209 }
0210 
0211 #ifdef isfinite
0212 #undef isfinite
0213 #endif
0214 #ifdef isnan
0215 #undef isnan
0216 #endif
0217 template<typename T> static Vc_ALWAYS_INLINE typename Vector<T, VectorAbi::Scalar>::Mask isfinite(const Scalar::Vector<T> &x)
0218 {
0219     return typename Vector<T, VectorAbi::Scalar>::Mask(
0220 #ifdef _MSC_VER
0221             !!_finite(x.data())
0222 #elif defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1500
0223             ::isfinite(x.data())
0224 #else
0225             std::isfinite(x.data())
0226 #endif
0227             );
0228 }
0229 
0230 template<typename T> Vc_ALWAYS_INLINE typename Vector<T, VectorAbi::Scalar>::Mask isinf(const Scalar::Vector<T> &x)
0231 {
0232     return typename Vector<T, VectorAbi::Scalar>::Mask(std::isinf(x.data()));
0233 }
0234 
0235 template<typename T> static Vc_ALWAYS_INLINE typename Vector<T, VectorAbi::Scalar>::Mask isnan(const Scalar::Vector<T> &x)
0236 {
0237     return typename Vector<T, VectorAbi::Scalar>::Mask(
0238 #ifdef _MSC_VER
0239             !!_isnan(x.data())
0240 #elif defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1500
0241             ::isnan(x.data())
0242 #else
0243             std::isnan(x.data())
0244 #endif
0245             );
0246 }
0247 
0248 Vc_ALWAYS_INLINE Scalar::Vector<float> frexp(Scalar::Vector<float> x, SimdArray<int, 1, Scalar::Vector<int>, 1> *e) {
0249     return Scalar::float_v(std::frexp(x.data(), &internal_data(*e).data()));
0250 }
0251 Vc_ALWAYS_INLINE Scalar::Vector<double> frexp(Scalar::Vector<double> x, SimdArray<int, 1, Scalar::Vector<int>, 1> *e) {
0252     return Scalar::double_v(std::frexp(x.data(), &internal_data(*e).data()));
0253 }
0254 
0255 Vc_ALWAYS_INLINE Scalar::Vector<float> ldexp(Scalar::Vector<float> x, const SimdArray<int, 1, Scalar::Vector<int>, 1> &e) {
0256     return Scalar::float_v(std::ldexp(x.data(), internal_data(e).data()));
0257 }
0258 Vc_ALWAYS_INLINE Scalar::Vector<double> ldexp(Scalar::Vector<double> x, const SimdArray<int, 1, Scalar::Vector<int>, 1> &e) {
0259     return Scalar::double_v(std::ldexp(x.data(), internal_data(e).data()));
0260 }
0261 
0262 // fma {{{1
0263 template <typename T>
0264 Vc_ALWAYS_INLINE Vector<T, VectorAbi::Scalar> fma(Vector<T, VectorAbi::Scalar> a,
0265                                                   Vector<T, VectorAbi::Scalar> b,
0266                                                   Vector<T, VectorAbi::Scalar> c)
0267 {
0268     if (std::is_integral<T>::value) {
0269         return a * b + c;
0270     } else {
0271         return std::fma(a.data(), b.data(), c.data());
0272     }
0273 }
0274 
0275 // }}}1
0276 }  // namespace Vc
0277 
0278 #endif // VC_SCALAR_MATH_H_
0279 
0280 // vim: foldmethod=marker