Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* CpuArch.h -- CPU specific code
  2. 2015-08-02: Igor Pavlov : Public domain */
  3.  
  4. #ifndef __CPU_ARCH_H
  5. #define __CPU_ARCH_H
  6.  
  7. #include "7zTypes.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) \
  24.     || defined(_M_IA64) \
  25.     || defined(__AARCH64EL__) \
  26.     || defined(__AARCH64EB__)
  27.   #define MY_CPU_64BIT
  28. #endif
  29.  
  30. #if defined(_M_IX86) || defined(__i386__)
  31. #define MY_CPU_X86
  32. #endif
  33.  
  34. #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
  35. #define MY_CPU_X86_OR_AMD64
  36. #endif
  37.  
  38. #if defined(MY_CPU_X86) \
  39.     || defined(_M_ARM) \
  40.     || defined(__ARMEL__) \
  41.     || defined(__THUMBEL__) \
  42.     || defined(__ARMEB__) \
  43.     || defined(__THUMBEB__)
  44.   #define MY_CPU_32BIT
  45. #endif
  46.  
  47. #if defined(_WIN32) && defined(_M_ARM)
  48. #define MY_CPU_ARM_LE
  49. #endif
  50.  
  51. #if defined(_WIN32) && defined(_M_IA64)
  52. #define MY_CPU_IA64_LE
  53. #endif
  54.  
  55. #if defined(MY_CPU_X86_OR_AMD64)
  56. #define MY_CPU_LE_UNALIGN
  57. #endif
  58.  
  59. #if defined(MY_CPU_X86_OR_AMD64) \
  60.     || defined(MY_CPU_ARM_LE) \
  61.     || defined(MY_CPU_IA64_LE) \
  62.     || defined(__LITTLE_ENDIAN__) \
  63.     || defined(__ARMEL__) \
  64.     || defined(__THUMBEL__) \
  65.     || defined(__AARCH64EL__) \
  66.     || defined(__MIPSEL__) \
  67.     || defined(__MIPSEL) \
  68.     || defined(_MIPSEL)
  69.   #define MY_CPU_LE
  70. #endif
  71.  
  72. #if defined(__BIG_ENDIAN__) \
  73.     || defined(__ARMEB__) \
  74.     || defined(__THUMBEB__) \
  75.     || defined(__AARCH64EB__) \
  76.     || defined(__MIPSEB__) \
  77.     || defined(__MIPSEB) \
  78.     || defined(_MIPSEB) \
  79.     || defined(__m68k__)
  80.   #define MY_CPU_BE
  81. #endif
  82.  
  83. #if defined(MY_CPU_LE) && defined(MY_CPU_BE)
  84. Stop_Compiling_Bad_Endian
  85. #endif
  86.  
  87.  
  88. #ifdef MY_CPU_LE_UNALIGN
  89.  
  90. #define GetUi16(p) (*(const UInt16 *)(const void *)(p))
  91. #define GetUi32(p) (*(const UInt32 *)(const void *)(p))
  92. #define GetUi64(p) (*(const UInt64 *)(const void *)(p))
  93.  
  94. #define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
  95. #define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
  96. #define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
  97.  
  98. #else
  99.  
  100. #define GetUi16(p) ( (UInt16) ( \
  101.              ((const Byte *)(p))[0] | \
  102.     ((UInt16)((const Byte *)(p))[1] << 8) ))
  103.  
  104. #define GetUi32(p) ( \
  105.              ((const Byte *)(p))[0]        | \
  106.     ((UInt32)((const Byte *)(p))[1] <<  8) | \
  107.     ((UInt32)((const Byte *)(p))[2] << 16) | \
  108.     ((UInt32)((const Byte *)(p))[3] << 24))
  109.  
  110. #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
  111.  
  112. #define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
  113.     _ppp_[0] = (Byte)_vvv_; \
  114.     _ppp_[1] = (Byte)(_vvv_ >> 8); }
  115.  
  116. #define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
  117.     _ppp_[0] = (Byte)_vvv_; \
  118.     _ppp_[1] = (Byte)(_vvv_ >> 8); \
  119.     _ppp_[2] = (Byte)(_vvv_ >> 16); \
  120.     _ppp_[3] = (Byte)(_vvv_ >> 24); }
  121.  
  122. #define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
  123.     SetUi32(_ppp2_    , (UInt32)_vvv2_); \
  124.     SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
  125.  
  126. #endif
  127.  
  128.  
  129. #if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
  130.  
  131. #include <stdlib.h>
  132.  
  133. #pragma intrinsic(_byteswap_ulong)
  134. #pragma intrinsic(_byteswap_uint64)
  135. #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
  136. #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
  137.  
  138. #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
  139.  
  140. #else
  141.  
  142. #define GetBe32(p) ( \
  143.     ((UInt32)((const Byte *)(p))[0] << 24) | \
  144.     ((UInt32)((const Byte *)(p))[1] << 16) | \
  145.     ((UInt32)((const Byte *)(p))[2] <<  8) | \
  146.              ((const Byte *)(p))[3] )
  147.  
  148. #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
  149.  
  150. #define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
  151.     _ppp_[0] = (Byte)(_vvv_ >> 24); \
  152.     _ppp_[1] = (Byte)(_vvv_ >> 16); \
  153.     _ppp_[2] = (Byte)(_vvv_ >> 8); \
  154.     _ppp_[3] = (Byte)_vvv_; }
  155.  
  156. #endif
  157.  
  158.  
  159. #define GetBe16(p) ( (UInt16) ( \
  160.     ((UInt16)((const Byte *)(p))[0] << 8) | \
  161.              ((const Byte *)(p))[1] ))
  162.  
  163.  
  164.  
  165. #ifdef MY_CPU_X86_OR_AMD64
  166.  
  167. typedef struct
  168. {
  169.   UInt32 maxFunc;
  170.   UInt32 vendor[3];
  171.   UInt32 ver;
  172.   UInt32 b;
  173.   UInt32 c;
  174.   UInt32 d;
  175. } Cx86cpuid;
  176.  
  177. enum
  178. {
  179.   CPU_FIRM_INTEL,
  180.   CPU_FIRM_AMD,
  181.   CPU_FIRM_VIA
  182. };
  183.  
  184. void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
  185.  
  186. Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
  187. int x86cpuid_GetFirm(const Cx86cpuid *p);
  188.  
  189. #define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
  190. #define x86cpuid_GetModel(ver)  (((ver >> 12) &  0xF0) | ((ver >> 4) & 0xF))
  191. #define x86cpuid_GetStepping(ver) (ver & 0xF)
  192.  
  193. Bool CPU_Is_InOrder();
  194. Bool CPU_Is_Aes_Supported();
  195.  
  196. #endif
  197.  
  198. EXTERN_C_END
  199.  
  200. #endif
  201.