15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* CpuArch.h -- CPU specific code
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)2010-10-26: Igor Pavlov : Public domain */
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __CPU_ARCH_H
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __CPU_ARCH_H
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Types.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EXTERN_C_BEGIN
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MY_CPU_LE means that CPU is LITTLE ENDIAN.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_AMD64
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(MY_CPU_AMD64) || defined(_M_IA64)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_64BIT
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_M_IX86) || defined(__i386__)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_X86
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_X86_OR_AMD64
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(MY_CPU_X86) || defined(_M_ARM)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_32BIT
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_WIN32) && defined(_M_ARM)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_ARM_LE
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_WIN32) && defined(_M_IA64)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_IA64_LE
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(MY_CPU_X86_OR_AMD64)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_LE_UNALIGN
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE)  || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_LE
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__BIG_ENDIAN__)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MY_CPU_BE
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Stop_Compiling_Bad_Endian
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef MY_CPU_LE_UNALIGN
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetUi16(p) (*(const UInt16 *)(p))
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetUi32(p) (*(const UInt32 *)(p))
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetUi64(p) (*(const UInt64 *)(p))
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SetUi16(p, d) *(UInt16 *)(p) = (d);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SetUi32(p, d) *(UInt32 *)(p) = (d);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SetUi64(p, d) *(UInt64 *)(p) = (d);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetUi32(p) ( \
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             ((const Byte *)(p))[0]        | \
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((UInt32)((const Byte *)(p))[1] <<  8) | \
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((UInt32)((const Byte *)(p))[2] << 16) | \
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((UInt32)((const Byte *)(p))[3] << 24))
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SetUi16(p, d) { UInt32 _x_ = (d); \
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((Byte *)(p))[0] = (Byte)_x_; \
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SetUi32(p, d) { UInt32 _x_ = (d); \
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((Byte *)(p))[0] = (Byte)_x_; \
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SetUi64(p, d) { UInt64 _x64_ = (d); \
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetUi32(p, (UInt32)_x64_); \
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma intrinsic(_byteswap_ulong)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma intrinsic(_byteswap_uint64)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetBe32(p) ( \
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((UInt32)((const Byte *)(p))[0] << 24) | \
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((UInt32)((const Byte *)(p))[1] << 16) | \
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((UInt32)((const Byte *)(p))[2] <<  8) | \
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             ((const Byte *)(p))[3] )
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef MY_CPU_X86_OR_AMD64
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32 maxFunc;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32 vendor[3];
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32 ver;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32 b;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32 c;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UInt32 d;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} Cx86cpuid;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CPU_FIRM_INTEL,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CPU_FIRM_AMD,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CPU_FIRM_VIA
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int x86cpuid_GetFirm(const Cx86cpuid *p);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bool CPU_Is_InOrder();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bool CPU_Is_Aes_Supported();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EXTERN_C_END
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
157