~ubuntu-branches/ubuntu/raring/vc/raring-proposed

« back to all changes in this revision

Viewing changes to common/macros.h

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-03-08 12:50:59 UTC
  • Revision ID: package-import@ubuntu.com-20130308125059-2vpu3hm02kgrqv96
Tags: upstream-0.7.0
ImportĀ upstreamĀ versionĀ 0.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  This file is part of the Vc library.
 
2
 
 
3
    Copyright (C) 2010-2012 Matthias Kretz <kretz@kde.org>
 
4
 
 
5
    Vc is free software: you can redistribute it and/or modify
 
6
    it under the terms of the GNU Lesser General Public License as
 
7
    published by the Free Software Foundation, either version 3 of
 
8
    the License, or (at your option) any later version.
 
9
 
 
10
    Vc is distributed in the hope that it will be useful, but
 
11
    WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
    GNU Lesser General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU Lesser General Public
 
16
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.
 
17
 
 
18
*/
 
19
 
 
20
#ifndef VC_COMMON_MACROS_H
 
21
#define VC_COMMON_MACROS_H
 
22
#undef VC_COMMON_UNDOMACROS_H
 
23
 
 
24
#include <Vc/global.h>
 
25
 
 
26
#if VC_GCC && !__OPTIMIZE__
 
27
// GCC uses lots of old-style-casts in macros that disguise as intrinsics
 
28
#pragma GCC diagnostic push
 
29
#pragma GCC diagnostic ignored "-Wold-style-cast"
 
30
#endif
 
31
 
 
32
#ifdef VC_MSVC
 
33
# define ALIGN(n) __declspec(align(n))
 
34
# define STRUCT_ALIGN1(n) ALIGN(n)
 
35
# define STRUCT_ALIGN2(n)
 
36
# define ALIGNED_TYPEDEF(n, _type_, _newType_) typedef ALIGN(n) _type_ _newType_
 
37
#else
 
38
# define ALIGN(n) __attribute__((aligned(n)))
 
39
# define STRUCT_ALIGN1(n)
 
40
# define STRUCT_ALIGN2(n) ALIGN(n)
 
41
# define ALIGNED_TYPEDEF(n, _type_, _newType_) typedef _type_ _newType_ ALIGN(n)
 
42
#endif
 
43
 
 
44
#define FREE_STORE_OPERATORS_ALIGNED(alignment) \
 
45
        inline void *operator new(size_t size) { return _mm_malloc(size, alignment); } \
 
46
        inline void *operator new(size_t, void *p) { return p; } \
 
47
        inline void *operator new[](size_t size) { return _mm_malloc(size, alignment); } \
 
48
        inline void operator delete(void *ptr, size_t) { _mm_free(ptr); } \
 
49
        inline void operator delete[](void *ptr, size_t) { _mm_free(ptr); }
 
50
 
 
51
#ifdef VC_CXX11
 
52
#define Vc_ALIGNOF(_TYPE_) alignof(_TYPE_)
 
53
#else
 
54
#define Vc_ALIGNOF(_TYPE_) __alignof(_TYPE_)
 
55
#endif
 
56
 
 
57
#ifdef VC_CLANG
 
58
#  define Vc_INTRINSIC_L inline
 
59
#  define Vc_INTRINSIC_R __attribute__((always_inline))
 
60
#  define Vc_INTRINSIC Vc_INTRINSIC_L Vc_INTRINSIC_R
 
61
#  define Vc_FLATTEN
 
62
#  define Vc_CONST __attribute__((const))
 
63
#  define Vc_CONST_L
 
64
#  define Vc_CONST_R Vc_CONST
 
65
#  define Vc_PURE __attribute__((pure))
 
66
#  define Vc_PURE_L
 
67
#  define Vc_PURE_R Vc_PURE
 
68
#  define Vc_MAY_ALIAS __attribute__((may_alias))
 
69
#  define Vc_ALWAYS_INLINE_L inline
 
70
#  define Vc_ALWAYS_INLINE_R __attribute__((always_inline))
 
71
#  define Vc_ALWAYS_INLINE Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE_R
 
