Parolin 0.7.9 6796
Console (soon DLLs) to do a tar like job
Loading...
Searching...
No Matches
CpuArch.h
Go to the documentation of this file.
1/* CpuArch.h -- CPU specific code
22023-04-02 : Igor Pavlov : Public domain */
3
4#ifndef ZIP7_INC_CPU_ARCH_H
5#define ZIP7_INC_CPU_ARCH_H
6
7#include "7zTypes.h"
8
10
11/*
12MY_CPU_LE means that CPU is LITTLE ENDIAN.
13MY_CPU_BE means that CPU is BIG ENDIAN.
14If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
15
16MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
17
18MY_CPU_64BIT means that processor can work with 64-bit registers.
19 MY_CPU_64BIT can be used to select fast code branch
20 MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8)
21*/
22
23#if defined(_M_X64) \
24 || defined(_M_AMD64) \
25 || defined(__x86_64__) \
26 || defined(__AMD64__) \
27 || defined(__amd64__)
28 #define MY_CPU_AMD64
29 #ifdef __ILP32__
30 #define MY_CPU_NAME "x32"
31 #define MY_CPU_SIZEOF_POINTER 4
32 #else
33 #define MY_CPU_NAME "x64"
34 #define MY_CPU_SIZEOF_POINTER 8
35 #endif
36 #define MY_CPU_64BIT
37#endif
38
39
40#if defined(_M_IX86) \
41 || defined(__i386__)
42 #define MY_CPU_X86
43 #define MY_CPU_NAME "x86"
44 /* #define MY_CPU_32BIT */
45 #define MY_CPU_SIZEOF_POINTER 4
46#endif
47
48
49#if defined(_M_ARM64) \
50 || defined(__AARCH64EL__) \
51 || defined(__AARCH64EB__) \
52 || defined(__aarch64__)
53 #define MY_CPU_ARM64
54 #ifdef __ILP32__
55 #define MY_CPU_NAME "arm64-32"
56 #define MY_CPU_SIZEOF_POINTER 4
57 #else
58 #define MY_CPU_NAME "arm64"
59 #define MY_CPU_SIZEOF_POINTER 8
60 #endif
61 #define MY_CPU_64BIT
62#endif
63
64
65#if defined(_M_ARM) \
66 || defined(_M_ARM_NT) \
67 || defined(_M_ARMT) \
68 || defined(__arm__) \
69 || defined(__thumb__) \
70 || defined(__ARMEL__) \
71 || defined(__ARMEB__) \
72 || defined(__THUMBEL__) \
73 || defined(__THUMBEB__)
74 #define MY_CPU_ARM
75
76 #if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT)
77 #define MY_CPU_ARMT
78 #define MY_CPU_NAME "armt"
79 #else
80 #define MY_CPU_ARM32
81 #define MY_CPU_NAME "arm"
82 #endif
83 /* #define MY_CPU_32BIT */
84 #define MY_CPU_SIZEOF_POINTER 4
85#endif
86
87
88#if defined(_M_IA64) \
89 || defined(__ia64__)
90 #define MY_CPU_IA64
91 #define MY_CPU_NAME "ia64"
92 #define MY_CPU_64BIT
93#endif
94
95
96#if defined(__mips64) \
97 || defined(__mips64__) \
98 || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
99 #define MY_CPU_NAME "mips64"
100 #define MY_CPU_64BIT
101#elif defined(__mips__)
102 #define MY_CPU_NAME "mips"
103 /* #define MY_CPU_32BIT */
104#endif
105
106
107#if defined(__ppc64__) \
108 || defined(__powerpc64__) \
109 || defined(__ppc__) \
110 || defined(__powerpc__) \
111 || defined(__PPC__) \
112 || defined(_POWER)
113
114#define MY_CPU_PPC_OR_PPC64
115
116#if defined(__ppc64__) \
117 || defined(__powerpc64__) \
118 || defined(_LP64) \
119 || defined(__64BIT__)
120 #ifdef __ILP32__
121 #define MY_CPU_NAME "ppc64-32"
122 #define MY_CPU_SIZEOF_POINTER 4
123 #else
124 #define MY_CPU_NAME "ppc64"
125 #define MY_CPU_SIZEOF_POINTER 8
126 #endif
127 #define MY_CPU_64BIT
128#else
129 #define MY_CPU_NAME "ppc"
130 #define MY_CPU_SIZEOF_POINTER 4
131 /* #define MY_CPU_32BIT */
132#endif
133#endif
134
135
136#if defined(__riscv) \
137 || defined(__riscv__)
138 #if __riscv_xlen == 32
139 #define MY_CPU_NAME "riscv32"
140 #elif __riscv_xlen == 64
141 #define MY_CPU_NAME "riscv64"
142 #else
143 #define MY_CPU_NAME "riscv"
144 #endif
145#endif
146
147
148#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
149#define MY_CPU_X86_OR_AMD64
150#endif
151
152#if defined(MY_CPU_ARM) || defined(MY_CPU_ARM64)
153#define MY_CPU_ARM_OR_ARM64
154#endif
155
156
157#ifdef _WIN32
158
159 #ifdef MY_CPU_ARM
160 #define MY_CPU_ARM_LE
161 #endif
162
163 #ifdef MY_CPU_ARM64
164 #define MY_CPU_ARM64_LE
165 #endif
166
167 #ifdef _M_IA64
168 #define MY_CPU_IA64_LE
169 #endif
170
171#endif
172
173
174#if defined(MY_CPU_X86_OR_AMD64) \
175 || defined(MY_CPU_ARM_LE) \
176 || defined(MY_CPU_ARM64_LE) \
177 || defined(MY_CPU_IA64_LE) \
178 || defined(__LITTLE_ENDIAN__) \
179 || defined(__ARMEL__) \
180 || defined(__THUMBEL__) \
181 || defined(__AARCH64EL__) \
182 || defined(__MIPSEL__) \
183 || defined(__MIPSEL) \
184 || defined(_MIPSEL) \
185 || defined(__BFIN__) \
186 || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
187 #define MY_CPU_LE
188#endif
189
190#if defined(__BIG_ENDIAN__) \
191 || defined(__ARMEB__) \
192 || defined(__THUMBEB__) \
193 || defined(__AARCH64EB__) \
194 || defined(__MIPSEB__) \
195 || defined(__MIPSEB) \
196 || defined(_MIPSEB) \
197 || defined(__m68k__) \
198 || defined(__s390__) \
199 || defined(__s390x__) \
200 || defined(__zarch__) \
201 || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
202 #define MY_CPU_BE
203#endif
204
205
206#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
207 #error Stop_Compiling_Bad_Endian
208#endif
209
210#if !defined(MY_CPU_LE) && !defined(MY_CPU_BE)
211 #error Stop_Compiling_CPU_ENDIAN_must_be_detected_at_compile_time
212#endif
213
214#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
215 #error Stop_Compiling_Bad_32_64_BIT
216#endif
217
218#ifdef __SIZEOF_POINTER__
219 #ifdef MY_CPU_SIZEOF_POINTER
220 #if MY_CPU_SIZEOF_POINTER != __SIZEOF_POINTER__
221 #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE
222 #endif
223 #else
224 #define MY_CPU_SIZEOF_POINTER __SIZEOF_POINTER__
225 #endif
226#endif
227
228#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
229#if defined (_LP64)
230 #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE
231#endif
232#endif
233
234#ifdef _MSC_VER
235 #if _MSC_VER >= 1300
236 #define MY_CPU_pragma_pack_push_1 __pragma(pack(push, 1))
237 #define MY_CPU_pragma_pop __pragma(pack(pop))
238 #else
239 #define MY_CPU_pragma_pack_push_1
240 #define MY_CPU_pragma_pop
241 #endif
242#else
243 #ifdef __xlC__
244 #define MY_CPU_pragma_pack_push_1 _Pragma("pack(1)")
245 #define MY_CPU_pragma_pop _Pragma("pack()")
246 #else
247 #define MY_CPU_pragma_pack_push_1 _Pragma("pack(push, 1)")
248 #define MY_CPU_pragma_pop _Pragma("pack(pop)")
249 #endif
250#endif
251
252
253#ifndef MY_CPU_NAME
254 #ifdef MY_CPU_LE
255 #define MY_CPU_NAME "LE"
256 #elif defined(MY_CPU_BE)
257 #define MY_CPU_NAME "BE"
258 #else
259 /*
260 #define MY_CPU_NAME ""
261 */
262 #endif
263#endif
264
265
266
267
268
269#ifdef __has_builtin
270 #define Z7_has_builtin(x) __has_builtin(x)
271#else
272 #define Z7_has_builtin(x) 0
273#endif
274
275
276#define Z7_BSWAP32_CONST(v) \
277 ( (((UInt32)(v) << 24) ) \
278 | (((UInt32)(v) << 8) & (UInt32)0xff0000) \
279 | (((UInt32)(v) >> 8) & (UInt32)0xff00 ) \
280 | (((UInt32)(v) >> 24) ))
281
282
283#if defined(_MSC_VER) && (_MSC_VER >= 1300)
284
285#include <stdlib.h>
286
287/* Note: these macros will use bswap instruction (486), that is unsupported in 386 cpu */
288
289#pragma intrinsic(_byteswap_ushort)
290#pragma intrinsic(_byteswap_ulong)
291#pragma intrinsic(_byteswap_uint64)
292
293#define Z7_BSWAP16(v) _byteswap_ushort(v)
294#define Z7_BSWAP32(v) _byteswap_ulong (v)
295#define Z7_BSWAP64(v) _byteswap_uint64(v)
296#define Z7_CPU_FAST_BSWAP_SUPPORTED
297
298#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
299 || (defined(__clang__) && Z7_has_builtin(__builtin_bswap16))
300
301#define Z7_BSWAP16(v) __builtin_bswap16(v)
302#define Z7_BSWAP32(v) __builtin_bswap32(v)
303#define Z7_BSWAP64(v) __builtin_bswap64(v)
304#define Z7_CPU_FAST_BSWAP_SUPPORTED
305
306#else
307
308#define Z7_BSWAP16(v) ((UInt16) \
309 ( ((UInt32)(v) << 8) \
310 | ((UInt32)(v) >> 8) \
311 ))
312
313#define Z7_BSWAP32(v) Z7_BSWAP32_CONST(v)
314
315#define Z7_BSWAP64(v) \
316 ( ( ( (UInt64)(v) ) << 8 * 7 ) \
317 | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 1) ) << 8 * 5 ) \
318 | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 2) ) << 8 * 3 ) \
319 | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 3) ) << 8 * 1 ) \
320 | ( ( (UInt64)(v) >> 8 * 1 ) & ((UInt32)0xff << 8 * 3) ) \
321 | ( ( (UInt64)(v) >> 8 * 3 ) & ((UInt32)0xff << 8 * 2) ) \
322 | ( ( (UInt64)(v) >> 8 * 5 ) & ((UInt32)0xff << 8 * 1) ) \
323 | ( ( (UInt64)(v) >> 8 * 7 ) ) \
324 )
325
326#endif
327
328
329
330#ifdef MY_CPU_LE
331 #if defined(MY_CPU_X86_OR_AMD64) \
332 || defined(MY_CPU_ARM64)
333 #define MY_CPU_LE_UNALIGN
334 #define MY_CPU_LE_UNALIGN_64
335 #elif defined(__ARM_FEATURE_UNALIGNED)
336 /* gcc9 for 32-bit arm can use LDRD instruction that requires 32-bit alignment.
337 So we can't use unaligned 64-bit operations. */
338 #define MY_CPU_LE_UNALIGN
339 #endif
340#endif
341
342
343#ifdef MY_CPU_LE_UNALIGN
344
345#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
346#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
347#ifdef MY_CPU_LE_UNALIGN_64
348#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
349#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); }
350#endif
351
352#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); }
353#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); }
354
355#else
356
357#define GetUi16(p) ( (UInt16) ( \
358 ((const Byte *)(p))[0] | \
359 ((UInt16)((const Byte *)(p))[1] << 8) ))
360
361#define GetUi32(p) ( \
362 ((const Byte *)(p))[0] | \
363 ((UInt32)((const Byte *)(p))[1] << 8) | \
364 ((UInt32)((const Byte *)(p))[2] << 16) | \
365 ((UInt32)((const Byte *)(p))[3] << 24))
366
367#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
368 _ppp_[0] = (Byte)_vvv_; \
369 _ppp_[1] = (Byte)(_vvv_ >> 8); }
370
371#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
372 _ppp_[0] = (Byte)_vvv_; \
373 _ppp_[1] = (Byte)(_vvv_ >> 8); \
374 _ppp_[2] = (Byte)(_vvv_ >> 16); \
375 _ppp_[3] = (Byte)(_vvv_ >> 24); }
376
377#endif
378
379
380#ifndef GetUi64
381#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
382#endif
383
384#ifndef SetUi64
385#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
386 SetUi32(_ppp2_ , (UInt32)_vvv2_) \
387 SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)) }
388#endif
389
390
391#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED)
392
393#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p))
394#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); }
395
396#if defined(MY_CPU_LE_UNALIGN_64)
397#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p))
398#endif
399
400#else
401
402#define GetBe32(p) ( \
403 ((UInt32)((const Byte *)(p))[0] << 24) | \
404 ((UInt32)((const Byte *)(p))[1] << 16) | \
405 ((UInt32)((const Byte *)(p))[2] << 8) | \
406 ((const Byte *)(p))[3] )
407
408#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
409 _ppp_[0] = (Byte)(_vvv_ >> 24); \
410 _ppp_[1] = (Byte)(_vvv_ >> 16); \
411 _ppp_[2] = (Byte)(_vvv_ >> 8); \
412 _ppp_[3] = (Byte)_vvv_; }
413
414#endif
415
416#ifndef GetBe64
417#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
418#endif
419
420#ifndef GetBe16
421#define GetBe16(p) ( (UInt16) ( \
422 ((UInt16)((const Byte *)(p))[0] << 8) | \
423 ((const Byte *)(p))[1] ))
424#endif
425
426
427#if defined(MY_CPU_BE)
428#define Z7_CONV_BE_TO_NATIVE_CONST32(v) (v)
429#define Z7_CONV_LE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v)
430#define Z7_CONV_NATIVE_TO_BE_32(v) (v)
431#elif defined(MY_CPU_LE)
432#define Z7_CONV_BE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v)
433#define Z7_CONV_LE_TO_NATIVE_CONST32(v) (v)
434#define Z7_CONV_NATIVE_TO_BE_32(v) Z7_BSWAP32(v)
435#else
436#error Stop_Compiling_Unknown_Endian_CONV
437#endif
438
439
440#if defined(MY_CPU_BE)
441
442#define GetBe32a(p) (*(const UInt32 *)(const void *)(p))
443#define GetBe16a(p) (*(const UInt16 *)(const void *)(p))
444#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
445#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
446
447#define GetUi32a(p) GetUi32(p)
448#define GetUi16a(p) GetUi16(p)
449#define SetUi32a(p, v) SetUi32(p, v)
450#define SetUi16a(p, v) SetUi16(p, v)
451
452#elif defined(MY_CPU_LE)
453
454#define GetUi32a(p) (*(const UInt32 *)(const void *)(p))
455#define GetUi16a(p) (*(const UInt16 *)(const void *)(p))
456#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
457#define SetUi16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
458
459#define GetBe32a(p) GetBe32(p)
460#define GetBe16a(p) GetBe16(p)
461#define SetBe32a(p, v) SetBe32(p, v)
462#define SetBe16a(p, v) SetBe16(p, v)
463
464#else
465#error Stop_Compiling_Unknown_Endian_CPU_a
466#endif
467
468
469#if defined(MY_CPU_X86_OR_AMD64) \
470 || defined(MY_CPU_ARM_OR_ARM64) \
471 || defined(MY_CPU_PPC_OR_PPC64)
472 #define Z7_CPU_FAST_ROTATE_SUPPORTED
473#endif
474
475
476#ifdef MY_CPU_X86_OR_AMD64
477
478void Z7_FASTCALL z7_x86_cpuid(UInt32 a[4], UInt32 function);
479UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void);
480#if defined(MY_CPU_AMD64)
481#define Z7_IF_X86_CPUID_SUPPORTED
482#else
483#define Z7_IF_X86_CPUID_SUPPORTED if (z7_x86_cpuid_GetMaxFunc())
484#endif
485
486BoolInt CPU_IsSupported_AES(void);
487BoolInt CPU_IsSupported_AVX(void);
488BoolInt CPU_IsSupported_AVX2(void);
489BoolInt CPU_IsSupported_VAES_AVX2(void);
490BoolInt CPU_IsSupported_CMOV(void);
491BoolInt CPU_IsSupported_SSE(void);
492BoolInt CPU_IsSupported_SSE2(void);
493BoolInt CPU_IsSupported_SSSE3(void);
494BoolInt CPU_IsSupported_SSE41(void);
495BoolInt CPU_IsSupported_SHA(void);
496BoolInt CPU_IsSupported_PageGB(void);
497
498#elif defined(MY_CPU_ARM_OR_ARM64)
499
500BoolInt CPU_IsSupported_CRC32(void);
501BoolInt CPU_IsSupported_NEON(void);
502
503#if defined(_WIN32)
504BoolInt CPU_IsSupported_CRYPTO(void);
505#define CPU_IsSupported_SHA1 CPU_IsSupported_CRYPTO
506#define CPU_IsSupported_SHA2 CPU_IsSupported_CRYPTO
507#define CPU_IsSupported_AES CPU_IsSupported_CRYPTO
508#else
509BoolInt CPU_IsSupported_SHA1(void);
510BoolInt CPU_IsSupported_SHA2(void);
511BoolInt CPU_IsSupported_AES(void);
512#endif
513
514#endif
515
516#if defined(__APPLE__)
517int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize);
518int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val);
519#endif
520
522
523#endif
int BoolInt
Definition 7zTypes.h:259
#define EXTERN_C_BEGIN
Definition 7zTypes.h:20
#define Z7_FASTCALL
Definition 7zTypes.h:308
#define EXTERN_C_END
Definition 7zTypes.h:21
char buf[N_BUF]
Definition spewG.c:36
unsigned int UInt32
Definition bzlib_private.h:45
#define a(i)
Definition sha256.c:41
char name[NAME_LEN_MAX+1]
Name of the filter.
Definition string_conversion.c:450