QtBase  v6.3.1
qprocessordetection.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #ifndef QGLOBAL_H
42 # include <QtCore/qglobal.h>
43 #endif
44 
45 #ifndef QPROCESSORDETECTION_H
46 #define QPROCESSORDETECTION_H
47 
48 /*
49  This file uses preprocessor #defines to set various Q_PROCESSOR_* #defines
50  based on the following patterns:
51 
52  Q_PROCESSOR_{FAMILY}
53  Q_PROCESSOR_{FAMILY}_{VARIANT}
54  Q_PROCESSOR_{FAMILY}_{REVISION}
55 
56  The first is always defined. Defines for the various revisions/variants are
57  optional and usually dependent on how the compiler was invoked. Variants
58  that are a superset of another should have a define for the superset.
59 
60  In addition to the processor family, variants, and revisions, we also set
61  Q_BYTE_ORDER appropriately for the target processor. For bi-endian
62  processors, we try to auto-detect the byte order using the __BIG_ENDIAN__,
63  __LITTLE_ENDIAN__, or __BYTE_ORDER__ preprocessor macros.
64 
65  Note: when adding support for new processors, be sure to update
66  config.tests/arch/arch.cpp to ensure that configure can detect the target
67  and host architectures.
68 */
69 
70 /* Machine byte-order, reuse preprocessor provided macros when available */
71 #if defined(__ORDER_BIG_ENDIAN__)
72 # define Q_BIG_ENDIAN __ORDER_BIG_ENDIAN__
73 #else
74 # define Q_BIG_ENDIAN 4321
75 #endif
76 #if defined(__ORDER_LITTLE_ENDIAN__)
77 # define Q_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
78 #else
79 # define Q_LITTLE_ENDIAN 1234
80 #endif
81 
82 /*
83  Alpha family, no revisions or variants
84 
85  Alpha is bi-endian, use endianness auto-detection implemented below.
86 */
87 // #elif defined(__alpha__) || defined(_M_ALPHA)
88 // # define Q_PROCESSOR_ALPHA
89 // Q_BYTE_ORDER not defined, use endianness auto-detection
90 
91 /*
92  ARM family, known revisions: V5, V6, V7, V8
93 
94  ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to
95  auto-detection implemented below.
96 */
97 #if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
98 # if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
99 # define Q_PROCESSOR_ARM_64
100 # define Q_PROCESSOR_WORDSIZE 8
101 # else
102 # define Q_PROCESSOR_ARM_32
103 # endif
104 # if defined(__ARM_ARCH) && __ARM_ARCH > 1
105 # define Q_PROCESSOR_ARM __ARM_ARCH
106 # elif defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM > 1
107 # define Q_PROCESSOR_ARM __TARGET_ARCH_ARM
108 # elif defined(_M_ARM) && _M_ARM > 1
109 # define Q_PROCESSOR_ARM _M_ARM
110 # elif defined(__ARM64_ARCH_8__) \
111  || defined(__aarch64__) \
112  || defined(__ARMv8__) \
113  || defined(__ARMv8_A__) \
114  || defined(_M_ARM64)
115 # define Q_PROCESSOR_ARM 8
116 # elif defined(__ARM_ARCH_7__) \
117  || defined(__ARM_ARCH_7A__) \
118  || defined(__ARM_ARCH_7R__) \
119  || defined(__ARM_ARCH_7M__) \
120  || defined(__ARM_ARCH_7S__) \
121  || defined(_ARM_ARCH_7) \
122  || defined(__CORE_CORTEXA__)
123 # define Q_PROCESSOR_ARM 7
124 # elif defined(__ARM_ARCH_6__) \
125  || defined(__ARM_ARCH_6J__) \
126  || defined(__ARM_ARCH_6T2__) \
127  || defined(__ARM_ARCH_6Z__) \
128  || defined(__ARM_ARCH_6K__) \
129  || defined(__ARM_ARCH_6ZK__) \
130  || defined(__ARM_ARCH_6M__)
131 # define Q_PROCESSOR_ARM 6
132 # elif defined(__ARM_ARCH_5TEJ__) \
133  || defined(__ARM_ARCH_5TE__)
134 # define Q_PROCESSOR_ARM 5
135 # else
136 # define Q_PROCESSOR_ARM 0
137 # endif
138 # if Q_PROCESSOR_ARM >= 8
139 # define Q_PROCESSOR_ARM_V8
140 # endif
141 # if Q_PROCESSOR_ARM >= 7
142 # define Q_PROCESSOR_ARM_V7
143 # endif
144 # if Q_PROCESSOR_ARM >= 6
145 # define Q_PROCESSOR_ARM_V6
146 # endif
147 # if Q_PROCESSOR_ARM >= 5
148 # define Q_PROCESSOR_ARM_V5
149 # else
150 # error "ARM architecture too old"
151 # endif
152 # if defined(__ARMEL__) || defined(_M_ARM64)
153 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
154 # elif defined(__ARMEB__)
155 # define Q_BYTE_ORDER Q_BIG_ENDIAN
156 # else
157 // Q_BYTE_ORDER not defined, use endianness auto-detection
158 #endif
159 
160 /*
161  AVR32 family, no revisions or variants
162 
163  AVR32 is big-endian.
164 */
165 // #elif defined(__avr32__)
166 // # define Q_PROCESSOR_AVR32
167 // # define Q_BYTE_ORDER Q_BIG_ENDIAN
168 
169 /*
170  Blackfin family, no revisions or variants
171 
172  Blackfin is little-endian.
173 */
174 // #elif defined(__bfin__)
175 // # define Q_PROCESSOR_BLACKFIN
176 // # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
177 
178 /*
179  X86 family, known variants: 32- and 64-bit
180 
181  X86 is little-endian.
182 */
183 #elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
184 # define Q_PROCESSOR_X86_32
185 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
186 # define Q_PROCESSOR_WORDSIZE 4
187 
188 /*
189  * We define Q_PROCESSOR_X86 == 6 for anything above a equivalent or better
190  * than a Pentium Pro (the processor whose architecture was called P6) or an
191  * Athlon.
192  *
193  * All processors since the Pentium III and the Athlon 4 have SSE support, so
194  * we use that to detect. That leaves the original Athlon, Pentium Pro and
195  * Pentium II.
196  */
197 
198 # if defined(_M_IX86)
199 # define Q_PROCESSOR_X86 (_M_IX86/100)
200 # elif defined(__i686__) || defined(__athlon__) || defined(__SSE__) || defined(__pentiumpro__)
201 # define Q_PROCESSOR_X86 6
202 # elif defined(__i586__) || defined(__k6__) || defined(__pentium__)
203 # define Q_PROCESSOR_X86 5
204 # elif defined(__i486__) || defined(__80486__)
205 # define Q_PROCESSOR_X86 4
206 # else
207 # define Q_PROCESSOR_X86 3
208 # endif
209 
210 #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
211 # define Q_PROCESSOR_X86 6
212 # define Q_PROCESSOR_X86_64
213 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
214 # define Q_PROCESSOR_WORDSIZE 8
215 
216 /*
217  Itanium (IA-64) family, no revisions or variants
218 
219  Itanium is bi-endian, use endianness auto-detection implemented below.
220 */
221 #elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
222 # define Q_PROCESSOR_IA64
223 # define Q_PROCESSOR_WORDSIZE 8
224 // Q_BYTE_ORDER not defined, use endianness auto-detection
225 
226 /*
227  MIPS family, known revisions: I, II, III, IV, 32, 64
228 
229  MIPS is bi-endian, use endianness auto-detection implemented below.
230 */
231 #elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
232 # define Q_PROCESSOR_MIPS
233 # if defined(_MIPS_ARCH_MIPS1) || (defined(__mips) && __mips - 0 >= 1)
234 # define Q_PROCESSOR_MIPS_I
235 # endif
236 # if defined(_MIPS_ARCH_MIPS2) || (defined(__mips) && __mips - 0 >= 2)
237 # define Q_PROCESSOR_MIPS_II
238 # endif
239 # if defined(_MIPS_ARCH_MIPS3) || (defined(__mips) && __mips - 0 >= 3)
240 # define Q_PROCESSOR_MIPS_III
241 # endif
242 # if defined(_MIPS_ARCH_MIPS4) || (defined(__mips) && __mips - 0 >= 4)
243 # define Q_PROCESSOR_MIPS_IV
244 # endif
245 # if defined(_MIPS_ARCH_MIPS5) || (defined(__mips) && __mips - 0 >= 5)
246 # define Q_PROCESSOR_MIPS_V
247 # endif
248 # if defined(_MIPS_ARCH_MIPS32) || defined(__mips32) || (defined(__mips) && __mips - 0 >= 32)
249 # define Q_PROCESSOR_MIPS_32
250 # endif
251 # if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
252 # define Q_PROCESSOR_MIPS_64
253 # define Q_PROCESSOR_WORDSIZE 8
254 # endif
255 # if defined(__MIPSEL__)
256 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
257 # elif defined(__MIPSEB__)
258 # define Q_BYTE_ORDER Q_BIG_ENDIAN
259 # else
260 // Q_BYTE_ORDER not defined, use endianness auto-detection
261 # endif
262 
263 /*
264  Power family, known variants: 32- and 64-bit
265 
266  There are many more known variants/revisions that we do not handle/detect.
267  See http://en.wikipedia.org/wiki/Power_Architecture
268  and http://en.wikipedia.org/wiki/File:PowerISA-evolution.svg
269 
270  Power is bi-endian, use endianness auto-detection implemented below.
271 */
272 #elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \
273  || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \
274  || defined(_M_MPPC) || defined(_M_PPC)
275 # define Q_PROCESSOR_POWER
276 # if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
277 # define Q_PROCESSOR_POWER_64
278 # define Q_PROCESSOR_WORDSIZE 8
279 # else
280 # define Q_PROCESSOR_POWER_32
281 # endif
282 // Q_BYTE_ORDER not defined, use endianness auto-detection
283 
284 /*
285  RISC-V family, known variants: 32- and 64-bit
286 
287  RISC-V is little-endian.
288 */
289 #elif defined(__riscv)
290 # define Q_PROCESSOR_RISCV
291 # if __riscv_xlen == 64
292 # define Q_PROCESSOR_RISCV_64
293 # else
294 # define Q_PROCESSOR_RISCV_32
295 # endif
296 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
297 
298 /*
299  S390 family, known variant: S390X (64-bit)
300 
301  S390 is big-endian.
302 */
303 #elif defined(__s390__)
304 # define Q_PROCESSOR_S390
305 # if defined(__s390x__)
306 # define Q_PROCESSOR_S390_X
307 # endif
308 # define Q_BYTE_ORDER Q_BIG_ENDIAN
309 
310 /*
311  SuperH family, optional revision: SH-4A
312 
313  SuperH is bi-endian, use endianness auto-detection implemented below.
314 */
315 // #elif defined(__sh__)
316 // # define Q_PROCESSOR_SH
317 // # if defined(__sh4a__)
318 // # define Q_PROCESSOR_SH_4A
319 // # endif
320 // Q_BYTE_ORDER not defined, use endianness auto-detection
321 
322 /*
323  SPARC family, optional revision: V9
324 
325  SPARC is big-endian only prior to V9, while V9 is bi-endian with big-endian
326  as the default byte order. Assume all SPARC systems are big-endian.
327 */
328 #elif defined(__sparc__)
329 # define Q_PROCESSOR_SPARC
330 # if defined(__sparc_v9__)
331 # define Q_PROCESSOR_SPARC_V9
332 # endif
333 # if defined(__sparc64__)
334 # define Q_PROCESSOR_SPARC_64
335 # endif
336 # define Q_BYTE_ORDER Q_BIG_ENDIAN
337 
338 // -- Web Assembly --
339 #elif defined(__EMSCRIPTEN__)
340 # define Q_PROCESSOR_WASM
341 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
342 # define Q_PROCESSOR_WORDSIZE 8
343 #ifdef QT_COMPILER_SUPPORTS_SSE2
344 # define Q_PROCESSOR_X86 6 // enables SIMD support
345 #endif
346 
347 #endif
348 
349 /*
350  NOTE:
351  GCC 4.6 added __BYTE_ORDER__, __ORDER_BIG_ENDIAN__, __ORDER_LITTLE_ENDIAN__
352  and __ORDER_PDP_ENDIAN__ in SVN r165881. If you are using GCC 4.6 or newer,
353  this code will properly detect your target byte order; if you are not, and
354  the __LITTLE_ENDIAN__ or __BIG_ENDIAN__ macros are not defined, then this
355  code will fail to detect the target byte order.
356 */
357 // Some processors support either endian format, try to detect which we are using.
358 #if !defined(Q_BYTE_ORDER)
359 # if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == Q_BIG_ENDIAN || __BYTE_ORDER__ == Q_LITTLE_ENDIAN)
360 // Reuse __BYTE_ORDER__ as-is, since our Q_*_ENDIAN #defines match the preprocessor defaults
361 # define Q_BYTE_ORDER __BYTE_ORDER__
362 # elif defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN)
363 # define Q_BYTE_ORDER Q_BIG_ENDIAN
364 # elif defined(__LITTLE_ENDIAN__) || defined(_little_endian__) || defined(_LITTLE_ENDIAN)
365 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
366 # else
367 # error "Unable to determine byte order!"
368 # endif
369 #endif
370 
371 /*
372  Size of a pointer and the machine register size. We detect a 64-bit system by:
373  * GCC and compatible compilers (Clang, ICC on OS X and Windows) always define
374  __SIZEOF_POINTER__. This catches all known cases of ILP32 builds on 64-bit
375  processors.
376  * Most other Unix compilers define __LP64__ or _LP64 on 64-bit mode
377  (Long and Pointer 64-bit)
378  * If Q_PROCESSOR_WORDSIZE was defined above, it's assumed to match the pointer
379  size.
380  Otherwise, we assume to be 32-bit and then check in qglobal.cpp that it is right.
381 */
382 
383 #if defined __SIZEOF_POINTER__
384 # define QT_POINTER_SIZE __SIZEOF_POINTER__
385 #elif defined(__LP64__) || defined(_LP64)
386 # define QT_POINTER_SIZE 8
387 #elif defined(Q_PROCESSOR_WORDSIZE)
388 # define QT_POINTER_SIZE Q_PROCESSOR_WORDSIZE
389 #else
390 # define QT_POINTER_SIZE 4
391 #endif
392 
393 /*
394  Define Q_PROCESSOR_WORDSIZE to be the size of the machine's word (usually,
395  the size of the register). On some architectures where a pointer could be
396  smaller than the register, the macro is defined above.
397 
398  Falls back to QT_POINTER_SIZE if not set explicitly for the platform.
399 */
400 #ifndef Q_PROCESSOR_WORDSIZE
401 # define Q_PROCESSOR_WORDSIZE QT_POINTER_SIZE
402 #endif
403 
404 
405 #endif // QPROCESSORDETECTION_H