Warning, /include/Vc/scalar/vector.tcc is written in an unsupported language. File is not indexed.
0001 /* This file is part of the Vc library. {{{
0002 Copyright © 2011-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 #include <cmath>
0029 #include "../common/data.h"
0030 #include "../common/where.h"
0031 #include "../common/transpose.h"
0032 #include "operators.h"
0033 #include "macros.h"
0034 namespace Vc_VERSIONED_NAMESPACE
0035 {
0036
0037 // special value constructors{{{1
0038 template <typename T>
0039 Vc_INTRINSIC Vector<T, VectorAbi::Scalar>::Vector(VectorSpecialInitializerZero)
0040 : m_data(0)
0041 {
0042 }
0043 template <typename T>
0044 Vc_INTRINSIC Vector<T, VectorAbi::Scalar>::Vector(VectorSpecialInitializerOne)
0045 : m_data(1)
0046 {
0047 }
0048 template <typename T>
0049 Vc_INTRINSIC Vector<T, VectorAbi::Scalar>::Vector(VectorSpecialInitializerIndexesFromZero)
0050 : m_data(0)
0051 {
0052 }
0053
0054 // load member functions{{{1
0055 template <typename T>
0056 template <typename U, typename Flags>
0057 Vc_INTRINSIC typename Vector<T, VectorAbi::Scalar>::
0058 #ifndef Vc_MSVC
0059 template
0060 #endif
0061 load_concept<U, Flags>::type Vector<T, VectorAbi::Scalar>::load(const U *mem, Flags)
0062 {
0063 m_data = mem[0];
0064 }
0065
0066 // store member functions{{{1
0067 template <typename T>
0068 template <typename U, typename Flags, typename>
0069 Vc_INTRINSIC void Vector<T, VectorAbi::Scalar>::store(U *mem, Flags) const
0070 {
0071 mem[0] = m_data;
0072 }
0073 template <typename T>
0074 template <typename U, typename Flags, typename>
0075 Vc_INTRINSIC void Vector<T, VectorAbi::Scalar>::store(U *mem, Mask mask, Flags) const
0076 {
0077 if (mask.data())
0078 mem[0] = m_data;
0079 }
0080
0081 // gather {{{1
0082 template <typename T>
0083 template <class MT, class IT, int Scale>
0084 Vc_ALWAYS_INLINE void Vector<T, VectorAbi::Scalar>::gatherImplementation(
0085 const Common::GatherArguments<MT, IT, Scale> &args)
0086 {
0087 m_data = args.address[Scale * args.indexes[0]];
0088 }
0089
0090 template <typename T>
0091 template <class MT, class IT, int Scale>
0092 Vc_ALWAYS_INLINE void Vector<T, VectorAbi::Scalar>::gatherImplementation(
0093 const Common::GatherArguments<MT, IT, Scale> &args, MaskArgument mask)
0094 {
0095 if (mask.data()) {
0096 m_data = args.address[Scale * args.indexes[0]];
0097 }
0098 }
0099
0100 // scatter {{{1
0101 template <typename T>
0102 template <typename MT, typename IT>
0103 Vc_ALWAYS_INLINE void Vector<T, VectorAbi::Scalar>::scatterImplementation(MT *mem,
0104 IT &&indexes)
0105 const
0106 {
0107 mem[indexes[0]] = m_data;
0108 }
0109
0110 template <typename T>
0111 template <typename MT, typename IT>
0112 Vc_ALWAYS_INLINE void Vector<T, VectorAbi::Scalar>::scatterImplementation(
0113 MT *mem, IT &&indexes, MaskArgument mask) const
0114 {
0115 if (mask.data()) {
0116 mem[indexes[0]] = m_data;
0117 }
0118 }
0119
0120 // exponent {{{1
0121 Vc_INTRINSIC Vc_CONST Scalar::float_v exponent(Scalar::float_v x)
0122 {
0123 Vc_ASSERT(x.data() >= 0.f);
0124 union { float f; int i; } value;
0125 value.f = x.data();
0126 return Scalar::float_v(static_cast<float>((value.i >> 23) - 0x7f));
0127 }
0128 Vc_INTRINSIC Vc_CONST Scalar::double_v Vc_VDECL exponent(Scalar::double_v x)
0129 {
0130 Vc_ASSERT(x.data() >= 0.);
0131 union { double f; long long i; } value;
0132 value.f = x.data();
0133 return Scalar::double_v(static_cast<double>((value.i >> 52) - 0x3ff));
0134 }
0135
0136 // Random {{{1
0137 static Vc_ALWAYS_INLINE void _doRandomStep(Scalar::uint_v &state0, Scalar::uint_v &state1)
0138 {
0139 using Scalar::uint_v;
0140 state0.load(&Common::RandomState[0]);
0141 state1.load(&Common::RandomState[uint_v::Size]);
0142 Detail::operator+(Detail::operator*(state1, uint_v(0xdeece66du)),
0143 uint_v(11))
0144 .store(&Common::RandomState[uint_v::Size]);
0145 uint_v(Detail::operator+(Detail::operator*(state0, uint_v(0xdeece66du)), uint_v(11))
0146 .data() ^
0147 (state1.data() >> 16))
0148 .store(&Common::RandomState[0]);
0149 }
0150
0151 template<typename T> Vc_INTRINSIC Vector<T, VectorAbi::Scalar> Vector<T, VectorAbi::Scalar>::Random()
0152 {
0153 Scalar::uint_v state0, state1;
0154 _doRandomStep(state0, state1);
0155 return Vector<T, VectorAbi::Scalar>(static_cast<EntryType>(state0.data()));
0156 }
0157 template<> Vc_INTRINSIC Scalar::float_v Scalar::float_v::Random()
0158 {
0159 Scalar::uint_v state0, state1;
0160 _doRandomStep(state0, state1);
0161 union { unsigned int i; float f; } x;
0162 x.i = (state0.data() & 0x0fffffffu) | 0x3f800000u;
0163 return Scalar::float_v(x.f - 1.f);
0164 }
0165 template<> Vc_INTRINSIC Scalar::double_v Scalar::double_v::Random()
0166 {
0167 typedef unsigned long long uint64 Vc_MAY_ALIAS;
0168 uint64 state0 = *reinterpret_cast<const uint64 *>(&Common::RandomState[8]);
0169 state0 = (state0 * 0x5deece66dull + 11) & 0x000fffffffffffffull;
0170 *reinterpret_cast<uint64 *>(&Common::RandomState[8]) = state0;
0171 union { unsigned long long i; double f; } x;
0172 x.i = state0 | 0x3ff0000000000000ull;
0173 return Scalar::double_v(x.f - 1.);
0174 }
0175 // isnegative {{{1
0176 Vc_INTRINSIC Vc_CONST Scalar::float_m isnegative(Scalar::float_v x)
0177 {
0178 static_assert(sizeof(float) == sizeof(unsigned int),
0179 "This code assumes float and unsigned int have the same number of "
0180 "Bytes. Please file a bug report if this is a problem.");
0181 union { float f; unsigned int i; } u;
0182 u.f = x.data();
0183 return Scalar::float_m(0u != (u.i & 0x80000000u));
0184 }
0185 Vc_INTRINSIC Vc_CONST Scalar::double_m Vc_VDECL isnegative(Scalar::double_v x)
0186 {
0187 static_assert(sizeof(double) == sizeof(unsigned long long),
0188 "This code assumes double and unsigned long long have the same number "
0189 "of Bytes. Please file a bug report if this is a problem.");
0190 union { double d; unsigned long long l; } u;
0191 u.d = x.data();
0192 return Scalar::double_m(0ull != (u.l & 0x8000000000000000ull));
0193 }
0194
0195 // setQnan {{{1
0196 template<typename T> Vc_INTRINSIC void Vector<T, VectorAbi::Scalar>::setQnan()
0197 {
0198 union { float f; unsigned int i; } u;
0199 u.i = 0xffffffffu;
0200 m_data = u.f;
0201 }
0202 template<> Vc_INTRINSIC void Scalar::double_v::setQnan()
0203 {
0204 union { double d; unsigned long long l; } u;
0205 u.l = 0xffffffffffffffffull;
0206 m_data = u.d;
0207 }
0208 template<typename T> Vc_INTRINSIC void Vector<T, VectorAbi::Scalar>::setQnan(Mask m)
0209 {
0210 if (m.data()) {
0211 setQnan();
0212 }
0213 }
0214 template<> Vc_INTRINSIC void Scalar::double_v::setQnan(Scalar::double_v::Mask m)
0215 {
0216 if (m.data()) {
0217 setQnan();
0218 }
0219 }
0220 // }}}1
0221
0222 namespace Common
0223 {
0224 // transpose_impl {{{1
0225 Vc_ALWAYS_INLINE void transpose_impl(TransposeTag<1, 1>, Scalar::float_v *Vc_RESTRICT r[],
0226 const TransposeProxy<Scalar::float_v> &proxy)
0227 {
0228 *r[0] = std::get<0>(proxy.in).data();
0229 }
0230 // }}}1
0231 } // namespace Common
0232 }
0233 // vim: foldmethod=marker