72
#  define VC_IS_UNLIKELY(x) __builtin_expect(x, 0)
 
73
#  define VC_IS_LIKELY(x) __builtin_expect(x, 1)
 
74
#  define VC_RESTRICT __restrict__
 
75
#  define VC_DEPRECATED(msg)
 
76
#elif defined(__GNUC__)
 
77
#  if VC_GCC < 0x40300 || defined(VC_OPEN64)
 
78
// GCC 4.1 and 4.2 ICE on may_alias. Since Open64 uses the GCC 4.2 frontend it has the same problem.
 
79
#    define Vc_MAY_ALIAS
 
80
#  else
 
81
#    define Vc_MAY_ALIAS __attribute__((__may_alias__))
 
82
#  endif
 
83
#  if VC_GCC < 0x40200
 
84
// GCC 4.1 fails with "sorry unimplemented: inlining failed"
 
85
#    define Vc_INTRINSIC_R __attribute__((__flatten__))
 
86
#  elif VC_GCC < 0x40300 || defined(VC_OPEN64)
 
87
// the GCC 4.2 frontend doesn't know the __artificial__ attribute
 
88
#    define Vc_INTRINSIC_R __attribute__((__flatten__, __always_inline__))
 
89
#  else
 
90
#    define Vc_INTRINSIC_R __attribute__((__flatten__, __always_inline__, __artificial__))
 
91
#  endif
 
92
#  define Vc_INTRINSIC_L inline
 
93
#  define Vc_INTRINSIC Vc_INTRINSIC_L Vc_INTRINSIC_R
 
94
#  define Vc_FLATTEN __attribute__((__flatten__))
 
95
#  define Vc_ALWAYS_INLINE_L inline
 
96
#  define Vc_ALWAYS_INLINE_R __attribute__((__always_inline__))
 
97
#  define Vc_ALWAYS_INLINE Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE_R
 
98
#  ifdef VC_ICC
 
99
     // ICC miscompiles if there are functions marked as pure or const
 
100
#    define Vc_PURE
 
101
#    define Vc_CONST
 
102
#  else
 
103
#    define Vc_PURE __attribute__((__pure__))
 
104
#    define Vc_CONST __attribute__((__const__))
 
105
#  endif
 
106
#  define Vc_CONST_L
 
107
#  define Vc_CONST_R Vc_CONST
 
108
#  define Vc_PURE_L
 
109
#  define Vc_PURE_R Vc_PURE
 
110
#  define VC_IS_UNLIKELY(x) __builtin_expect(x, 0)
 
111
#  define VC_IS_LIKELY(x) __builtin_expect(x, 1)
 
112
#  define VC_RESTRICT __restrict__
 
113
#  define VC_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
 
114
#else
 
115
#  define Vc_FLATTEN
 
116
#  ifdef Vc_PURE
 
117
#    undef Vc_PURE
 
118
#  endif
 
119
#  define Vc_MAY_ALIAS
 
120
#  ifdef VC_MSVC
 
121
#    define Vc_ALWAYS_INLINE inline __forceinline
 
122
#    define Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE
 
123
#    define Vc_ALWAYS_INLINE_R
 
124
#    define Vc_CONST __declspec(noalias)
 
125
#    define Vc_CONST_L Vc_CONST
 
126
#    define Vc_CONST_R
 
127
#    define Vc_PURE /*Vc_CONST*/
 
128
#    define Vc_PURE_L Vc_PURE
 
129
#    define Vc_PURE_R
 
130
#    define Vc_INTRINSIC inline __forceinline
 
131
#    define Vc_INTRINSIC_L Vc_INTRINSIC
 
132
#    define Vc_INTRINSIC_R
 
133
#  else
 
134
#    define Vc_ALWAYS_INLINE
 
135
#    define Vc_ALWAYS_INLINE_L
 
136
#    define Vc_ALWAYS_INLINE_R
 
137
#    define Vc_CONST
 
138
#    define Vc_CONST_L
 
139
#    define Vc_CONST_R
 
140
#    define Vc_PURE
 
141
#    define Vc_PURE_L
 
142
#    define Vc_PURE_R
 
