1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtCore module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #ifndef QSIMD_P_H |
43 | #define QSIMD_P_H |
44 | |
45 | #include <qglobal.h> |
46 | |
47 | |
48 | QT_BEGIN_HEADER |
49 | |
50 | |
51 | #if defined(QT_NO_MAC_XARCH) || (defined(Q_OS_DARWIN) && (defined(__ppc__) || defined(__ppc64__))) |
52 | // Disable MMX and SSE on Mac/PPC builds, or if the compiler |
53 | // does not support -Xarch argument passing |
54 | #undef QT_HAVE_SSE |
55 | #undef QT_HAVE_SSE2 |
56 | #undef QT_HAVE_SSE3 |
57 | #undef QT_HAVE_SSSE3 |
58 | #undef QT_HAVE_SSE4_1 |
59 | #undef QT_HAVE_SSE4_2 |
60 | #undef QT_HAVE_AVX |
61 | #undef QT_HAVE_3DNOW |
62 | #undef QT_HAVE_MMX |
63 | #endif |
64 | |
65 | // SSE intrinsics |
66 | #if defined(QT_HAVE_SSE2) && (defined(__SSE2__) || defined(Q_CC_MSVC)) |
67 | #if defined(QT_LINUXBASE) |
68 | /// this is an evil hack - the posix_memalign declaration in LSB |
69 | /// is wrong - see http://bugs.linuxbase.org/show_bug.cgi?id=2431 |
70 | # define posix_memalign _lsb_hack_posix_memalign |
71 | # include <emmintrin.h> |
72 | # undef posix_memalign |
73 | #else |
74 | # ifdef Q_CC_MINGW |
75 | # include <windows.h> |
76 | # endif |
77 | # include <emmintrin.h> |
78 | #endif |
79 | |
80 | // SSE3 intrinsics |
81 | #if defined(QT_HAVE_SSE3) && (defined(__SSE3__) || defined(Q_CC_MSVC)) |
82 | #include <pmmintrin.h> |
83 | #endif |
84 | |
85 | // SSSE3 intrinsics |
86 | #if defined(QT_HAVE_SSSE3) && (defined(__SSSE3__) || defined(Q_CC_MSVC)) |
87 | #include <tmmintrin.h> |
88 | #endif |
89 | |
90 | // SSE4.1 intrinsics |
91 | #if defined(QT_HAVE_SSE4_1) && (defined(__SSE4_1__) || defined(Q_CC_MSVC)) |
92 | #include <smmintrin.h> |
93 | #endif |
94 | |
95 | // SSE4.2 intrinsics |
96 | #if defined(QT_HAVE_SSE4_2) && (defined(__SSE4_2__) || defined(Q_CC_MSVC)) |
97 | #include <nmmintrin.h> |
98 | |
99 | // Add missing intrisics in some compilers (e.g. llvm-gcc) |
100 | #ifndef _SIDD_UBYTE_OPS |
101 | #define _SIDD_UBYTE_OPS 0x00 |
102 | #endif |
103 | |
104 | #ifndef _SIDD_UWORD_OPS |
105 | #define _SIDD_UWORD_OPS 0x01 |
106 | #endif |
107 | |
108 | #ifndef _SIDD_SBYTE_OPS |
109 | #define _SIDD_SBYTE_OPS 0x02 |
110 | #endif |
111 | |
112 | #ifndef _SIDD_SWORD_OPS |
113 | #define _SIDD_SWORD_OPS 0x03 |
114 | #endif |
115 | |
116 | #ifndef _SIDD_CMP_EQUAL_ANY |
117 | #define _SIDD_CMP_EQUAL_ANY 0x00 |
118 | #endif |
119 | |
120 | #ifndef _SIDD_CMP_RANGES |
121 | #define _SIDD_CMP_RANGES 0x04 |
122 | #endif |
123 | |
124 | #ifndef _SIDD_CMP_EQUAL_EACH |
125 | #define _SIDD_CMP_EQUAL_EACH 0x08 |
126 | #endif |
127 | |
128 | #ifndef _SIDD_CMP_EQUAL_ORDERED |
129 | #define _SIDD_CMP_EQUAL_ORDERED 0x0c |
130 | #endif |
131 | |
132 | #ifndef _SIDD_POSITIVE_POLARITY |
133 | #define _SIDD_POSITIVE_POLARITY 0x00 |
134 | #endif |
135 | |
136 | #ifndef _SIDD_NEGATIVE_POLARITY |
137 | #define _SIDD_NEGATIVE_POLARITY 0x10 |
138 | #endif |
139 | |
140 | #ifndef _SIDD_MASKED_POSITIVE_POLARITY |
141 | #define _SIDD_MASKED_POSITIVE_POLARITY 0x20 |
142 | #endif |
143 | |
144 | #ifndef _SIDD_MASKED_NEGATIVE_POLARITY |
145 | #define _SIDD_MASKED_NEGATIVE_POLARITY 0x30 |
146 | #endif |
147 | |
148 | #ifndef _SIDD_LEAST_SIGNIFICANT |
149 | #define _SIDD_LEAST_SIGNIFICANT 0x00 |
150 | #endif |
151 | |
152 | #ifndef _SIDD_MOST_SIGNIFICANT |
153 | #define _SIDD_MOST_SIGNIFICANT 0x40 |
154 | #endif |
155 | |
156 | #ifndef _SIDD_BIT_MASK |
157 | #define _SIDD_BIT_MASK 0x00 |
158 | #endif |
159 | |
160 | #ifndef _SIDD_UNIT_MASK |
161 | #define _SIDD_UNIT_MASK 0x40 |
162 | #endif |
163 | |
164 | #endif |
165 | |
166 | // AVX intrinsics |
167 | #if defined(QT_HAVE_AVX) && (defined(__AVX__) || defined(Q_CC_MSVC)) |
168 | #include <immintrin.h> |
169 | #endif |
170 | |
171 | |
172 | #if !defined(QT_BOOTSTRAPPED) && (!defined(Q_CC_MSVC) || (defined(_M_X64) || _M_IX86_FP == 2)) |
173 | #define QT_ALWAYS_HAVE_SSE2 |
174 | #endif |
175 | #endif // defined(QT_HAVE_SSE2) && (defined(__SSE2__) || defined(Q_CC_MSVC)) |
176 | |
177 | // NEON intrinsics |
178 | #if defined __ARM_NEON__ |
179 | #define QT_ALWAYS_HAVE_NEON |
180 | #include <arm_neon.h> |
181 | #endif |
182 | |
183 | |
184 | // IWMMXT intrinsics |
185 | #if defined(QT_HAVE_IWMMXT) |
186 | #include <mmintrin.h> |
187 | #if defined(Q_OS_WINCE) |
188 | # include "qplatformdefs.h" |
189 | #endif |
190 | #endif |
191 | |
192 | #if defined(QT_HAVE_IWMMXT) |
193 | #if !defined(__IWMMXT__) && !defined(Q_OS_WINCE) |
194 | # include <xmmintrin.h> |
195 | #elif defined(Q_OS_WINCE_STD) && defined(_X86_) |
196 | # pragma warning(disable: 4391) |
197 | # include <xmmintrin.h> |
198 | #endif |
199 | #endif |
200 | |
201 | // 3D now intrinsics |
202 | #if defined(QT_HAVE_3DNOW) && (defined(__3dNOW__) || defined(Q_CC_MSVC)) |
203 | #include <mm3dnow.h> |
204 | #endif |
205 | |
206 | QT_BEGIN_NAMESPACE |
207 | |
208 | QT_MODULE(Core) |
209 | |
210 | enum CPUFeatures { |
211 | None = 0, |
212 | MMX = 0x1, |
213 | MMXEXT = 0x2, |
214 | MMX3DNOW = 0x4, |
215 | MMX3DNOWEXT = 0x8, |
216 | SSE = 0x10, |
217 | SSE2 = 0x20, |
218 | CMOV = 0x40, |
219 | IWMMXT = 0x80, |
220 | NEON = 0x100, |
221 | SSE3 = 0x200, |
222 | SSSE3 = 0x400, |
223 | SSE4_1 = 0x800, |
224 | SSE4_2 = 0x1000, |
225 | AVX = 0x2000 |
226 | }; |
227 | |
228 | Q_CORE_EXPORT uint qDetectCPUFeatures(); |
229 | |
230 | |
231 | #define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \ |
232 | for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i) |
233 | |
234 | QT_END_NAMESPACE |
235 | |
236 | QT_END_HEADER |
237 | |
238 | #endif // QSIMD_P_H |
239 | |