]>
Commit | Line | Data |
---|---|---|
1e230224 | 1 | /* CpuArch.h -- CPU specific code\r |
7e6776de | 2 | 2018-02-18 : Igor Pavlov : Public domain */\r |
11ff2c71 | 3 | \r |
1e230224 LG |
4 | #ifndef __CPU_ARCH_H\r |
5 | #define __CPU_ARCH_H\r | |
6 | \r | |
7 | #include "7zTypes.h"\r | |
8 | \r | |
9 | EXTERN_C_BEGIN\r | |
11ff2c71 LG |
10 | \r |
11 | /*\r | |
1e230224 LG |
12 | MY_CPU_LE means that CPU is LITTLE ENDIAN.\r |
13 | MY_CPU_BE means that CPU is BIG ENDIAN.\r | |
14 | If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.\r | |
15 | \r | |
16 | MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.\r | |
11ff2c71 LG |
17 | */\r |
18 | \r | |
1436aea4 MK |
19 | #if defined (_M_X64) \\r |
20 | || defined (_M_AMD64) \\r | |
21 | || defined (__x86_64__) \\r | |
22 | || defined (__AMD64__) \\r | |
23 | || defined (__amd64__)\r | |
24 | #define MY_CPU_AMD64\r | |
f0737de8 | 25 | #ifdef __ILP32__\r |
1436aea4 | 26 | #define MY_CPU_NAME "x32"\r |
f0737de8 | 27 | #else\r |
1436aea4 | 28 | #define MY_CPU_NAME "x64"\r |
f0737de8 | 29 | #endif\r |
1436aea4 | 30 | #define MY_CPU_64BIT\r |
1e230224 LG |
31 | #endif\r |
32 | \r | |
1436aea4 MK |
33 | #if defined (_M_IX86) \\r |
34 | || defined (__i386__)\r | |
35 | #define MY_CPU_X86\r | |
36 | #define MY_CPU_NAME "x86"\r | |
37 | #define MY_CPU_32BIT\r | |
f0737de8 LG |
38 | #endif\r |
39 | \r | |
1436aea4 MK |
40 | #if defined (_M_ARM64) \\r |
41 | || defined (__AARCH64EL__) \\r | |
42 | || defined (__AARCH64EB__) \\r | |
43 | || defined (__aarch64__)\r | |
44 | #define MY_CPU_ARM64\r | |
45 | #define MY_CPU_NAME "arm64"\r | |
46 | #define MY_CPU_64BIT\r | |
1e230224 LG |
47 | #endif\r |
48 | \r | |
1436aea4 MK |
49 | #if defined (_M_ARM) \\r |
50 | || defined (_M_ARM_NT) \\r | |
51 | || defined (_M_ARMT) \\r | |
52 | || defined (__arm__) \\r | |
53 | || defined (__thumb__) \\r | |
54 | || defined (__ARMEL__) \\r | |
55 | || defined (__ARMEB__) \\r | |
56 | || defined (__THUMBEL__) \\r | |
57 | || defined (__THUMBEB__)\r | |
58 | #define MY_CPU_ARM\r | |
59 | #define MY_CPU_NAME "arm"\r | |
60 | #define MY_CPU_32BIT\r | |
1e230224 LG |
61 | #endif\r |
62 | \r | |
1436aea4 MK |
63 | #if defined (_M_IA64) \\r |
64 | || defined (__ia64__)\r | |
65 | #define MY_CPU_IA64\r | |
66 | #define MY_CPU_NAME "ia64"\r | |
67 | #define MY_CPU_64BIT\r | |
1e230224 LG |
68 | #endif\r |
69 | \r | |
1436aea4 MK |
70 | #if defined (__mips64) \\r |
71 | || defined (__mips64__) \\r | |
72 | || (defined (__mips) && (__mips == 64 || __mips == 4 || __mips == 3))\r | |
73 | #define MY_CPU_NAME "mips64"\r | |
74 | #define MY_CPU_64BIT\r | |
75 | #elif defined (__mips__)\r | |
76 | #define MY_CPU_NAME "mips"\r | |
77 | /* #define MY_CPU_32BIT */\r | |
f0737de8 LG |
78 | #endif\r |
79 | \r | |
1436aea4 MK |
80 | #if defined (__ppc64__) \\r |
81 | || defined (__powerpc64__)\r | |
f0737de8 | 82 | #ifdef __ILP32__\r |
1436aea4 | 83 | #define MY_CPU_NAME "ppc64-32"\r |
f0737de8 | 84 | #else\r |
1436aea4 | 85 | #define MY_CPU_NAME "ppc64"\r |
f0737de8 | 86 | #endif\r |
1436aea4 MK |
87 | #define MY_CPU_64BIT\r |
88 | #elif defined (__ppc__) \\r | |
89 | || defined (__powerpc__)\r | |
90 | #define MY_CPU_NAME "ppc"\r | |
91 | #define MY_CPU_32BIT\r | |
1e230224 LG |
92 | #endif\r |
93 | \r | |
1436aea4 MK |
94 | #if defined (__sparc64__)\r |
95 | #define MY_CPU_NAME "sparc64"\r | |
96 | #define MY_CPU_64BIT\r | |
97 | #elif defined (__sparc__)\r | |
98 | #define MY_CPU_NAME "sparc"\r | |
99 | /* #define MY_CPU_32BIT */\r | |
11ff2c71 LG |
100 | #endif\r |
101 | \r | |
1436aea4 | 102 | #if defined (MY_CPU_X86) || defined (MY_CPU_AMD64)\r |
f0737de8 | 103 | #define MY_CPU_X86_OR_AMD64\r |
1e230224 LG |
104 | #endif\r |
105 | \r | |
f0737de8 LG |
106 | #ifdef _WIN32\r |
107 | \r | |
108 | #ifdef MY_CPU_ARM\r | |
1436aea4 | 109 | #define MY_CPU_ARM_LE\r |
f0737de8 LG |
110 | #endif\r |
111 | \r | |
112 | #ifdef MY_CPU_ARM64\r | |
1436aea4 | 113 | #define MY_CPU_ARM64_LE\r |
f0737de8 LG |
114 | #endif\r |
115 | \r | |
116 | #ifdef _M_IA64\r | |
1436aea4 | 117 | #define MY_CPU_IA64_LE\r |
f0737de8 LG |
118 | #endif\r |
119 | \r | |
120 | #endif\r | |
121 | \r | |
1436aea4 MK |
122 | #if defined (MY_CPU_X86_OR_AMD64) \\r |
123 | || defined (MY_CPU_ARM_LE) \\r | |
124 | || defined (MY_CPU_ARM64_LE) \\r | |
125 | || defined (MY_CPU_IA64_LE) \\r | |
126 | || defined (__LITTLE_ENDIAN__) \\r | |
127 | || defined (__ARMEL__) \\r | |
128 | || defined (__THUMBEL__) \\r | |
129 | || defined (__AARCH64EL__) \\r | |
130 | || defined (__MIPSEL__) \\r | |
131 | || defined (__MIPSEL) \\r | |
132 | || defined (_MIPSEL) \\r | |
133 | || defined (__BFIN__) \\r | |
134 | || (defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))\r | |
135 | #define MY_CPU_LE\r | |
1e230224 LG |
136 | #endif\r |
137 | \r | |
1436aea4 MK |
138 | #if defined (__BIG_ENDIAN__) \\r |
139 | || defined (__ARMEB__) \\r | |
140 | || defined (__THUMBEB__) \\r | |
141 | || defined (__AARCH64EB__) \\r | |
142 | || defined (__MIPSEB__) \\r | |
143 | || defined (__MIPSEB) \\r | |
144 | || defined (_MIPSEB) \\r | |
145 | || defined (__m68k__) \\r | |
146 | || defined (__s390__) \\r | |
147 | || defined (__s390x__) \\r | |
148 | || defined (__zarch__) \\r | |
149 | || (defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))\r | |
150 | #define MY_CPU_BE\r | |
1e230224 LG |
151 | #endif\r |
152 | \r | |
1436aea4 | 153 | #if defined (MY_CPU_LE) && defined (MY_CPU_BE)\r |
f0737de8 LG |
154 | #error Stop_Compiling_Bad_Endian\r |
155 | #endif\r | |
156 | \r | |
1436aea4 | 157 | #if defined (MY_CPU_32BIT) && defined (MY_CPU_64BIT)\r |
f0737de8 | 158 | #error Stop_Compiling_Bad_32_64_BIT\r |
1e230224 LG |
159 | #endif\r |
160 | \r | |
f0737de8 LG |
161 | #ifndef MY_CPU_NAME\r |
162 | #ifdef MY_CPU_LE\r | |
1436aea4 MK |
163 | #define MY_CPU_NAME "LE"\r |
164 | #elif defined (MY_CPU_BE)\r | |
165 | #define MY_CPU_NAME "BE"\r | |
f0737de8 | 166 | #else\r |
1436aea4 MK |
167 | \r |
168 | /*\r | |
169 | #define MY_CPU_NAME ""\r | |
170 | */\r | |
f0737de8 LG |
171 | #endif\r |
172 | #endif\r | |
173 | \r | |
1e230224 | 174 | #ifdef MY_CPU_LE\r |
1436aea4 MK |
175 | #if defined (MY_CPU_X86_OR_AMD64) \\r |
176 | || defined (MY_CPU_ARM64) \\r | |
177 | || defined (__ARM_FEATURE_UNALIGNED)\r | |
178 | #define MY_CPU_LE_UNALIGN\r | |
1e230224 LG |
179 | #endif\r |
180 | #endif\r | |
181 | \r | |
1e230224 | 182 | #ifdef MY_CPU_LE_UNALIGN\r |
11ff2c71 | 183 | \r |
1436aea4 MK |
184 | #define GetUi16(p) (*(const UInt16 *)(const void *)(p))\r |
185 | #define GetUi32(p) (*(const UInt32 *)(const void *)(p))\r | |
186 | #define GetUi64(p) (*(const UInt64 *)(const void *)(p))\r | |
1e230224 | 187 | \r |
1436aea4 MK |
188 | #define SetUi16(p, v) { *(UInt16 *)(p) = (v); }\r |
189 | #define SetUi32(p, v) { *(UInt32 *)(p) = (v); }\r | |
190 | #define SetUi64(p, v) { *(UInt64 *)(p) = (v); }\r | |
11ff2c71 LG |
191 | \r |
192 | #else\r | |
193 | \r | |
1436aea4 | 194 | #define GetUi16(p) ( (UInt16) (\\r |
1e230224 LG |
195 | ((const Byte *)(p))[0] | \\r |
196 | ((UInt16)((const Byte *)(p))[1] << 8) ))\r | |
11ff2c71 | 197 | \r |
1436aea4 | 198 | #define GetUi32(p) (\\r |
11ff2c71 LG |
199 | ((const Byte *)(p))[0] | \\r |
200 | ((UInt32)((const Byte *)(p))[1] << 8) | \\r | |
201 | ((UInt32)((const Byte *)(p))[2] << 16) | \\r | |
202 | ((UInt32)((const Byte *)(p))[3] << 24))\r | |
203 | \r | |
1436aea4 | 204 | #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))\r |
11ff2c71 | 205 | \r |
1436aea4 | 206 | #define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v);\\r |
1e230224 LG |
207 | _ppp_[0] = (Byte)_vvv_; \\r |
208 | _ppp_[1] = (Byte)(_vvv_ >> 8); }\r | |
209 | \r | |
1436aea4 | 210 | #define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v);\\r |
1e230224 LG |
211 | _ppp_[0] = (Byte)_vvv_; \\r |
212 | _ppp_[1] = (Byte)(_vvv_ >> 8); \\r | |
213 | _ppp_[2] = (Byte)(_vvv_ >> 16); \\r | |
214 | _ppp_[3] = (Byte)(_vvv_ >> 24); }\r | |
215 | \r | |
1436aea4 | 216 | #define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v);\\r |
1e230224 LG |
217 | SetUi32(_ppp2_ , (UInt32)_vvv2_); \\r |
218 | SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }\r | |
11ff2c71 LG |
219 | \r |
220 | #endif\r | |
221 | \r | |
f0737de8 | 222 | #ifdef __has_builtin\r |
1436aea4 | 223 | #define MY__has_builtin(x) __has_builtin(x)\r |
f0737de8 | 224 | #else\r |
1436aea4 | 225 | #define MY__has_builtin(x) 0\r |
f0737de8 | 226 | #endif\r |
1e230224 | 227 | \r |
1436aea4 | 228 | #if defined (MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)\r |
1e230224 LG |
229 | \r |
230 | /* Note: we use bswap instruction, that is unsupported in 386 cpu */\r | |
231 | \r | |
1436aea4 | 232 | #include <stdlib.h>\r |
11ff2c71 | 233 | \r |
1436aea4 MK |
234 | #pragma intrinsic(_byteswap_ushort)\r |
235 | #pragma intrinsic(_byteswap_ulong)\r | |
236 | #pragma intrinsic(_byteswap_uint64)\r | |
f0737de8 LG |
237 | \r |
238 | /* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */\r | |
1436aea4 MK |
239 | #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))\r |
240 | #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))\r | |
11ff2c71 | 241 | \r |
1436aea4 | 242 | #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)\r |
1e230224 | 243 | \r |
1436aea4 MK |
244 | #elif defined (MY_CPU_LE_UNALIGN) && ( \\r |
245 | (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \\r | |
246 | || (defined (__clang__) && MY__has_builtin (__builtin_bswap16)))\r | |
1e230224 | 247 | \r |
f0737de8 | 248 | /* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */\r |
1436aea4 MK |
249 | #define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))\r |
250 | #define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))\r | |
1e230224 | 251 | \r |
1436aea4 | 252 | #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)\r |
1e230224 | 253 | \r |
11ff2c71 LG |
254 | #else\r |
255 | \r | |
1436aea4 | 256 | #define GetBe32(p) (\\r |
11ff2c71 LG |
257 | ((UInt32)((const Byte *)(p))[0] << 24) | \\r |
258 | ((UInt32)((const Byte *)(p))[1] << 16) | \\r | |
259 | ((UInt32)((const Byte *)(p))[2] << 8) | \\r | |
260 | ((const Byte *)(p))[3] )\r | |
261 | \r | |
1436aea4 | 262 | #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))\r |
11ff2c71 | 263 | \r |
1436aea4 | 264 | #define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v);\\r |
1e230224 LG |
265 | _ppp_[0] = (Byte)(_vvv_ >> 24); \\r |
266 | _ppp_[1] = (Byte)(_vvv_ >> 16); \\r | |
267 | _ppp_[2] = (Byte)(_vvv_ >> 8); \\r | |
268 | _ppp_[3] = (Byte)_vvv_; }\r | |
269 | \r | |
270 | #endif\r | |
271 | \r | |
f0737de8 LG |
272 | #ifndef GetBe16\r |
273 | \r | |
1436aea4 | 274 | #define GetBe16(p) ( (UInt16) (\\r |
1e230224 LG |
275 | ((UInt16)((const Byte *)(p))[0] << 8) | \\r |
276 | ((const Byte *)(p))[1] ))\r | |
277 | \r | |
f0737de8 LG |
278 | #endif\r |
279 | \r | |
1e230224 LG |
280 | #ifdef MY_CPU_X86_OR_AMD64\r |
281 | \r | |
1436aea4 MK |
282 | typedef struct {\r |
283 | UInt32 maxFunc;\r | |
284 | UInt32 vendor[3];\r | |
285 | UInt32 ver;\r | |
286 | UInt32 b;\r | |
287 | UInt32 c;\r | |
288 | UInt32 d;\r | |
1e230224 LG |
289 | } Cx86cpuid;\r |
290 | \r | |
1436aea4 | 291 | enum {\r |
1e230224 LG |
292 | CPU_FIRM_INTEL,\r |
293 | CPU_FIRM_AMD,\r | |
294 | CPU_FIRM_VIA\r | |
295 | };\r | |
296 | \r | |
1436aea4 MK |
297 | void\r |
298 | MyCPUID (\r | |
299 | UInt32 function,\r | |
300 | UInt32 *a,\r | |
301 | UInt32 *b,\r | |
302 | UInt32 *c,\r | |
303 | UInt32 *d\r | |
304 | );\r | |
305 | \r | |
306 | BoolInt\r | |
307 | x86cpuid_CheckAndRead (\r | |
308 | Cx86cpuid *p\r | |
309 | );\r | |
310 | \r | |
311 | int\r | |
312 | x86cpuid_GetFirm (\r | |
313 | const Cx86cpuid *p\r | |
314 | );\r | |
315 | \r | |
316 | #define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))\r | |
317 | #define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))\r | |
318 | #define x86cpuid_GetStepping(ver) (ver & 0xF)\r | |
319 | \r | |
320 | BoolInt\r | |
321 | CPU_Is_InOrder (\r | |
322 | );\r | |
323 | \r | |
324 | BoolInt\r | |
325 | CPU_Is_Aes_Supported (\r | |
326 | );\r | |
327 | \r | |
328 | BoolInt\r | |
329 | CPU_IsSupported_PageGB (\r | |
330 | );\r | |
1e230224 | 331 | \r |
11ff2c71 LG |
332 | #endif\r |
333 | \r | |
1e230224 | 334 | EXTERN_C_END\r |
11ff2c71 LG |
335 | \r |
336 | #endif\r |