143
#    define Vc_INTRINSIC
 
144
#    define Vc_INTRINSIC_L
 
145
#    define Vc_INTRINSIC_R
 
146
#  endif
 
147
#  define VC_IS_UNLIKELY(x) x
 
148
#  define VC_IS_LIKELY(x) x
 
149
#  define VC_RESTRICT __restrict
 
150
#  define VC_DEPRECATED(msg) __declspec(deprecated(msg))
 
151
#endif
 
152
 
 
153
#if __cplusplus >= 201103 /*C++11*/
 
154
#define _VC_CONSTEXPR constexpr
 
155
#define _VC_CONSTEXPR_L _VC_CONSTEXPR
 
156
#define _VC_CONSTEXPR_R
 
157
#else
 
158
#define _VC_CONSTEXPR Vc_INTRINSIC Vc_CONST
 
159
#define _VC_CONSTEXPR_L Vc_INTRINSIC_L Vc_CONST_L
 
160
#define _VC_CONSTEXPR_R Vc_INTRINSIC_R Vc_CONST_R
 
161
#endif
 
162
 
 
163
#ifdef VC_CXX11
 
164
# define _VC_NOEXCEPT noexcept
 
165
#else
 
166
# define _VC_NOEXCEPT throw()
 
167
#endif
 
168
 
 
169
 
 
170
#ifdef VC_GCC
 
171
# define VC_WARN_INLINE
 
172
# define VC_WARN(msg) __attribute__((warning("\n\t" msg)))
 
173
#else
 
174
# define VC_WARN_INLINE inline
 
175
# define VC_WARN(msg)
 
176
#endif
 
177
 
 
178
#define unrolled_loop16(_it_, _start_, _end_, _code_) \
 
179
if (_start_ +  0 < _end_) { enum { _it_ = (_start_ +  0) < _end_ ? (_start_ +  0) : _start_ }; _code_ } \
 
180
if (_start_ +  1 < _end_) { enum { _it_ = (_start_ +  1) < _end_ ? (_start_ +  1) : _start_ }; _code_ } \
 
181
if (_start_ +  2 < _end_) { enum { _it_ = (_start_ +  2) < _end_ ? (_start_ +  2) : _start_ }; _code_ } \
 
182
if (_start_ +  3 < _end_) { enum { _it_ = (_start_ +  3) < _end_ ? (_start_ +  3) : _start_ }; _code_ } \
 
183
if (_start_ +  4 < _end_) { enum { _it_ = (_start_ +  4) < _end_ ? (_start_ +  4) : _start_ }; _code_ } \
 
184
if (_start_ +  5 < _end_) { enum { _it_ = (_start_ +  5) < _end_ ? (_start_ +  5) : _start_ }; _code_ } \
 
185
if (_start_ +  6 < _end_) { enum { _it_ = (_start_ +  6) < _end_ ? (_start_ +  6) : _start_ }; _code_ } \
 
186
if (_start_ +  7 < _end_) { enum { _it_ = (_start_ +  7) < _end_ ? (_start_ +  7) : _start_ }; _code_ } \
 
187
if (_start_ +  8 < _end_) { enum { _it_ = (_start_ +  8) < _end_ ? (_start_ +  8) : _start_ }; _code_ } \
 
188
if (_start_ +  9 < _end_) { enum { _it_ = (_start_ +  9) < _end_ ? (_start_ +  9) : _start_ }; _code_ } \
 
189
if (_start_ + 10 < _end_) { enum { _it_ = (_start_ + 10) < _end_ ? (_start_ + 10) : _start_ }; _code_ } \
 
190
if (_start_ + 11 < _end_) { enum { _it_ = (_start_ + 11) < _end_ ? (_start_ + 11) : _start_ }; _code_ } \
 
191
if (_start_ + 12 < _end_) { enum { _it_ = (_start_ + 12) < _end_ ? (_start_ + 12) : _start_ }; _code_ } \
 
192
if (_start_ + 13 < _end_) { enum { _it_ = (_start_ + 13) < _end_ ? (_start_ + 13) : _start_ }; _code_ } \
 
