home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 7662 / gttool_src_bin.7z / gttool / src / util.h < prev    next >
Encoding:
C/C++ Source or Header  |  2014-02-17  |  6.0 KB  |  232 lines

  1. #pragma once
  2.  
  3. #include "common.h"
  4.  
  5. inline uint32_t hi32(const uint64_t x)
  6. {
  7.     return (x >> 32);
  8. }
  9.  
  10. inline uint32_t lo32(const uint64_t x)
  11. {
  12.     return (x & 0xFFFFFFFFu);
  13. }
  14.  
  15. union uint128_t
  16. {
  17.     inline uint128_t()
  18.         : hi(0)
  19.         , lo(0)
  20.     {
  21.     }
  22.  
  23.     inline uint128_t(uint64_t x)
  24.         : hi(0)
  25.         , lo(x)
  26.     {
  27.     }
  28.  
  29.     struct
  30.     {
  31.         uint64_t hi;
  32.         uint64_t lo;
  33.     };
  34. };
  35.  
  36. uint128_t mul64(const uint64_t a, const uint64_t b);
  37.  
  38. inline uint32_t float_as_uint(const float x)
  39. {
  40.     union { float f; uint32_t u; } f2u;
  41.     f2u.f = x;
  42.     return f2u.u;
  43. }
  44.  
  45. inline float uint_as_float(const uint32_t x)
  46. {
  47.     union { uint32_t u; float f; } u2f;
  48.     u2f.u = x;
  49.     return u2f.f;
  50. }
  51.  
  52. inline uint64_t double_as_uint(const double x)
  53. {
  54.     union { double f; uint64_t u; } f2u;
  55.     f2u.f = x;
  56.     return f2u.u;
  57. }
  58.  
  59. inline double uint_as_double(const uint64_t x)
  60. {
  61.     union { uint64_t u; double f; } u2f;
  62.     u2f.u = x;
  63.     return u2f.f;
  64. }
  65.  
  66. template<typename T>
  67. inline typename std::enable_if<std::is_arithmetic<T>::value && std::is_signed<T>::value, T>::type isign(T x)
  68. {
  69.     return (x >> (sizeof(x) * CHAR_BIT - 1));
  70. }
  71.  
  72. uint32_t bitmask32(const int begin, const int end);
  73.  
  74. uint32_t rotl(const uint32_t x, int n);
  75. uint32_t rotr(const uint32_t x, int n);
  76.  
  77. uint32_t rlwinm(const uint32_t rs, const uint32_t sh, const int mb, const int me);
  78. uint32_t rlwimi(const uint32_t ra, const uint32_t rs, const uint32_t sh, const int mb, const int me);
  79. uint32_t clrlslwi(const uint32_t rs, const int b, const int n);
  80. uint32_t slw(const uint32_t ra, const uint32_t rs, const int rb);
  81. int32_t srawi(const int32_t rs, const int b);
  82.  
  83. template<typename T>
  84. inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type align_up(T address, size_t alignment)
  85. {
  86.     return (address + (alignment - 1)) & ~(T(alignment) - 1);
  87. }
  88.  
  89. template<typename T>
  90. inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type align_down(T address, size_t alignment)
  91. {
  92.     return address & ~(T(alignment) - 1);
  93. }
  94.  
  95. inline const void* advance_pointer(const void* ptr, intptr_t offset)
  96. {
  97.     return static_cast<const char*>(ptr) + offset;
  98. }
  99.  
  100. template<typename T> inline typename std::enable_if<std::is_enum<T>::value, T>::type operator ~(T x) { return static_cast<T>(~static_cast<typename std::underlying_type<T>::type>(x)); }
  101. template<typename T> inline typename std::enable_if<std::is_enum<T>::value, T>::type operator &(T x, T y) { return static_cast<T>(static_cast<typename std::underlying_type<T>::type>(x) & static_cast<typename std::underlying_type<T>::type>(y)); }
  102. template<typename T> inline typename std::enable_if<std::is_enum<T>::value, T>::type operator |(T x, T y) { return static_cast<T>(static_cast<typename std::underlying_type<T>::type>(x) | static_cast<typename std::underlying_type<T>::type>(y)); }
  103. template<typename T> inline typename std::enable_if<std::is_enum<T>::value, T>::type operator ^(T x, T y) { return static_cast<T>(static_cast<typename std::underlying_type<T>::type>(x) ^ static_cast<typename std::underlying_type<T>::type>(y)); }
  104.  
  105. namespace detail
  106. {
  107.     template<typename T, size_t Size>
  108.     struct swap_bytes
  109.     {
  110.         inline T operator()(const T x)
  111.         {
  112.             throw std::out_of_range("Unsupported type size");
  113.         }
  114.     };
  115.  
  116.     template<typename T>
  117.     struct swap_bytes<T, 1>
  118.     {
  119.         inline T operator()(const T x)
  120.         {
  121.             return x;
  122.         }
  123.     };
  124.  
  125.     template<typename T>
  126.     struct swap_bytes<T, 2>
  127.     {
  128.         inline T operator()(const T x)
  129.         {
  130.             return ((x >> 8) & 0xFF) | ((x & 0xFF) << 8);
  131.         }
  132.     };
  133.  
  134.     template<typename T>
  135.     struct swap_bytes<T, 4>
  136.     {
  137.         inline T operator()(const T x)
  138.         {
  139.             return ((x & 0xFF000000u) >> 24) | ((x & 0x00FF0000u) >> 8) | ((x & 0x0000FF00u) << 8) | ((x & 0x000000FFu) << 24);
  140.         }
  141.     };
  142.  
  143.     template<>
  144.     struct swap_bytes<float, 4>
  145.     {
  146.         inline float operator()(const float x)
  147.         {
  148.             return uint_as_float(swap_bytes<uint32_t, sizeof(uint32_t)>()(float_as_uint(x)));
  149.         }
  150.     };
  151.  
  152.     template<typename T>
  153.     struct swap_bytes<T, 8>
  154.     {
  155.         inline T operator()(const T x)
  156.         {
  157.             return ((x & 0xFF00000000000000ull) >> 56) | ((x & 0x00FF000000000000ull) >> 40) | ((x & 0x0000FF0000000000ull) >> 24) | ((x & 0x000000FF00000000ull) >> 8) | ((x & 0x00000000FF000000ull) << 8) | ((x & 0x0000000000FF0000ull) << 24) | ((x & 0x000000000000FF00ull) << 40) | ((x & 0x00000000000000FFull) << 56);
  158.         }
  159.     };
  160.  
  161.     template<>
  162.     struct swap_bytes<double, 8>
  163.     {
  164.         inline double operator()(const double x)
  165.         {
  166.             return uint_as_double(swap_bytes<uint64_t, sizeof(uint64_t)>()(double_as_uint(x)));
  167.         }
  168.     };
  169.  
  170.     template<Endianness from, Endianness to, typename T>
  171.     struct do_byte_swap
  172.     {
  173.         inline T operator()(const T x)
  174.         {
  175.             return swap_bytes<T, sizeof(T)>()(x);
  176.         }
  177.     };
  178.  
  179.     template<typename T> struct do_byte_swap<Endianness::kLITTLE, Endianness::kLITTLE, T>
  180.     {
  181.         inline T operator()(const T x)
  182.         {
  183.             return x;
  184.         }
  185.     };
  186.  
  187.     template<typename T> struct do_byte_swap<Endianness::kBIG, Endianness::kBIG, T>
  188.     {
  189.         inline T operator()(const T x)
  190.         {
  191.             return x;
  192.         }
  193.     };
  194. }
  195.  
  196. template<typename T>
  197. inline T swap_bytes(const T x)
  198. {
  199.     static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Unsupported type size");
  200.     static_assert(std::is_arithmetic<T>::value, "Non arithmetic type");
  201.     return detail::swap_bytes<T, sizeof(T)>()(x);
  202. }
  203.  
  204. template<Endianness from, Endianness to, typename T>
  205. inline T byte_swap(const T x)
  206. {
  207.     static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Unsupported type size");
  208.     static_assert(std::is_arithmetic<T>::value, "Non arithmetic type");
  209.     return detail::do_byte_swap<from, to, T>()(x);
  210. }
  211.  
  212. template<typename T>
  213. inline T little_to_host(const T x)
  214. {
  215.     return byte_swap<Endianness::kLITTLE, Endianness::kHOST>(x);
  216. }
  217.  
  218. template<typename T> inline T big_to_host(const T x)
  219. {
  220.     return byte_swap<Endianness::kBIG, Endianness::kHOST>(x);
  221. }
  222.  
  223. template<typename T> inline T host_to_little(const T x)
  224. {
  225.     return byte_swap<Endianness::kHOST, Endianness::kLITTLE>(x);
  226. }
  227.  
  228. template<typename T> inline T host_to_big(const T x)
  229. {
  230.     return byte_swap<Endianness::kHOST, Endianness::kBIG>(x);
  231. }
  232.