update libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / lzma-22.01 / include / CpuArch.h
CommitLineData
9e052883 1/* CpuArch.h -- CPU specific code\r
22022-07-15 : Igor Pavlov : Public domain */\r
3\r
4#ifndef __CPU_ARCH_H\r
5#define __CPU_ARCH_H\r
6\r
7#include "7zTypes.h"\r
8\r
9EXTERN_C_BEGIN\r
10\r
11/*\r
12MY_CPU_LE means that CPU is LITTLE ENDIAN.\r
13MY_CPU_BE means that CPU is BIG ENDIAN.\r
14If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.\r
15\r
16MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.\r
17\r
18MY_CPU_64BIT means that processor can work with 64-bit registers.\r
19 MY_CPU_64BIT can be used to select fast code branch\r
20 MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8)\r
21*/\r
22\r
23#if defined(_M_X64) \\r
24 || defined(_M_AMD64) \\r
25 || defined(__x86_64__) \\r
26 || defined(__AMD64__) \\r
27 || defined(__amd64__)\r
28 #define MY_CPU_AMD64\r
29 #ifdef __ILP32__\r
30 #define MY_CPU_NAME "x32"\r
31 #define MY_CPU_SIZEOF_POINTER 4\r
32 #else\r
33 #define MY_CPU_NAME "x64"\r
34 #define MY_CPU_SIZEOF_POINTER 8\r
35 #endif\r
36 #define MY_CPU_64BIT\r
37#endif\r
38\r
39\r
40#if defined(_M_IX86) \\r
41 || defined(__i386__)\r
42 #define MY_CPU_X86\r
43 #define MY_CPU_NAME "x86"\r
44 /* #define MY_CPU_32BIT */\r
45 #define MY_CPU_SIZEOF_POINTER 4\r
46#endif\r
47\r
48\r
49#if defined(_M_ARM64) \\r
50 || defined(__AARCH64EL__) \\r
51 || defined(__AARCH64EB__) \\r
52 || defined(__aarch64__)\r
53 #define MY_CPU_ARM64\r
54 #define MY_CPU_NAME "arm64"\r
55 #define MY_CPU_64BIT\r
56#endif\r
57\r
58\r
59#if defined(_M_ARM) \\r
60 || defined(_M_ARM_NT) \\r
61 || defined(_M_ARMT) \\r
62 || defined(__arm__) \\r
63 || defined(__thumb__) \\r
64 || defined(__ARMEL__) \\r
65 || defined(__ARMEB__) \\r
66 || defined(__THUMBEL__) \\r
67 || defined(__THUMBEB__)\r
68 #define MY_CPU_ARM\r
69\r
70 #if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT)\r
71 #define MY_CPU_NAME "armt"\r
72 #else\r
73 #define MY_CPU_NAME "arm"\r
74 #endif\r
75 /* #define MY_CPU_32BIT */\r
76 #define MY_CPU_SIZEOF_POINTER 4\r
77#endif\r
78\r
79\r
80#if defined(_M_IA64) \\r
81 || defined(__ia64__)\r
82 #define MY_CPU_IA64\r
83 #define MY_CPU_NAME "ia64"\r
84 #define MY_CPU_64BIT\r
85#endif\r
86\r
87\r
88#if defined(__mips64) \\r
89 || defined(__mips64__) \\r
90 || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))\r
91 #define MY_CPU_NAME "mips64"\r
92 #define MY_CPU_64BIT\r
93#elif defined(__mips__)\r
94 #define MY_CPU_NAME "mips"\r
95 /* #define MY_CPU_32BIT */\r
96#endif\r
97\r
98\r
99#if defined(__ppc64__) \\r
100 || defined(__powerpc64__) \\r
101 || defined(__ppc__) \\r
102 || defined(__powerpc__) \\r
103 || defined(__PPC__) \\r
104 || defined(_POWER)\r
105\r
106#if defined(__ppc64__) \\r
107 || defined(__powerpc64__) \\r
108 || defined(_LP64) \\r
109 || defined(__64BIT__)\r
110 #ifdef __ILP32__\r
111 #define MY_CPU_NAME "ppc64-32"\r
112 #define MY_CPU_SIZEOF_POINTER 4\r
113 #else\r
114 #define MY_CPU_NAME "ppc64"\r
115 #define MY_CPU_SIZEOF_POINTER 8\r
116 #endif\r
117 #define MY_CPU_64BIT\r
118#else\r
119 #define MY_CPU_NAME "ppc"\r
120 #define MY_CPU_SIZEOF_POINTER 4\r
121 /* #define MY_CPU_32BIT */\r
122#endif\r
123#endif\r
124\r
125\r
126#if defined(__riscv) \\r
127 || defined(__riscv__)\r
128 #if __riscv_xlen == 32\r
129 #define MY_CPU_NAME "riscv32"\r
130 #elif __riscv_xlen == 64\r
131 #define MY_CPU_NAME "riscv64"\r
132 #else\r
133 #define MY_CPU_NAME "riscv"\r
134 #endif\r
135#endif\r
136\r
137\r
138#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)\r
139#define MY_CPU_X86_OR_AMD64\r
140#endif\r
141\r
142#if defined(MY_CPU_ARM) || defined(MY_CPU_ARM64)\r
143#define MY_CPU_ARM_OR_ARM64\r
144#endif\r
145\r
146\r
147#ifdef _WIN32\r
148\r
149 #ifdef MY_CPU_ARM\r
150 #define MY_CPU_ARM_LE\r
151 #endif\r
152\r
153 #ifdef MY_CPU_ARM64\r
154 #define MY_CPU_ARM64_LE\r
155 #endif\r
156\r
157 #ifdef _M_IA64\r
158 #define MY_CPU_IA64_LE\r
159 #endif\r
160\r
161#endif\r
162\r
163\r
164#if defined(MY_CPU_X86_OR_AMD64) \\r
165 || defined(MY_CPU_ARM_LE) \\r
166 || defined(MY_CPU_ARM64_LE) \\r
167 || defined(MY_CPU_IA64_LE) \\r
168 || defined(__LITTLE_ENDIAN__) \\r
169 || defined(__ARMEL__) \\r
170 || defined(__THUMBEL__) \\r
171 || defined(__AARCH64EL__) \\r
172 || defined(__MIPSEL__) \\r
173 || defined(__MIPSEL) \\r
174 || defined(_MIPSEL) \\r
175 || defined(__BFIN__) \\r
176 || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))\r
177 #define MY_CPU_LE\r
178#endif\r
179\r
180#if defined(__BIG_ENDIAN__) \\r
181 || defined(__ARMEB__) \\r
182 || defined(__THUMBEB__) \\r
183 || defined(__AARCH64EB__) \\r
184 || defined(__MIPSEB__) \\r
185 || defined(__MIPSEB) \\r
186 || defined(_MIPSEB) \\r
187 || defined(__m68k__) \\r
188 || defined(__s390__) \\r
189 || defined(__s390x__) \\r
190 || defined(__zarch__) \\r
191 || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))\r
192 #define MY_CPU_BE\r
193#endif\r
194\r
195\r
196#if defined(MY_CPU_LE) && defined(MY_CPU_BE)\r
197 #error Stop_Compiling_Bad_Endian\r
198#endif\r
199\r
200\r
201#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)\r
202 #error Stop_Compiling_Bad_32_64_BIT\r
203#endif\r
204\r
205#ifdef __SIZEOF_POINTER__\r
206 #ifdef MY_CPU_SIZEOF_POINTER\r
207 #if MY_CPU_SIZEOF_POINTER != __SIZEOF_POINTER__\r
208 #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE\r
209 #endif\r
210 #else\r
211 #define MY_CPU_SIZEOF_POINTER __SIZEOF_POINTER__\r
212 #endif\r
213#endif\r
214\r
215#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)\r
216#if defined (_LP64)\r
217 #error Stop_Compiling_Bad_MY_CPU_PTR_SIZE\r
218#endif\r
219#endif\r
220\r
221#ifdef _MSC_VER\r
222 #if _MSC_VER >= 1300\r
223 #define MY_CPU_pragma_pack_push_1 __pragma(pack(push, 1))\r
224 #define MY_CPU_pragma_pop __pragma(pack(pop))\r
225 #else\r
226 #define MY_CPU_pragma_pack_push_1\r
227 #define MY_CPU_pragma_pop\r
228 #endif\r
229#else\r
230 #ifdef __xlC__\r
231 #define MY_CPU_pragma_pack_push_1 _Pragma("pack(1)")\r
232 #define MY_CPU_pragma_pop _Pragma("pack()")\r
233 #else\r
234 #define MY_CPU_pragma_pack_push_1 _Pragma("pack(push, 1)")\r
235 #define MY_CPU_pragma_pop _Pragma("pack(pop)")\r
236 #endif\r
237#endif\r
238\r
239\r
240#ifndef MY_CPU_NAME\r
241 #ifdef MY_CPU_LE\r
242 #define MY_CPU_NAME "LE"\r
243 #elif defined(MY_CPU_BE)\r
244 #define MY_CPU_NAME "BE"\r
245 #else\r
246 /*\r
247 #define MY_CPU_NAME ""\r
248 */\r
249 #endif\r
250#endif\r
251\r
252\r
253\r
254\r
255\r
256#ifdef MY_CPU_LE\r
257 #if defined(MY_CPU_X86_OR_AMD64) \\r
258 || defined(MY_CPU_ARM64)\r
259 #define MY_CPU_LE_UNALIGN\r
260 #define MY_CPU_LE_UNALIGN_64\r
261 #elif defined(__ARM_FEATURE_UNALIGNED)\r
262 /* gcc9 for 32-bit arm can use LDRD instruction that requires 32-bit alignment.\r
263 So we can't use unaligned 64-bit operations. */\r
264 #define MY_CPU_LE_UNALIGN\r
265 #endif\r
266#endif\r
267\r
268\r
269#ifdef MY_CPU_LE_UNALIGN\r
270\r
271#define GetUi16(p) (*(const UInt16 *)(const void *)(p))\r
272#define GetUi32(p) (*(const UInt32 *)(const void *)(p))\r
273#ifdef MY_CPU_LE_UNALIGN_64\r
274#define GetUi64(p) (*(const UInt64 *)(const void *)(p))\r
275#endif\r
276\r
277#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); }\r
278#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); }\r
279#ifdef MY_CPU_LE_UNALIGN_64\r
280#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); }\r
281#endif\r
282\r
283#else\r
284\r
285#define GetUi16(p) ( (UInt16) ( \\r
286 ((const Byte *)(p))[0] | \\r
287 ((UInt16)((const Byte *)(p))[1] << 8) ))\r
288\r
289#define GetUi32(p) ( \\r
290 ((const Byte *)(p))[0] | \\r
291 ((UInt32)((const Byte *)(p))[1] << 8) | \\r
292 ((UInt32)((const Byte *)(p))[2] << 16) | \\r
293 ((UInt32)((const Byte *)(p))[3] << 24))\r
294\r
295#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \\r
296 _ppp_[0] = (Byte)_vvv_; \\r
297 _ppp_[1] = (Byte)(_vvv_ >> 8); }\r
298\r
299#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \\r
300 _ppp_[0] = (Byte)_vvv_; \\r
301 _ppp_[1] = (Byte)(_vvv_ >> 8); \\r
302 _ppp_[2] = (Byte)(_vvv_ >> 16); \\r
303 _ppp_[3] = (Byte)(_vvv_ >> 24); }\r
304\r
305#endif\r
306\r
307\r
308#ifndef MY_CPU_LE_UNALIGN_64\r
309\r
310#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))\r
311\r
312#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \\r
313 SetUi32(_ppp2_ , (UInt32)_vvv2_); \\r
314 SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }\r
315\r
316#endif\r
317\r
318\r
319\r
320\r
321#ifdef __has_builtin\r
322 #define MY__has_builtin(x) __has_builtin(x)\r
323#else\r
324 #define MY__has_builtin(x) 0\r
325#endif\r
326\r
327#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ defined(_MSC_VER) && (_MSC_VER >= 1300)\r
328\r
329/* Note: we use bswap instruction, that is unsupported in 386 cpu */\r
330\r
331#include <stdlib.h>\r
332\r
333#pragma intrinsic(_byteswap_ushort)\r
334#pragma intrinsic(_byteswap_ulong)\r
335#pragma intrinsic(_byteswap_uint64)\r
336\r
337/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */\r
338#define GetBe32(p) _byteswap_ulong (*(const UInt32 *)(const void *)(p))\r
339#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const void *)(p))\r
340\r
341#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)\r
342\r
343#elif defined(MY_CPU_LE_UNALIGN) && ( \\r
344 (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \\r
345 || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )\r
346\r
347/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const void *)(p)) */\r
348#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const void *)(p))\r
349#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const void *)(p))\r
350\r
351#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)\r
352\r
353#else\r
354\r
355#define GetBe32(p) ( \\r
356 ((UInt32)((const Byte *)(p))[0] << 24) | \\r
357 ((UInt32)((const Byte *)(p))[1] << 16) | \\r
358 ((UInt32)((const Byte *)(p))[2] << 8) | \\r
359 ((const Byte *)(p))[3] )\r
360\r
361#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))\r
362\r
363#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \\r
364 _ppp_[0] = (Byte)(_vvv_ >> 24); \\r
365 _ppp_[1] = (Byte)(_vvv_ >> 16); \\r
366 _ppp_[2] = (Byte)(_vvv_ >> 8); \\r
367 _ppp_[3] = (Byte)_vvv_; }\r
368\r
369#endif\r
370\r
371\r
372#ifndef GetBe16\r
373\r
374#define GetBe16(p) ( (UInt16) ( \\r
375 ((UInt16)((const Byte *)(p))[0] << 8) | \\r
376 ((const Byte *)(p))[1] ))\r
377\r
378#endif\r
379\r
380\r
381\r
382#ifdef MY_CPU_X86_OR_AMD64\r
383\r
384typedef struct\r
385{\r
386 UInt32 maxFunc;\r
387 UInt32 vendor[3];\r
388 UInt32 ver;\r
389 UInt32 b;\r
390 UInt32 c;\r
391 UInt32 d;\r
392} Cx86cpuid;\r
393\r
394enum\r
395{\r
396 CPU_FIRM_INTEL,\r
397 CPU_FIRM_AMD,\r
398 CPU_FIRM_VIA\r
399};\r
400\r
401void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);\r
402\r
403BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p);\r
404int x86cpuid_GetFirm(const Cx86cpuid *p);\r
405\r
406#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))\r
407#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))\r
408#define x86cpuid_GetStepping(ver) (ver & 0xF)\r
409\r
410BoolInt CPU_Is_InOrder(void);\r
411\r
412BoolInt CPU_IsSupported_AES(void);\r
413BoolInt CPU_IsSupported_AVX2(void);\r
414BoolInt CPU_IsSupported_VAES_AVX2(void);\r
415BoolInt CPU_IsSupported_SSSE3(void);\r
416BoolInt CPU_IsSupported_SSE41(void);\r
417BoolInt CPU_IsSupported_SHA(void);\r
418BoolInt CPU_IsSupported_PageGB(void);\r
419\r
420#elif defined(MY_CPU_ARM_OR_ARM64)\r
421\r
422BoolInt CPU_IsSupported_CRC32(void);\r
423BoolInt CPU_IsSupported_NEON(void);\r
424\r
425#if defined(_WIN32)\r
426BoolInt CPU_IsSupported_CRYPTO(void);\r
427#define CPU_IsSupported_SHA1 CPU_IsSupported_CRYPTO\r
428#define CPU_IsSupported_SHA2 CPU_IsSupported_CRYPTO\r
429#define CPU_IsSupported_AES CPU_IsSupported_CRYPTO\r
430#else\r
431BoolInt CPU_IsSupported_SHA1(void);\r
432BoolInt CPU_IsSupported_SHA2(void);\r
433BoolInt CPU_IsSupported_AES(void);\r
434#endif\r
435\r
436#endif\r
437\r
438#if defined(__APPLE__)\r
439int My_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize);\r
440int My_sysctlbyname_Get_UInt32(const char *name, UInt32 *val);\r
441#endif\r
442\r
443EXTERN_C_END\r
444\r
445#endif\r