193
if (_start_ + 14 < _end_) { enum { _it_ = (_start_ + 14) < _end_ ? (_start_ + 14) : _start_ }; _code_ } \
 
194
if (_start_ + 15 < _end_) { enum { _it_ = (_start_ + 15) < _end_ ? (_start_ + 15) : _start_ }; _code_ } \
 
195
do {} while ( false )
 
196
 
 
197
#define for_all_vector_entries(_it_, _code_) \
 
198
  unrolled_loop16(_it_, 0, Size, _code_)
 
199
 
 
200
#ifdef NDEBUG
 
201
#define VC_ASSERT(x)
 
202
#else
 
203
#include <assert.h>
 
204
#define VC_ASSERT(x) assert(x);
 
205
#endif
 
206
 
 
207
#ifdef VC_CLANG
 
208
#define VC_HAS_BUILTIN(x) __has_builtin(x)
 
209
#else
 
210
#define VC_HAS_BUILTIN(x) 0
 
211
#endif
 
212
 
 
213
#ifndef VC_COMMON_MACROS_H_ONCE
 
214
#define VC_COMMON_MACROS_H_ONCE
 
215
 
 
216
#define _VC_CAT_HELPER(a, b, c, d) a##b##c##d
 
217
#define _VC_CAT(a, b, c, d) _VC_CAT_HELPER(a, b, c, d)
 
218
 
 
219
#if __cplusplus >= 201103 /*C++11*/ || (defined(VC_MSVC) && VC_MSVC >= 160000000)
 
220
#define VC_STATIC_ASSERT_NC(cond, msg) \
 
