1370b324cSopenharmony_ci/* CpuArch.h -- CPU specific code
2370b324cSopenharmony_ci2023-04-02 : Igor Pavlov : Public domain */
3370b324cSopenharmony_ci
4370b324cSopenharmony_ci#ifndef ZIP7_INC_CPU_ARCH_H
5370b324cSopenharmony_ci#define ZIP7_INC_CPU_ARCH_H
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "7zTypes.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_ciEXTERN_C_BEGIN
10370b324cSopenharmony_ci
11370b324cSopenharmony_ci/*
12370b324cSopenharmony_ciMY_CPU_LE means that CPU is LITTLE ENDIAN.
13370b324cSopenharmony_ciMY_CPU_BE means that CPU is BIG ENDIAN.
14370b324cSopenharmony_ciIf MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
15370b324cSopenharmony_ci
16370b324cSopenharmony_ciMY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
17370b324cSopenharmony_ci
18370b324cSopenharmony_ciMY_CPU_64BIT means that processor can work with 64-bit registers.
19370b324cSopenharmony_ci  MY_CPU_64BIT can be used to select fast code branch
20370b324cSopenharmony_ci  MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8)
21370b324cSopenharmony_ci*/
22370b324cSopenharmony_ci
23370b324cSopenharmony_ci#if  defined(_M_X64) \
24370b324cSopenharmony_ci  || defined(_M_AMD64) \
25370b324cSopenharmony_ci  || defined(__x86_64__) \
26370b324cSopenharmony_ci  || defined(__AMD64__) \
27370b324cSopenharmony_ci  || defined(__amd64__)
28370b324cSopenharmony_ci  #define MY_CPU_AMD64
29370b324cSopenharmony_ci  #ifdef __ILP32__
30370b324cSopenharmony_ci    #define MY_CPU_NAME "x32"
31370b324cSopenharmony_ci    #define MY_CPU_SIZEOF_POINTER 4
32370b324cSopenharmony_ci  #else
33370b324cSopenharmony_ci    #define MY_CPU_NAME "x64"
34370b324cSopenharmony_ci    #define MY_CPU_SIZEOF_POINTER 8
35370b324cSopenharmony_ci  #endif
36370b324cSopenharmony_ci  #define MY_CPU_64BIT
37370b324cSopenharmony_ci#endif
38370b324cSopenharmony_ci
39370b324cSopenharmony_ci
40370b324cSopenharmony_ci#if  defined(_M_IX86) \
41370b324cSopenharmony_ci  || defined(__i386__)
42370b324cSopenharmony_ci  #define MY_CPU_X86
43370b324cSopenharmony_ci  #define MY_CPU_NAME "x86"
44370b324cSopenharmony_ci  /* #define MY_CPU_32BIT */
45370b324cSopenharmony_ci  #define MY_CPU_SIZEOF_POINTER 4
46370b324cSopenharmony_ci#endif
47370b324cSopenharmony_ci
48370b324cSopenharmony_ci
49370b324cSopenharmony_ci#if  defined(_M_ARM64) \
50370b324cSopenharmony_ci  || defined(__AARCH64EL__) \
51370b324cSopenharmony_ci  || defined(__AARCH64EB__) \
52370b324cSopenharmony_ci  || defined(__aarch64__)
53370b324cSopenharmony_ci  #define MY_CPU_ARM64
54370b324cSopenharmony_ci  #ifdef __ILP32__
55370b324cSopenharmony_ci    #define MY_CPU_NAME "arm64-32"
56370b324cSopenharmony_ci    #define MY_CPU_SIZEOF_POINTER 4
57370b324cSopenharmony_ci  #else
58370b324cSopenharmony_ci    #define MY_CPU_NAME "arm64"
59370b324cSopenharmony_ci    #define MY_CPU_SIZEOF_POINTER 8
60370b324cSopenharmony_ci  #endif
61370b324cSopenharmony_ci  #define MY_CPU_64BIT
62370b324cSopenharmony_ci#endif
63370b324cSopenharmony_ci
64370b324cSopenharmony_ci
65370b324cSopenharmony_ci#if  defined(_M_ARM) \
66370b324cSopenharmony_ci  || defined(_M_ARM_NT) \
67370b324cSopenharmony_ci  || defined(_M_ARMT) \
68370b324cSopenharmony_ci  || defined(__arm__) \
69370b324cSopenharmony_ci  || defined(__thumb__) \
70370b324cSopenharmony_ci  || defined(__ARMEL__) \
71370b324cSopenharmony_ci  || defined(__ARMEB__) \
72370b324cSopenharmony_ci  || defined(__THUMBEL__) \
73370b324cSopenharmony_ci  || defined(__THUMBEB__)
74370b324cSopenharmony_ci  #define MY_CPU_ARM
75370b324cSopenharmony_ci
76370b324cSopenharmony_ci  #if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT)
77370b324cSopenharmony_ci    #define MY_CPU_ARMT
78370b324cSopenharmony_ci    #define MY_CPU_NAME "armt"
79370b324cSopenharmony_ci  #else
80370b324cSopenharmony_ci    #define MY_CPU_ARM32
81370b324cSopenharmony_ci    #define MY_CPU_NAME "arm"
82370b324cSopenharmony_ci  #endif
83370b324cSopenharmony_ci  /* #define MY_CPU_32BIT */
84370b324cSopenharmony_ci  #define MY_CPU_SIZEOF_POINTER 4
85370b324cSopenharmony_ci#endif
86370b324cSopenharmony_ci
87370b324cSopenharmony_ci
88370b324cSopenharmony_ci#if  defined(_M_IA64) \
89370b324cSopenharmony_ci  || defined(__ia64__)
90370b324cSopenharmony_ci  #define MY_CPU_IA64
91370b324cSopenharmony_ci  #define MY_CPU_NAME "ia64"
92370b324cSopenharmony_ci  #define MY_CPU_64BIT
93370b324cSopenharmony_ci#endif
94370b324cSopenharmony_ci
95370b324cSopenharmony_ci
96370b324cSopenharmony_ci#if  defined(__mips64) \
97370b324cSopenharmony_ci  || defined(__mips64__) \
98370b324cSopenharmony_ci  || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
99370b324cSopenharmony_ci  #define MY_CPU_NAME "mips64"
100370b324cSopenharmony_ci  #define MY_CPU_64BIT
101370b324cSopenharmony_ci#elif defined(__mips__)
102370b324cSopenharmony_ci  #define MY_CPU_NAME "mips"
103370b324cSopenharmony_ci  /* #define MY_CPU_32BIT */
104370b324cSopenharmony_ci#endif
105370b324cSopenharmony_ci
106370b324cSopenharmony_ci
107370b324cSopenharmony_ci#if  defined(__ppc64__) \
108370b324cSopenharmony_ci  || defined(__powerpc64__) \
109370b324cSopenharmony_ci  || defined(__ppc__) \
110370b324cSopenharmony_ci  || defined(__powerpc__) \
111370b324cSopenharmony_ci  || defined(__PPC__) \
112370b324cSopenharmony_ci  || defined(_POWER)
113370b324cSopenharmony_ci
114370b324cSopenharmony_ci#define MY_CPU_PPC_OR_PPC64
115370b324cSopenharmony_ci
116370b324cSopenharmony_ci#if  defined(__ppc64__) \
117370b324cSopenharmony_ci  || defined(__powerpc64__) \
118370b324cSopenharmony_ci  || defined(_LP64) \
119370b324cSopenharmony_ci  || defined(__64BIT__)
120370b324cSopenharmony_ci  #ifdef __ILP32__
121370b324cSopenharmony_ci    #define MY_CPU_NAME "ppc64-32"
122370b324cSopenharmony_ci    #define MY_CPU_SIZEOF_POINTER 4
123370b324cSopenharmony_ci  #else
124370b324cSopenharmony_ci    #define MY_CPU_NAME "ppc64"
125370b324cSopenharmony_ci    #define MY_CPU_SIZEOF_POINTER 8
126370b324cSopenharmony_ci  #endif
127370b324cSopenharmony_ci  #define MY_CPU_64BIT
128370b324cSopenharmony_ci#else
129370b324cSopenharmony_ci  #define MY_CPU_NAME "ppc"
130370b324cSopenharmony_ci  #define MY_CPU_SIZEOF_POINTER 4
131370b324cSopenharmony_ci  /* #define MY_CPU_32BIT */
132370b324cSopenharmony_ci#endif
133370b324cSopenharmony_ci#endif
134370b324cSopenharmony_ci
135370b324cSopenharmony_ci
136370b324cSopenharmony_ci#if  defined(__riscv) \
137370b324cSopenharmony_ci  || defined(__riscv__)
138370b324cSopenharmony_ci  #if __riscv_xlen == 32
139370b324cSopenharmony_ci    #define MY_CPU_NAME "riscv32"
140370b324cSopenharmony_ci  #elif __riscv_xlen == 64
141370b324cSopenharmony_ci    #define MY_CPU_NAME "riscv64"
142370b324cSopenharmony_ci  #else
143370b324cSopenharmony_ci    #define MY_CPU_NAME "riscv"
144370b324cSopenharmony_ci  #endif
145370b324cSopenharmony_ci#endif
146370b324cSopenharmony_ci
147370b324cSopenharmony_ci
148370b324cSopenharmony_ci#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
149370b324cSopenharmony_ci#define MY_CPU_X86_OR_AMD64
150370b324cSopenharmony_ci#endif
151370b324cSopenharmony_ci
152370b324cSopenharmony_ci#if defined(MY_CPU_ARM) || defined(MY_CPU_ARM64)
153370b324cSopenharmony_ci#define MY_CPU_ARM_OR_ARM64
154370b324cSopenharmony_ci#endif
155370b324cSopenharmony_ci
156370b324cSopenharmony_ci
157370b324cSopenharmony_ci#ifdef _WIN32
158370b324cSopenharmony_ci
159370b324cSopenharmony_ci  #ifdef MY_CPU_ARM
160370b324cSopenharmony_ci  #define MY_CPU_ARM_LE
161370b324cSopenharmony_ci  #endif
162370b324cSopenharmony_ci
163370b324cSopenharmony_ci  #ifdef MY_CPU_ARM64
164370b324cSopenharmony_ci  #define MY_CPU_ARM64_LE
165370b324cSopenharmony_ci  #endif
166370b324cSopenharmony_ci
167370b324cSopenharmony_ci  #ifdef _M_IA64
168370b324cSopenharmony_ci  #define MY_CPU_IA64_LE
169370b324cSopenharmony_ci  #endif
170370b324cSopenharmony_ci
171370b324cSopenharmony_ci#endif
172370b324cSopenharmony_ci
173370b324cSopenharmony_ci
174370b324cSopenharmony_ci#if defined(MY_CPU_X86_OR_AMD64) \
175370b324cSopenharmony_ci    || defined(MY_CPU_ARM_LE) \
176370b324cSopenharmony_ci    || defined(MY_CPU_ARM64_LE) \
177370b324cSopenharmony_ci    || defined(MY_CPU_IA64_LE) \
178370b324cSopenharmony_ci    || defined(__LITTLE_ENDIAN__) \
179370b324cSopenharmony_ci    || defined(__ARMEL__) \
180370b324cSopenharmony_ci    || defined(__THUMBEL__) \
181370b324cSopenharmony_ci    || defined(__AARCH64EL__) \
182370b324cSopenharmony_ci    || defined(__MIPSEL__) \
183370b324cSopenharmony_ci    || defined(__MIPSEL) \
184370b324cSopenharmony_ci    || defined(_MIPSEL) \
185370b324cSopenharmony_ci    || defined(__BFIN__) \
186370b324cSopenharmony_ci    || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
187370b324cSopenharmony_ci  #define MY_CPU_LE
188370b324cSopenharmony_ci#endif
189370b324cSopenharmony_ci
190370b324cSopenharmony_ci#if defined(__BIG_ENDIAN__) \
191370b324cSopenharmony_ci    || defined(__ARMEB__) \
192370b324cSopenharmony_ci    || defined(__THUMBEB__) \
193370b324cSopenharmony_ci    || defined(__AARCH64EB__) \
194370b324cSopenharmony_ci    || defined(__MIPSEB__) \
195370b324cSopenharmony_ci    || defined(__MIPSEB) \
196370b324cSopenharmony_ci    || defined(_MIPSEB) \
197370b324cSopenharmony_ci    || defined(__m68k__) \
198370b324cSopenharmony_ci    || defined(__s390__) \
199370b324cSopenharmony_ci    || defined(__s390x__) \
200370b324cSopenharmony_ci    || defined(__zarch__) \
201370b324cSopenharmony_ci    || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
202370b324cSopenharmony_ci  #define MY_CPU_BE
203370b324cSopenharmony_ci#endif
204370b324cSopenharmony_ci
205370b324cSopenharmony_ci
206370b324cSopenharmony_ci#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
207370b324cSopenharmony_ci  #error Stop_Compiling_Bad_Endian
208370b324cSopenharmony_ci#endif
209370b324cSopenharmony_ci
210370b324cSopenharmony_ci#if !defined(MY_CPU_LE) && !defined(MY_CPU_BE)
211370b324cSopenharmony_ci  #error Stop_Compiling_CPU_ENDIAN_must_be_detected_at_compile_time
212370b324cSopenharmony_ci#endif
213370b324cSopenharmony_ci
214370b324cSopenharmony_ci#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
215370b324cSopenharmony_ci  #error Stop_Compiling_Bad_32_64_BIT
216370b324cSopenharmony_ci#endif
217370b324cSopenharmony_ci
218370b324cSopenharmony_ci#ifdef __SIZEOF_POINTER__
219370b324cSopenharmony_ci  #ifdef MY_CPU_SIZEOF_POINTER
220370b324cSopenharmony_ci    #if MY_CPU_SIZEOF_POINTER != __SIZEOF_POINTER__
221370b324cSopenharmony_ci      #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE
222370b324cSopenharmony_ci    #endif
223370b324cSopenharmony_ci  #else
224370b324cSopenharmony_ci    #define MY_CPU_SIZEOF_POINTER  __SIZEOF_POINTER__
225370b324cSopenharmony_ci  #endif
226370b324cSopenharmony_ci#endif
227370b324cSopenharmony_ci
228370b324cSopenharmony_ci#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
229370b324cSopenharmony_ci#if defined (_LP64)
230370b324cSopenharmony_ci      #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE
231370b324cSopenharmony_ci#endif
232370b324cSopenharmony_ci#endif
233370b324cSopenharmony_ci
234370b324cSopenharmony_ci#ifdef _MSC_VER
235370b324cSopenharmony_ci  #if _MSC_VER >= 1300
236370b324cSopenharmony_ci    #define MY_CPU_pragma_pack_push_1   __pragma(pack(push, 1))
237370b324cSopenharmony_ci    #define MY_CPU_pragma_pop           __pragma(pack(pop))
238370b324cSopenharmony_ci  #else
239370b324cSopenharmony_ci    #define MY_CPU_pragma_pack_push_1
240370b324cSopenharmony_ci    #define MY_CPU_pragma_pop
241370b324cSopenharmony_ci  #endif
242370b324cSopenharmony_ci#else
243370b324cSopenharmony_ci  #ifdef __xlC__
244370b324cSopenharmony_ci    #define MY_CPU_pragma_pack_push_1   _Pragma("pack(1)")
245370b324cSopenharmony_ci    #define MY_CPU_pragma_pop           _Pragma("pack()")
246370b324cSopenharmony_ci  #else
247370b324cSopenharmony_ci    #define MY_CPU_pragma_pack_push_1   _Pragma("pack(push, 1)")
248370b324cSopenharmony_ci    #define MY_CPU_pragma_pop           _Pragma("pack(pop)")
249370b324cSopenharmony_ci  #endif
250370b324cSopenharmony_ci#endif
251370b324cSopenharmony_ci
252370b324cSopenharmony_ci
253370b324cSopenharmony_ci#ifndef MY_CPU_NAME
254370b324cSopenharmony_ci  #ifdef MY_CPU_LE
255370b324cSopenharmony_ci    #define MY_CPU_NAME "LE"
256370b324cSopenharmony_ci  #elif defined(MY_CPU_BE)
257370b324cSopenharmony_ci    #define MY_CPU_NAME "BE"
258370b324cSopenharmony_ci  #else
259370b324cSopenharmony_ci    /*
260370b324cSopenharmony_ci    #define MY_CPU_NAME ""
261370b324cSopenharmony_ci    */
262370b324cSopenharmony_ci  #endif
263370b324cSopenharmony_ci#endif
264370b324cSopenharmony_ci
265370b324cSopenharmony_ci
266370b324cSopenharmony_ci
267370b324cSopenharmony_ci
268370b324cSopenharmony_ci
269370b324cSopenharmony_ci#ifdef __has_builtin
270370b324cSopenharmony_ci  #define Z7_has_builtin(x)  __has_builtin(x)
271370b324cSopenharmony_ci#else
272370b324cSopenharmony_ci  #define Z7_has_builtin(x)  0
273370b324cSopenharmony_ci#endif
274370b324cSopenharmony_ci
275370b324cSopenharmony_ci
276370b324cSopenharmony_ci#define Z7_BSWAP32_CONST(v) \
277370b324cSopenharmony_ci       ( (((UInt32)(v) << 24)                   ) \
278370b324cSopenharmony_ci       | (((UInt32)(v) <<  8) & (UInt32)0xff0000) \
279370b324cSopenharmony_ci       | (((UInt32)(v) >>  8) & (UInt32)0xff00  ) \
280370b324cSopenharmony_ci       | (((UInt32)(v) >> 24)                   ))
281370b324cSopenharmony_ci
282370b324cSopenharmony_ci
283370b324cSopenharmony_ci#if defined(_MSC_VER) && (_MSC_VER >= 1300)
284370b324cSopenharmony_ci
285370b324cSopenharmony_ci#include <stdlib.h>
286370b324cSopenharmony_ci
287370b324cSopenharmony_ci/* Note: these macros will use bswap instruction (486), that is unsupported in 386 cpu */
288370b324cSopenharmony_ci
289370b324cSopenharmony_ci#pragma intrinsic(_byteswap_ushort)
290370b324cSopenharmony_ci#pragma intrinsic(_byteswap_ulong)
291370b324cSopenharmony_ci#pragma intrinsic(_byteswap_uint64)
292370b324cSopenharmony_ci
293370b324cSopenharmony_ci#define Z7_BSWAP16(v)  _byteswap_ushort(v)
294370b324cSopenharmony_ci#define Z7_BSWAP32(v)  _byteswap_ulong (v)
295370b324cSopenharmony_ci#define Z7_BSWAP64(v)  _byteswap_uint64(v)
296370b324cSopenharmony_ci#define Z7_CPU_FAST_BSWAP_SUPPORTED
297370b324cSopenharmony_ci
298370b324cSopenharmony_ci#elif  (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
299370b324cSopenharmony_ci    || (defined(__clang__) && Z7_has_builtin(__builtin_bswap16))
300370b324cSopenharmony_ci
301370b324cSopenharmony_ci#define Z7_BSWAP16(v)  __builtin_bswap16(v)
302370b324cSopenharmony_ci#define Z7_BSWAP32(v)  __builtin_bswap32(v)
303370b324cSopenharmony_ci#define Z7_BSWAP64(v)  __builtin_bswap64(v)
304370b324cSopenharmony_ci#define Z7_CPU_FAST_BSWAP_SUPPORTED
305370b324cSopenharmony_ci
306370b324cSopenharmony_ci#else
307370b324cSopenharmony_ci
308370b324cSopenharmony_ci#define Z7_BSWAP16(v) ((UInt16) \
309370b324cSopenharmony_ci       ( ((UInt32)(v) << 8) \
310370b324cSopenharmony_ci       | ((UInt32)(v) >> 8) \
311370b324cSopenharmony_ci       ))
312370b324cSopenharmony_ci
313370b324cSopenharmony_ci#define Z7_BSWAP32(v) Z7_BSWAP32_CONST(v)
314370b324cSopenharmony_ci
315370b324cSopenharmony_ci#define Z7_BSWAP64(v) \
316370b324cSopenharmony_ci       ( ( ( (UInt64)(v)                           ) << 8 * 7 ) \
317370b324cSopenharmony_ci       | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 1) ) << 8 * 5 ) \
318370b324cSopenharmony_ci       | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 2) ) << 8 * 3 ) \
319370b324cSopenharmony_ci       | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 3) ) << 8 * 1 ) \
320370b324cSopenharmony_ci       | ( ( (UInt64)(v) >> 8 * 1 ) & ((UInt32)0xff << 8 * 3) ) \
321370b324cSopenharmony_ci       | ( ( (UInt64)(v) >> 8 * 3 ) & ((UInt32)0xff << 8 * 2) ) \
322370b324cSopenharmony_ci       | ( ( (UInt64)(v) >> 8 * 5 ) & ((UInt32)0xff << 8 * 1) ) \
323370b324cSopenharmony_ci       | ( ( (UInt64)(v) >> 8 * 7 )                           ) \
324370b324cSopenharmony_ci       )
325370b324cSopenharmony_ci
326370b324cSopenharmony_ci#endif
327370b324cSopenharmony_ci
328370b324cSopenharmony_ci
329370b324cSopenharmony_ci
330370b324cSopenharmony_ci#ifdef MY_CPU_LE
331370b324cSopenharmony_ci  #if defined(MY_CPU_X86_OR_AMD64) \
332370b324cSopenharmony_ci      || defined(MY_CPU_ARM64)
333370b324cSopenharmony_ci    #define MY_CPU_LE_UNALIGN
334370b324cSopenharmony_ci    #define MY_CPU_LE_UNALIGN_64
335370b324cSopenharmony_ci  #elif defined(__ARM_FEATURE_UNALIGNED)
336370b324cSopenharmony_ci    /* gcc9 for 32-bit arm can use LDRD instruction that requires 32-bit alignment.
337370b324cSopenharmony_ci       So we can't use unaligned 64-bit operations. */
338370b324cSopenharmony_ci    #define MY_CPU_LE_UNALIGN
339370b324cSopenharmony_ci  #endif
340370b324cSopenharmony_ci#endif
341370b324cSopenharmony_ci
342370b324cSopenharmony_ci
343370b324cSopenharmony_ci#ifdef MY_CPU_LE_UNALIGN
344370b324cSopenharmony_ci
345370b324cSopenharmony_ci#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
346370b324cSopenharmony_ci#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
347370b324cSopenharmony_ci#ifdef MY_CPU_LE_UNALIGN_64
348370b324cSopenharmony_ci#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
349370b324cSopenharmony_ci#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); }
350370b324cSopenharmony_ci#endif
351370b324cSopenharmony_ci
352370b324cSopenharmony_ci#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); }
353370b324cSopenharmony_ci#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); }
354370b324cSopenharmony_ci
355370b324cSopenharmony_ci#else
356370b324cSopenharmony_ci
357370b324cSopenharmony_ci#define GetUi16(p) ( (UInt16) ( \
358370b324cSopenharmony_ci             ((const Byte *)(p))[0] | \
359370b324cSopenharmony_ci    ((UInt16)((const Byte *)(p))[1] << 8) ))
360370b324cSopenharmony_ci
361370b324cSopenharmony_ci#define GetUi32(p) ( \
362370b324cSopenharmony_ci             ((const Byte *)(p))[0]        | \
363370b324cSopenharmony_ci    ((UInt32)((const Byte *)(p))[1] <<  8) | \
364370b324cSopenharmony_ci    ((UInt32)((const Byte *)(p))[2] << 16) | \
365370b324cSopenharmony_ci    ((UInt32)((const Byte *)(p))[3] << 24))
366370b324cSopenharmony_ci
367370b324cSopenharmony_ci#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
368370b324cSopenharmony_ci    _ppp_[0] = (Byte)_vvv_; \
369370b324cSopenharmony_ci    _ppp_[1] = (Byte)(_vvv_ >> 8); }
370370b324cSopenharmony_ci
371370b324cSopenharmony_ci#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
372370b324cSopenharmony_ci    _ppp_[0] = (Byte)_vvv_; \
373370b324cSopenharmony_ci    _ppp_[1] = (Byte)(_vvv_ >> 8); \
374370b324cSopenharmony_ci    _ppp_[2] = (Byte)(_vvv_ >> 16); \
375370b324cSopenharmony_ci    _ppp_[3] = (Byte)(_vvv_ >> 24); }
376370b324cSopenharmony_ci
377370b324cSopenharmony_ci#endif
378370b324cSopenharmony_ci
379370b324cSopenharmony_ci
380370b324cSopenharmony_ci#ifndef GetUi64
381370b324cSopenharmony_ci#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
382370b324cSopenharmony_ci#endif
383370b324cSopenharmony_ci
384370b324cSopenharmony_ci#ifndef SetUi64
385370b324cSopenharmony_ci#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
386370b324cSopenharmony_ci    SetUi32(_ppp2_    , (UInt32)_vvv2_) \
387370b324cSopenharmony_ci    SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)) }
388370b324cSopenharmony_ci#endif
389370b324cSopenharmony_ci
390370b324cSopenharmony_ci
391370b324cSopenharmony_ci#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED)
392370b324cSopenharmony_ci
393370b324cSopenharmony_ci#define GetBe32(p)  Z7_BSWAP32 (*(const UInt32 *)(const void *)(p))
394370b324cSopenharmony_ci#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); }
395370b324cSopenharmony_ci
396370b324cSopenharmony_ci#if defined(MY_CPU_LE_UNALIGN_64)
397370b324cSopenharmony_ci#define GetBe64(p)  Z7_BSWAP64 (*(const UInt64 *)(const void *)(p))
398370b324cSopenharmony_ci#endif
399370b324cSopenharmony_ci
400370b324cSopenharmony_ci#else
401370b324cSopenharmony_ci
402370b324cSopenharmony_ci#define GetBe32(p) ( \
403370b324cSopenharmony_ci    ((UInt32)((const Byte *)(p))[0] << 24) | \
404370b324cSopenharmony_ci    ((UInt32)((const Byte *)(p))[1] << 16) | \
405370b324cSopenharmony_ci    ((UInt32)((const Byte *)(p))[2] <<  8) | \
406370b324cSopenharmony_ci             ((const Byte *)(p))[3] )
407370b324cSopenharmony_ci
408370b324cSopenharmony_ci#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
409370b324cSopenharmony_ci    _ppp_[0] = (Byte)(_vvv_ >> 24); \
410370b324cSopenharmony_ci    _ppp_[1] = (Byte)(_vvv_ >> 16); \
411370b324cSopenharmony_ci    _ppp_[2] = (Byte)(_vvv_ >> 8); \
412370b324cSopenharmony_ci    _ppp_[3] = (Byte)_vvv_; }
413370b324cSopenharmony_ci
414370b324cSopenharmony_ci#endif
415370b324cSopenharmony_ci
416370b324cSopenharmony_ci#ifndef GetBe64
417370b324cSopenharmony_ci#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
418370b324cSopenharmony_ci#endif
419370b324cSopenharmony_ci
420370b324cSopenharmony_ci#ifndef GetBe16
421370b324cSopenharmony_ci#define GetBe16(p) ( (UInt16) ( \
422370b324cSopenharmony_ci    ((UInt16)((const Byte *)(p))[0] << 8) | \
423370b324cSopenharmony_ci             ((const Byte *)(p))[1] ))
424370b324cSopenharmony_ci#endif
425370b324cSopenharmony_ci
426370b324cSopenharmony_ci
427370b324cSopenharmony_ci#if defined(MY_CPU_BE)
428370b324cSopenharmony_ci#define Z7_CONV_BE_TO_NATIVE_CONST32(v)  (v)
429370b324cSopenharmony_ci#define Z7_CONV_LE_TO_NATIVE_CONST32(v)  Z7_BSWAP32_CONST(v)
430370b324cSopenharmony_ci#define Z7_CONV_NATIVE_TO_BE_32(v)       (v)
431370b324cSopenharmony_ci#elif defined(MY_CPU_LE)
432370b324cSopenharmony_ci#define Z7_CONV_BE_TO_NATIVE_CONST32(v)  Z7_BSWAP32_CONST(v)
433370b324cSopenharmony_ci#define Z7_CONV_LE_TO_NATIVE_CONST32(v)  (v)
434370b324cSopenharmony_ci#define Z7_CONV_NATIVE_TO_BE_32(v)       Z7_BSWAP32(v)
435370b324cSopenharmony_ci#else
436370b324cSopenharmony_ci#error Stop_Compiling_Unknown_Endian_CONV
437370b324cSopenharmony_ci#endif
438370b324cSopenharmony_ci
439370b324cSopenharmony_ci
440370b324cSopenharmony_ci#if defined(MY_CPU_BE)
441370b324cSopenharmony_ci
442370b324cSopenharmony_ci#define GetBe32a(p)      (*(const UInt32 *)(const void *)(p))
443370b324cSopenharmony_ci#define GetBe16a(p)      (*(const UInt16 *)(const void *)(p))
444370b324cSopenharmony_ci#define SetBe32a(p, v)   { *(UInt32 *)(void *)(p) = (v); }
445370b324cSopenharmony_ci#define SetBe16a(p, v)   { *(UInt16 *)(void *)(p) = (v); }
446370b324cSopenharmony_ci
447370b324cSopenharmony_ci#define GetUi32a(p)      GetUi32(p)
448370b324cSopenharmony_ci#define GetUi16a(p)      GetUi16(p)
449370b324cSopenharmony_ci#define SetUi32a(p, v)   SetUi32(p, v)
450370b324cSopenharmony_ci#define SetUi16a(p, v)   SetUi16(p, v)
451370b324cSopenharmony_ci
452370b324cSopenharmony_ci#elif defined(MY_CPU_LE)
453370b324cSopenharmony_ci
454370b324cSopenharmony_ci#define GetUi32a(p)      (*(const UInt32 *)(const void *)(p))
455370b324cSopenharmony_ci#define GetUi16a(p)      (*(const UInt16 *)(const void *)(p))
456370b324cSopenharmony_ci#define SetUi32a(p, v)   { *(UInt32 *)(void *)(p) = (v); }
457370b324cSopenharmony_ci#define SetUi16a(p, v)   { *(UInt16 *)(void *)(p) = (v); }
458370b324cSopenharmony_ci
459370b324cSopenharmony_ci#define GetBe32a(p)      GetBe32(p)
460370b324cSopenharmony_ci#define GetBe16a(p)      GetBe16(p)
461370b324cSopenharmony_ci#define SetBe32a(p, v)   SetBe32(p, v)
462370b324cSopenharmony_ci#define SetBe16a(p, v)   SetBe16(p, v)
463370b324cSopenharmony_ci
464370b324cSopenharmony_ci#else
465370b324cSopenharmony_ci#error Stop_Compiling_Unknown_Endian_CPU_a
466370b324cSopenharmony_ci#endif
467370b324cSopenharmony_ci
468370b324cSopenharmony_ci
469370b324cSopenharmony_ci#if defined(MY_CPU_X86_OR_AMD64) \
470370b324cSopenharmony_ci  || defined(MY_CPU_ARM_OR_ARM64) \
471370b324cSopenharmony_ci  || defined(MY_CPU_PPC_OR_PPC64)
472370b324cSopenharmony_ci  #define Z7_CPU_FAST_ROTATE_SUPPORTED
473370b324cSopenharmony_ci#endif
474370b324cSopenharmony_ci
475370b324cSopenharmony_ci
476370b324cSopenharmony_ci#ifdef MY_CPU_X86_OR_AMD64
477370b324cSopenharmony_ci
478370b324cSopenharmony_civoid Z7_FASTCALL z7_x86_cpuid(UInt32 a[4], UInt32 function);
479370b324cSopenharmony_ciUInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void);
480370b324cSopenharmony_ci#if defined(MY_CPU_AMD64)
481370b324cSopenharmony_ci#define Z7_IF_X86_CPUID_SUPPORTED
482370b324cSopenharmony_ci#else
483370b324cSopenharmony_ci#define Z7_IF_X86_CPUID_SUPPORTED if (z7_x86_cpuid_GetMaxFunc())
484370b324cSopenharmony_ci#endif
485370b324cSopenharmony_ci
486370b324cSopenharmony_ciBoolInt CPU_IsSupported_AES(void);
487370b324cSopenharmony_ciBoolInt CPU_IsSupported_AVX(void);
488370b324cSopenharmony_ciBoolInt CPU_IsSupported_AVX2(void);
489370b324cSopenharmony_ciBoolInt CPU_IsSupported_VAES_AVX2(void);
490370b324cSopenharmony_ciBoolInt CPU_IsSupported_CMOV(void);
491370b324cSopenharmony_ciBoolInt CPU_IsSupported_SSE(void);
492370b324cSopenharmony_ciBoolInt CPU_IsSupported_SSE2(void);
493370b324cSopenharmony_ciBoolInt CPU_IsSupported_SSSE3(void);
494370b324cSopenharmony_ciBoolInt CPU_IsSupported_SSE41(void);
495370b324cSopenharmony_ciBoolInt CPU_IsSupported_SHA(void);
496370b324cSopenharmony_ciBoolInt CPU_IsSupported_PageGB(void);
497370b324cSopenharmony_ci
498370b324cSopenharmony_ci#elif defined(MY_CPU_ARM_OR_ARM64)
499370b324cSopenharmony_ci
500370b324cSopenharmony_ciBoolInt CPU_IsSupported_CRC32(void);
501370b324cSopenharmony_ciBoolInt CPU_IsSupported_NEON(void);
502370b324cSopenharmony_ci
503370b324cSopenharmony_ci#if defined(_WIN32)
504370b324cSopenharmony_ciBoolInt CPU_IsSupported_CRYPTO(void);
505370b324cSopenharmony_ci#define CPU_IsSupported_SHA1  CPU_IsSupported_CRYPTO
506370b324cSopenharmony_ci#define CPU_IsSupported_SHA2  CPU_IsSupported_CRYPTO
507370b324cSopenharmony_ci#define CPU_IsSupported_AES   CPU_IsSupported_CRYPTO
508370b324cSopenharmony_ci#else
509370b324cSopenharmony_ciBoolInt CPU_IsSupported_SHA1(void);
510370b324cSopenharmony_ciBoolInt CPU_IsSupported_SHA2(void);
511370b324cSopenharmony_ciBoolInt CPU_IsSupported_AES(void);
512370b324cSopenharmony_ci#endif
513370b324cSopenharmony_ci
514370b324cSopenharmony_ci#endif
515370b324cSopenharmony_ci
516370b324cSopenharmony_ci#if defined(__APPLE__)
517370b324cSopenharmony_ciint z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize);
518370b324cSopenharmony_ciint z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val);
519370b324cSopenharmony_ci#endif
520370b324cSopenharmony_ci
521370b324cSopenharmony_ciEXTERN_C_END
522370b324cSopenharmony_ci
523370b324cSopenharmony_ci#endif
524