1 | /* CpuArch.h -- CPU specific code |
2 | 2010-12-01: Igor Pavlov : Public domain */ |
3 | |
4 | #ifndef __CPU_ARCH_H |
5 | #define __CPU_ARCH_H |
6 | |
7 | #include "Types.h" |
8 | |
9 | EXTERN_C_BEGIN |
10 | |
11 | /* |
12 | MY_CPU_LE means that CPU is LITTLE ENDIAN. |
13 | If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). |
14 | |
15 | MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. |
16 | If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. |
17 | */ |
18 | |
19 | #if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) |
20 | #define MY_CPU_AMD64 |
21 | #endif |
22 | |
23 | #if defined(MY_CPU_AMD64) || defined(_M_IA64) |
24 | #define MY_CPU_64BIT |
25 | #endif |
26 | |
27 | #if defined(_M_IX86) || defined(__i386__) |
28 | #define MY_CPU_X86 |
29 | #endif |
30 | |
31 | #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) |
32 | #define MY_CPU_X86_OR_AMD64 |
33 | #endif |
34 | |
35 | #if defined(MY_CPU_X86) || defined(_M_ARM) |
36 | #define MY_CPU_32BIT |
37 | #endif |
38 | |
39 | #if defined(_WIN32) && defined(_M_ARM) |
40 | #define MY_CPU_ARM_LE |
41 | #endif |
42 | |
43 | #if defined(_WIN32) && defined(_M_IA64) |
44 | #define MY_CPU_IA64_LE |
45 | #endif |
46 | |
47 | #if defined(MY_CPU_X86_OR_AMD64) |
48 | #define MY_CPU_LE_UNALIGN |
49 | #endif |
50 | |
51 | #if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) |
52 | #define MY_CPU_LE |
53 | #endif |
54 | |
55 | #if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__) |
56 | #define MY_CPU_BE |
57 | #endif |
58 | |
59 | #if defined(MY_CPU_LE) && defined(MY_CPU_BE) |
60 | Stop_Compiling_Bad_Endian |
61 | #endif |
62 | |
63 | #ifdef MY_CPU_LE_UNALIGN |
64 | |
65 | #define GetUi16(p) (*(const UInt16 *)(p)) |
66 | #define GetUi32(p) (*(const UInt32 *)(p)) |
67 | #define GetUi64(p) (*(const UInt64 *)(p)) |
68 | #define SetUi16(p, d) *(UInt16 *)(p) = (d); |
69 | #define SetUi32(p, d) *(UInt32 *)(p) = (d); |
70 | #define SetUi64(p, d) *(UInt64 *)(p) = (d); |
71 | |
72 | #else |
73 | |
74 | #define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) |
75 | |
76 | #define GetUi32(p) ( \ |
77 | ((const Byte *)(p))[0] | \ |
78 | ((UInt32)((const Byte *)(p))[1] << 8) | \ |
79 | ((UInt32)((const Byte *)(p))[2] << 16) | \ |
80 | ((UInt32)((const Byte *)(p))[3] << 24)) |
81 | |
82 | #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) |
83 | |
84 | #define SetUi16(p, d) { UInt32 _x_ = (d); \ |
85 | ((Byte *)(p))[0] = (Byte)_x_; \ |
86 | ((Byte *)(p))[1] = (Byte)(_x_ >> 8); } |
87 | |
88 | #define SetUi32(p, d) { UInt32 _x_ = (d); \ |
89 | ((Byte *)(p))[0] = (Byte)_x_; \ |
90 | ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ |
91 | ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ |
92 | ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } |
93 | |
94 | #define SetUi64(p, d) { UInt64 _x64_ = (d); \ |
95 | SetUi32(p, (UInt32)_x64_); \ |
96 | SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } |
97 | |
98 | #endif |
99 | |
100 | #if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) |
101 | |
102 | #pragma intrinsic(_byteswap_ulong) |
103 | #pragma intrinsic(_byteswap_uint64) |
104 | #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) |
105 | #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) |
106 | |
107 | #else |
108 | |
109 | #define GetBe32(p) ( \ |
110 | ((UInt32)((const Byte *)(p))[0] << 24) | \ |
111 | ((UInt32)((const Byte *)(p))[1] << 16) | \ |
112 | ((UInt32)((const Byte *)(p))[2] << 8) | \ |
113 | ((const Byte *)(p))[3] ) |
114 | |
115 | #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) |
116 | |
117 | #endif |
118 | |
119 | #define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) |
120 | |
121 | |
122 | #ifdef MY_CPU_X86_OR_AMD64 |
123 | |
124 | typedef struct |
125 | { |
126 | UInt32 maxFunc; |
127 | UInt32 vendor[3]; |
128 | UInt32 ver; |
129 | UInt32 b; |
130 | UInt32 c; |
131 | UInt32 d; |
132 | } Cx86cpuid; |
133 | |
134 | enum |
135 | { |
136 | CPU_FIRM_INTEL, |
137 | CPU_FIRM_AMD, |
138 | CPU_FIRM_VIA |
139 | }; |
140 | |
141 | Bool x86cpuid_CheckAndRead(Cx86cpuid *p); |
142 | int x86cpuid_GetFirm(const Cx86cpuid *p); |
143 | |
144 | #define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) |
145 | #define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) |
146 | #define x86cpuid_GetStepping(p) ((p)->ver & 0xF) |
147 | |
148 | Bool CPU_Is_InOrder(); |
149 | Bool CPU_Is_Aes_Supported(); |
150 | |
151 | #endif |
152 | |
153 | EXTERN_C_END |
154 | |
155 | #endif |
156 | |