221
    static_assert(cond, #msg)
 
222
#define VC_STATIC_ASSERT(cond, msg) VC_STATIC_ASSERT_NC(cond, msg)
 
223
#else // C++98
 
224
namespace Vc {
 
225
    namespace {
 
226
        template<bool> struct STATIC_ASSERT_FAILURE;
 
227
        template<> struct STATIC_ASSERT_FAILURE<true> {};
 
228
}}
 
229
 
 
230
#define VC_STATIC_ASSERT_NC(cond, msg) \
 
231
    typedef STATIC_ASSERT_FAILURE<cond> _VC_CAT(static_assert_failed_on_line_,__LINE__,_,msg); \
 
232
    enum { \
 
233
        _VC_CAT(static_assert_failed__on_line_,__LINE__,_,msg) = sizeof(_VC_CAT(static_assert_failed_on_line_,__LINE__,_,msg)) \
 
234
    }
 
235
#define VC_STATIC_ASSERT(cond, msg) VC_STATIC_ASSERT_NC(cond, msg)
 
236
#endif // C++11/98
 
237
 
 
238
    template<int e, int center> struct exponentToMultiplier { enum {
 
239
        X = exponentToMultiplier<e - 1, center>::X * ((e - center < 31) ? 2 : 1),
 
240
        Value = (X == 0 ? 1 : X)
 
241
    }; };
 
242
    template<int center> struct exponentToMultiplier<center,center> { enum { X = 1, Value = X }; };
 
243
    template<int center> struct exponentToMultiplier<   -1, center> { enum { X = 0, Value = 1 }; };
 
244
    template<int center> struct exponentToMultiplier< -256, center> { enum { X = 0, Value = 1 }; };
 
245
    template<int center> struct exponentToMultiplier< -512, center> { enum { X = 0, Value = 1 }; };
 
246
    template<int center> struct exponentToMultiplier<-1024, center> { enum { X = 0, Value = 1 }; };
 
247
 
 
248
    template<int e, int center> struct exponentToDivisor { enum {
 
249
        X = exponentToDivisor<e + 1, center>::X * ((center - e < 31) ? 2 : 1),
 
250
        Value = (X == 0 ? 1 : X)
 
251
    }; };
 
252
    template<int center> struct exponentToDivisor<center, center> { enum { X = 1, Value = X }; };
 
253
    template<int center> struct exponentToDivisor<     1, center> { enum { X = 0, Value = 1 }; };
 
254
    template<int center> struct exponentToDivisor<   256, center> { enum { X = 0, Value = 1 }; };
 
255
    template<int center> struct exponentToDivisor<   512, center> { enum { X = 0, Value = 1 }; };
 
256
    template<int center> struct exponentToDivisor<  1024, center> { enum { X = 0, Value = 1 }; };
 
257
#endif // VC_COMMON_MACROS_H_ONCE
 
258
 
 
259
#define _CAT_IMPL(a, b) a##b
 
260
#define CAT(a, b) _CAT_IMPL(a, b)
 
261
 
 
262
#define Vc_buildDouble(sign, mantissa, exponent) \
 
263
    ((static_cast<double>((mantissa & 0x000fffffffffffffull) | 0x0010000000000000ull) / 0x0010000000000000ull) \
 
264
    * exponentToMultiplier<exponent,  0>::Value \
 
265
    * exponentToMultiplier<exponent, 30>::Value \
 
266
    * exponentToMultiplier<exponent, 60>::Value \
 
267
    * exponentToMultiplier<exponent, 90>::Value \
 
268
    / exponentToDivisor<exponent,   0>::Value \
 
269
    / exponentToDivisor<exponent, -30>::Value \
 
270
    / exponentToDivisor<exponent, -60>::Value \
 
271
    / exponentToDivisor<exponent, -90>::Value \
 
272
    * static_cast<double>(sign))
 
273
#define Vc_buildFloat(sign, mantissa, exponent) \
 
274
    ((static_cast<float>((mantissa & 0x007fffffu) | 0x00800000) / 0x00800000) \
 
275
    * exponentToMultiplier<exponent,  0>::Value \
 
276
    * exponentToMultiplier<exponent, 30>::Value \
 
277
    * exponentToMultiplier<exponent, 60>::Value \
 
278
    * exponentToMultiplier<exponent, 90>::Value \
 
279
    / exponentToDivisor<exponent,   0>::Value \
 
280
    / exponentToDivisor<exponent, -30>::Value \
 
281
    / exponentToDivisor<exponent, -60>::Value \
 
282
    / exponentToDivisor<exponent, -90>::Value \
 
283
    * static_cast<float>(sign))
 
284
 
 
285
#define _VC_APPLY_IMPL_1(macro, a, b, c, d, e) macro(a)
 
286
#define _VC_APPLY_IMPL_2(macro, a, b, c, d, e) macro(a, b)
 
287
#define _VC_APPLY_IMPL_3(macro, a, b, c, d, e) macro(a, b, c)
 
288
#define _VC_APPLY_IMPL_4(macro, a, b, c, d, e) macro(a, b, c, d)
 
289
#define _VC_APPLY_IMPL_5(macro, a, b, c, d, e) macro(a, b, c, d, e)
 
290
 
 
291
#define VC_LIST_FLOAT_VECTOR_TYPES(size, macro, a, b, c, d) \
 
292
    size(macro, double_v, a, b, c, d) \
 
293
    size(macro,  float_v, a, b, c, d) \
 
294
    size(macro, sfloat_v, a, b, c, d)
 
295
#define VC_LIST_INT_VECTOR_TYPES(size, macro, a, b, c, d) \
 
296
    size(macro,    int_v, a, b, c, d) \
 
297
    size(macro,   uint_v, a, b, c, d) \
 
298
    size(macro,  short_v, a, b, c, d) \
 
299
    size(macro, ushort_v, a, b, c, d)
 
300
#define VC_LIST_VECTOR_TYPES(size, macro, a, b, c, d) \
 
301
    VC_LIST_FLOAT_VECTOR_TYPES(size, macro, a, b, c, d) \
 
302
    VC_LIST_INT_VECTOR_TYPES(size, macro, a, b, c, d)
 
303
#define VC_LIST_COMPARES(size, macro, a, b, c, d) \
 
304
    size(macro, ==, a, b, c, d) \
 
305
    size(macro, !=, a, b, c, d) \
 
306
    size(macro, <=, a, b, c, d) \
 
307
    size(macro, >=, a, b, c, d) \
 
308
    size(macro, < , a, b, c, d) \
 
309
    size(macro, > , a, b, c, d)
 
310
#define VC_LIST_LOGICAL(size, macro, a, b, c, d) \
 
311
    size(macro, &&, a, b, c, d) \
 
312
    size(macro, ||, a, b, c, d)
 
313
#define VC_LIST_BINARY(size, macro, a, b, c, d) \
 
314
    size(macro, |, a, b, c, d) \
 
315
    size(macro, &, a, b, c, d) \
 
316
    size(macro, ^, a, b, c, d)
 
317
#define VC_LIST_SHIFTS(size, macro, a, b, c, d) \
 
318
    size(macro, <<, a, b, c, d) \
 
319
    size(macro, >>, a, b, c, d)
 
320
#define VC_LIST_ARITHMETICS(size, macro, a, b, c, d) \
 
321
    size(macro, +, a, b, c, d) \
 
322
    size(macro, -, a, b, c, d) \
 
323
    size(macro, *, a, b, c, d) \
 
324
    size(macro, /, a, b, c, d) \
 
325
    size(macro, %, a, b, c, d)
 
326
 
 
327
#define VC_APPLY_0(_list, macro)             _list(_VC_APPLY_IMPL_1, macro, 0, 0, 0, 0)
 
328
#define VC_APPLY_1(_list, macro, a)          _list(_VC_APPLY_IMPL_2, macro, a, 0, 0, 0)
 
329
#define VC_APPLY_2(_list, macro, a, b)       _list(_VC_APPLY_IMPL_3, macro, a, b, 0, 0)
 
330
#define VC_APPLY_3(_list, macro, a, b, c)    _list(_VC_APPLY_IMPL_4, macro, a, b, c, 0)
 
331
#define VC_APPLY_4(_list, macro, a, b, c, d) _list(_VC_APPLY_IMPL_5, macro, a, b, c, d)
 
332
 
 
333
#define VC_ALL_COMPARES(macro)     VC_APPLY_0(VC_LIST_COMPARES, macro)
 
334
#define VC_ALL_LOGICAL(macro)      VC_APPLY_0(VC_LIST_LOGICAL, macro)
 
335
#define VC_ALL_BINARY(macro)       VC_APPLY_0(VC_LIST_BINARY, macro)
 
336
#define VC_ALL_SHIFTS(macro)       VC_APPLY_0(VC_LIST_SHIFTS, macro)
 
337
#define VC_ALL_ARITHMETICS(macro)  VC_APPLY_0(VC_LIST_ARITHMETICS, macro)
 
338
#define VC_ALL_FLOAT_VECTOR_TYPES(macro) VC_APPLY_0(VC_LIST_FLOAT_VECTOR_TYPES, macro)
 
339
#define VC_ALL_VECTOR_TYPES(macro) VC_APPLY_0(VC_LIST_VECTOR_TYPES, macro)
 
340
 
 
341
#define VC_EXACT_TYPE(_test, _reference, _type) \
 
342
    typename EnableIf<IsEqualType<_test, _reference>::Value, _type>::Value
 
343
 
 
344
#ifdef VC_PASSING_VECTOR_BY_VALUE_IS_BROKEN
 
345
#define VC_ALIGNED_PARAMETER(_Type) const _Type &
 
346
#else
 
347
#define VC_ALIGNED_PARAMETER(_Type) const _Type
 
348
#endif
 
349
 
 
350
#if defined(VC_ICC) || defined(VC_CLANG)
 
351
#define VC_OFFSETOF(Type, member) (reinterpret_cast<const char *>(&reinterpret_cast<const Type *>(0)->member) - reinterpret_cast<const char *>(0))
 
352
#elif defined(VC_GCC) && VC_GCC < 0x40500
 
353
#define VC_OFFSETOF(Type, member) (reinterpret_cast<const char *>(&reinterpret_cast<const Type *>(0x1000)->member) - reinterpret_cast<const char *>(0x1000))
 
354
#else
 
355
#define VC_OFFSETOF(Type, member) offsetof(Type, member)
 
356
#endif
 
357
 
 
358
 
 
359
#endif // VC_COMMON_MACROS_H