File indexing completed on 2025-01-30 10:25:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef VC_COMMON_TRIGONOMETRIC_H_
0029 #define VC_COMMON_TRIGONOMETRIC_H_
0030
0031 #include "macros.h"
0032
0033 #ifdef Vc_HAVE_LIBMVEC
0034 extern "C" {
0035 __m128 _ZGVbN4v_sinf(__m128);
0036 __m128d _ZGVbN2v_sin(__m128d);
0037 __m128 _ZGVbN4v_cosf(__m128);
0038 __m128d _ZGVbN2v_cos(__m128d);
0039 __m256 _ZGVdN8v_sinf(__m256);
0040 __m256d _ZGVdN4v_sin(__m256d);
0041 __m256 _ZGVdN8v_cosf(__m256);
0042 __m256d _ZGVdN4v_cos(__m256d);
0043 }
0044 #endif
0045
0046 namespace Vc_VERSIONED_NAMESPACE
0047 {
0048 namespace Detail
0049 {
0050 template<Vc::Implementation Impl> struct MapImpl { enum Dummy { Value = Impl }; };
0051 template<> struct MapImpl<Vc::SSE42Impl> { enum Dummy { Value = MapImpl<Vc::SSE41Impl>::Value }; };
0052
0053 template<Vc::Implementation Impl> using TrigonometricImplementation =
0054 ImplementationT<MapImpl<Impl>::Value
0055 #if defined(Vc_IMPL_XOP) && defined(Vc_IMPL_FMA4)
0056 + Vc::XopInstructions
0057 + Vc::Fma4Instructions
0058 #endif
0059 >;
0060 }
0061
0062 namespace Common
0063 {
0064 template<typename Impl> struct Trigonometric
0065 {
0066 template<typename T> static T Vc_VDECL sin(const T &_x);
0067 template<typename T> static T Vc_VDECL cos(const T &_x);
0068 template<typename T> static void Vc_VDECL sincos(const T &_x, T *_sin, T *_cos);
0069 template<typename T> static T Vc_VDECL asin (const T &_x);
0070 template<typename T> static T Vc_VDECL atan (const T &_x);
0071 template<typename T> static T Vc_VDECL atan2(const T &y, const T &x);
0072 };
0073 }
0074
0075 #if defined Vc_IMPL_SSE || defined DOXYGEN
0076
0077 namespace Detail
0078 {
0079 template <typename T, typename Abi>
0080 using Trig = Common::Trigonometric<Detail::TrigonometricImplementation<
0081 (std::is_same<Abi, VectorAbi::Sse>::value
0082 ? SSE42Impl
0083 : std::is_same<Abi, VectorAbi::Avx>::value ? AVXImpl : ScalarImpl)>>;
0084 }
0085
0086 #ifdef Vc_HAVE_LIBMVEC
0087 Vc_INTRINSIC __m128 sin_dispatch(__m128 x) { return ::_ZGVbN4v_sinf(x); }
0088 Vc_INTRINSIC __m128d sin_dispatch(__m128d x) { return ::_ZGVbN2v_sin (x); }
0089 Vc_INTRINSIC __m128 cos_dispatch(__m128 x) { return ::_ZGVbN4v_cosf(x); }
0090 Vc_INTRINSIC __m128d cos_dispatch(__m128d x) { return ::_ZGVbN2v_cos (x); }
0091 #ifdef Vc_IMPL_AVX
0092 Vc_INTRINSIC __m256 sin_dispatch(__m256 x) { return ::_ZGVdN8v_sinf(x); }
0093 Vc_INTRINSIC __m256d sin_dispatch(__m256d x) { return ::_ZGVdN4v_sin (x); }
0094 Vc_INTRINSIC __m256 cos_dispatch(__m256 x) { return ::_ZGVdN8v_cosf(x); }
0095 Vc_INTRINSIC __m256d cos_dispatch(__m256d x) { return ::_ZGVdN4v_cos (x); }
0096 #endif
0097
0098 template <typename T, typename Abi>
0099 Vc_INTRINSIC Vector<T, detail::not_fixed_size_abi<Abi>> sin(const Vector<T, Abi> &x)
0100 {
0101 return sin_dispatch(x.data());
0102 }
0103 template <typename T, typename Abi>
0104 Vc_INTRINSIC Vector<T, detail::not_fixed_size_abi<Abi>> cos(const Vector<T, Abi> &x)
0105 {
0106 return cos_dispatch(x.data());
0107 }
0108 #else
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 template <typename T, typename Abi>
0134 Vc_INTRINSIC Vector<T, detail::not_fixed_size_abi<Abi>> sin(const Vector<T, Abi> &x)
0135 {
0136 return Detail::Trig<T, Abi>::sin(x);
0137 }
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 template <typename T, typename Abi>
0151 Vc_INTRINSIC Vector<T, detail::not_fixed_size_abi<Abi>> cos(const Vector<T, Abi> &x)
0152 {
0153 return Detail::Trig<T, Abi>::cos(x);
0154 }
0155 #endif
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 template <typename T, typename Abi>
0168 Vc_INTRINSIC Vector<T, detail::not_fixed_size_abi<Abi>> asin(const Vector<T, Abi> &x)
0169 {
0170 return Detail::Trig<T, Abi>::asin(x);
0171 }
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 template <typename T, typename Abi>
0183 Vc_INTRINSIC Vector<T, detail::not_fixed_size_abi<Abi>> atan(const Vector<T, Abi> &x)
0184 {
0185 return Detail::Trig<T, Abi>::atan(x);
0186 }
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 template <typename T, typename Abi>
0199 Vc_INTRINSIC Vector<T, detail::not_fixed_size_abi<Abi>> atan2(const Vector<T, Abi> &y,
0200 const Vector<T, Abi> &x)
0201 {
0202 return Detail::Trig<T, Abi>::atan2(y, x);
0203 }
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216 template <typename T, typename Abi>
0217 Vc_INTRINSIC void sincos(const Vector<T, Abi> &x,
0218 Vector<T, detail::not_fixed_size_abi<Abi>> *sin,
0219 Vector<T, Abi> *cos)
0220 {
0221 Detail::Trig<T, Abi>::sincos(x, sin, cos);
0222 }
0223 #endif
0224 }
0225
0226 #endif