cpu.hpp (5371B)
1 #ifndef _C4_CPU_HPP_ 2 #define _C4_CPU_HPP_ 3 4 /** @file cpu.hpp Provides processor information macros 5 * @ingroup basic_headers */ 6 7 // see also https://sourceforge.net/p/predef/wiki/Architectures/ 8 // see also https://sourceforge.net/p/predef/wiki/Endianness/ 9 // see also https://github.com/googlesamples/android-ndk/blob/android-mk/hello-jni/jni/hello-jni.c 10 // see http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/global/qprocessordetection.h 11 12 #ifdef __ORDER_LITTLE_ENDIAN__ 13 # define _C4EL __ORDER_LITTLE_ENDIAN__ 14 #else 15 # define _C4EL 1234 16 #endif 17 18 #ifdef __ORDER_BIG_ENDIAN__ 19 # define _C4EB __ORDER_BIG_ENDIAN__ 20 #else 21 # define _C4EB 4321 22 #endif 23 24 // mixed byte order (eg, PowerPC or ia64) 25 #define _C4EM 1111 26 27 #if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) 28 # define C4_CPU_X86_64 29 # define C4_WORDSIZE 8 30 # define C4_BYTE_ORDER _C4EL 31 32 #elif defined(__i386) || defined(__i386__) || defined(_M_IX86) 33 # define C4_CPU_X86 34 # define C4_WORDSIZE 4 35 # define C4_BYTE_ORDER _C4EL 36 37 #elif defined(__arm__) || defined(_M_ARM) \ 38 || defined(__TARGET_ARCH_ARM) || defined(__aarch64__) || defined(_M_ARM64) 39 # if defined(__aarch64__) || defined(_M_ARM64) 40 # define C4_CPU_ARM64 41 # define C4_CPU_ARMV8 42 # define C4_WORDSIZE 8 43 # else 44 # define C4_CPU_ARM 45 # define C4_WORDSIZE 4 46 # if defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__) \ 47 || (defined(__ARCH_ARM) && __ARCH_ARM >= 8) \ 48 || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 8) 49 # define C4_CPU_ARMV8 50 # elif defined(__ARM_ARCH_7__) || defined(_ARM_ARCH_7) \ 51 || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) \ 52 || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) \ 53 || defined(__ARM_ARCH_7EM__) \ 54 || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 7) \ 55 || (defined(_M_ARM) && _M_ARM >= 7) 56 # define C4_CPU_ARMV7 57 # elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ 58 || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) \ 59 || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) \ 60 || defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_6KZ__) \ 61 || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 6) 62 # define C4_CPU_ARMV6 63 # elif defined(__ARM_ARCH_5TEJ__) \ 64 || defined(__ARM_ARCH_5TE__) \ 65 || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 5) 66 # define C4_CPU_ARMV5 67 # elif defined(__ARM_ARCH_4T__) \ 68 || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 4) 69 # define C4_CPU_ARMV4 70 # else 71 # error "unknown CPU architecture: ARM" 72 # endif 73 # endif 74 # if defined(__ARMEL__) || defined(__LITTLE_ENDIAN__) || defined(__AARCH64EL__) \ 75 || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) \ 76 || defined(_MSC_VER) // winarm64 does not provide any of the above macros, 77 // but advises little-endianess: 78 // https://docs.microsoft.com/en-us/cpp/build/overview-of-arm-abi-conventions?view=msvc-170 79 // So if it is visual studio compiling, we'll assume little endian. 80 # define C4_BYTE_ORDER _C4EL 81 # elif defined(__ARMEB__) || defined(__BIG_ENDIAN__) || defined(__AARCH64EB__) \ 82 || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) 83 # define C4_BYTE_ORDER _C4EB 84 # elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_PDP_ENDIAN__) 85 # define C4_BYTE_ORDER _C4EM 86 # else 87 # error "unknown endianness" 88 # endif 89 90 #elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) 91 # define C4_CPU_IA64 92 # define C4_WORDSIZE 8 93 # define C4_BYTE_ORDER _C4EM 94 // itanium is bi-endian - check byte order below 95 96 #elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \ 97 || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \ 98 || defined(_M_MPPC) || defined(_M_PPC) 99 # if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) 100 # define C4_CPU_PPC64 101 # define C4_WORDSIZE 8 102 # else 103 # define C4_CPU_PPC 104 # define C4_WORDSIZE 4 105 # endif 106 # define C4_BYTE_ORDER _C4EM 107 // ppc is bi-endian - check byte order below 108 109 #elif defined(__s390x__) || defined(__zarch__) || defined(__SYSC_ZARCH_) 110 # define C4_CPU_S390_X 111 # define C4_WORDSIZE 8 112 # define C4_BYTE_ORDER _C4EB 113 114 #elif defined(__xtensa__) || defined(__XTENSA__) 115 # define C4_CPU_XTENSA 116 # define C4_WORDSIZE 4 117 // not sure about this... 118 # if defined(__XTENSA_EL__) || defined(__xtensa_el__) 119 # define C4_BYTE_ORDER _C4EL 120 # else 121 # define C4_BYTE_ORDER _C4EB 122 # endif 123 124 #elif defined(__riscv) 125 # if __riscv_xlen == 64 126 # define C4_CPU_RISCV64 127 # define C4_WORDSIZE 8 128 # else 129 # define C4_CPU_RISCV32 130 # define C4_WORDSIZE 4 131 # endif 132 # define C4_BYTE_ORDER _C4EL 133 134 #elif defined(__EMSCRIPTEN__) 135 # define C4_BYTE_ORDER _C4EL 136 # define C4_WORDSIZE 4 137 138 #elif defined(SWIG) 139 # error "please define CPU architecture macros when compiling with swig" 140 141 #else 142 # error "unknown CPU architecture" 143 #endif 144 145 #define C4_LITTLE_ENDIAN (C4_BYTE_ORDER == _C4EL) 146 #define C4_BIG_ENDIAN (C4_BYTE_ORDER == _C4EB) 147 #define C4_MIXED_ENDIAN (C4_BYTE_ORDER == _C4EM) 148 149 #endif /* _C4_CPU_HPP_ */