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 #endif 344 345 /* 346 NOTE: 347 GCC 4.6 added __BYTE_ORDER__, __ORDER_BIG_ENDIAN__, __ORDER_LITTLE_ENDIAN__ 348 and __ORDER_PDP_ENDIAN__ in SVN r165881. If you are using GCC 4.6 or newer, 349 this code will properly detect your target byte order; if you are not, and 350 the __LITTLE_ENDIAN__ or __BIG_ENDIAN__ macros are not defined, then this 351 code will fail to detect the target byte order. 352 */ 353 // Some processors support either endian format, try to detect which we are using. 354 #if !defined(Q_BYTE_ORDER) 355 # if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == Q_BIG_ENDIAN || __BYTE_ORDER__ == Q_LITTLE_ENDIAN) 356 // Reuse __BYTE_ORDER__ as-is, since our Q_*_ENDIAN #defines match the preprocessor defaults 357 # define Q_BYTE_ORDER __BYTE_ORDER__ 358 # elif defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN) 359 # define Q_BYTE_ORDER Q_BIG_ENDIAN 360 # elif defined(__LITTLE_ENDIAN__) || defined(_little_endian__) || defined(_LITTLE_ENDIAN) \ 361 || defined(WINAPI_FAMILY) // WinRT is always little-endian according to MSDN. 362 # define Q_BYTE_ORDER Q_LITTLE_ENDIAN 363 # else 364 # error "Unable to determine byte order!" 365 # endif 366 #endif 367 368 /* 369 Size of a pointer and the machine register size. We detect a 64-bit system by: 370 * GCC and compatible compilers (Clang, ICC on OS X and Windows) always define 371 __SIZEOF_POINTER__. This catches all known cases of ILP32 builds on 64-bit 372 processors. 373 * Most other Unix compilers define __LP64__ or _LP64 on 64-bit mode 374 (Long and Pointer 64-bit) 375 * If Q_PROCESSOR_WORDSIZE was defined above, it's assumed to match the pointer 376 size. 377 Otherwise, we assume to be 32-bit and then check in qglobal.cpp that it is right. 378 */ 379 380 #if defined __SIZEOF_POINTER__ 381 # define QT_POINTER_SIZE __SIZEOF_POINTER__ 382 #elif defined(__LP64__) || defined(_LP64) 383 # define QT_POINTER_SIZE 8 384 #elif defined(Q_PROCESSOR_WORDSIZE) 385 # define QT_POINTER_SIZE Q_PROCESSOR_WORDSIZE 386 #else 387 # define QT_POINTER_SIZE 4 388 #endif 389 390 /* 391 Define Q_PROCESSOR_WORDSIZE to be the size of the machine's word (usually, 392 the size of the register). On some architectures where a pointer could be 393 smaller than the register, the macro is defined above. 394 395 Falls back to QT_POINTER_SIZE if not set explicitly for the platform. 396 */ 397 #ifndef Q_PROCESSOR_WORDSIZE 398 # define Q_PROCESSOR_WORDSIZE QT_POINTER_SIZE 399 #endif 400 401 402 #endif // QPROCESSORDETECTION_H 403