File indexing completed on 2025-02-02 04:25:58
0001 /* CpuArch.h -- CPU specific code 0002 2013-11-12: Igor Pavlov : Public domain */ 0003 0004 #ifndef __CPU_ARCH_H 0005 #define __CPU_ARCH_H 0006 0007 #include "7zTypes.h" 0008 0009 EXTERN_C_BEGIN 0010 0011 /* 0012 MY_CPU_LE means that CPU is LITTLE ENDIAN. 0013 If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). 0014 0015 MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. 0016 If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. 0017 */ 0018 0019 #if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) 0020 #define MY_CPU_AMD64 0021 #endif 0022 0023 #if defined(MY_CPU_AMD64) || defined(_M_IA64) 0024 #define MY_CPU_64BIT 0025 #endif 0026 0027 #if defined(_M_IX86) || defined(__i386__) 0028 #define MY_CPU_X86 0029 #endif 0030 0031 #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) 0032 #define MY_CPU_X86_OR_AMD64 0033 #endif 0034 0035 #if defined(MY_CPU_X86) || defined(_M_ARM) 0036 #define MY_CPU_32BIT 0037 #endif 0038 0039 #if defined(_WIN32) && defined(_M_ARM) 0040 #define MY_CPU_ARM_LE 0041 #endif 0042 0043 #if defined(_WIN32) && defined(_M_IA64) 0044 #define MY_CPU_IA64_LE 0045 #endif 0046 0047 #if defined(MY_CPU_X86_OR_AMD64) 0048 #define MY_CPU_LE_UNALIGN 0049 #endif 0050 0051 #if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) 0052 #define MY_CPU_LE 0053 #endif 0054 0055 #if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__) 0056 #define MY_CPU_BE 0057 #endif 0058 0059 #if defined(MY_CPU_LE) && defined(MY_CPU_BE) 0060 Stop_Compiling_Bad_Endian 0061 #endif 0062 0063 #ifdef MY_CPU_LE_UNALIGN 0064 0065 #define GetUi16(p) (*(const UInt16 *)(const void *)(p)) 0066 #define GetUi32(p) (*(const UInt32 *)(const void *)(p)) 0067 #define GetUi64(p) (*(const UInt64 *)(const void *)(p)) 0068 #define SetUi16(p, d) *(UInt16 *)(p) = (d); 0069 #define SetUi32(p, d) *(UInt32 *)(p) = (d); 0070 #define SetUi64(p, d) *(UInt64 *)(p) = (d); 0071 0072 #else 0073 0074 #define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) 0075 0076 #define GetUi32(p) ( \ 0077 ((const Byte *)(p))[0] | \ 0078 ((UInt32)((const Byte *)(p))[1] << 8) | \ 0079 ((UInt32)((const Byte *)(p))[2] << 16) | \ 0080 ((UInt32)((const Byte *)(p))[3] << 24)) 0081 0082 #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) 0083 0084 #define SetUi16(p, d) { UInt32 _x_ = (d); \ 0085 ((Byte *)(p))[0] = (Byte)_x_; \ 0086 ((Byte *)(p))[1] = (Byte)(_x_ >> 8); } 0087 0088 #define SetUi32(p, d) { UInt32 _x_ = (d); \ 0089 ((Byte *)(p))[0] = (Byte)_x_; \ 0090 ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ 0091 ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ 0092 ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } 0093 0094 #define SetUi64(p, d) { UInt64 _x64_ = (d); \ 0095 SetUi32(p, (UInt32)_x64_); \ 0096 SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } 0097 0098 #endif 0099 0100 #if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) 0101 0102 #include <stdlib.h> 0103 0104 #pragma intrinsic(_byteswap_ulong) 0105 #pragma intrinsic(_byteswap_uint64) 0106 #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) 0107 #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) 0108 0109 #else 0110 0111 #define GetBe32(p) ( \ 0112 ((UInt32)((const Byte *)(p))[0] << 24) | \ 0113 ((UInt32)((const Byte *)(p))[1] << 16) | \ 0114 ((UInt32)((const Byte *)(p))[2] << 8) | \ 0115 ((const Byte *)(p))[3] ) 0116 0117 #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) 0118 0119 #endif 0120 0121 #define GetBe16(p) ((UInt16)(((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])) 0122 0123 0124 #ifdef MY_CPU_X86_OR_AMD64 0125 0126 typedef struct 0127 { 0128 UInt32 maxFunc; 0129 UInt32 vendor[3]; 0130 UInt32 ver; 0131 UInt32 b; 0132 UInt32 c; 0133 UInt32 d; 0134 } Cx86cpuid; 0135 0136 enum 0137 { 0138 CPU_FIRM_INTEL, 0139 CPU_FIRM_AMD, 0140 CPU_FIRM_VIA 0141 }; 0142 0143 Bool x86cpuid_CheckAndRead(Cx86cpuid *p); 0144 int x86cpuid_GetFirm(const Cx86cpuid *p); 0145 0146 #define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) 0147 #define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) 0148 #define x86cpuid_GetStepping(p) ((p)->ver & 0xF) 0149 0150 Bool CPU_Is_InOrder(); 0151 Bool CPU_Is_Aes_Supported(); 0152 0153 #endif 0154 0155 EXTERN_C_END 0156 0157 #endif