intrinPortable.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. Copyright (c) 2018 tevador
  3. This file is part of RandomX.
  4. RandomX is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. RandomX is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with RandomX. If not, see<http://www.gnu.org/licenses/>.
  14. */
  15. #pragma once
  16. #if defined(_MSC_VER)
  17. #if defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP == 2)
  18. #define __SSE2__ 1
  19. #endif
  20. #endif
  21. #ifdef __SSE2__
  22. #ifdef __GNUC__
  23. #include <x86intrin.h>
  24. #else
  25. #include <intrin.h>
  26. #endif
  27. #else
  28. #include <cstdint>
  29. #include <stdexcept>
  30. #define _mm_malloc(a,b) malloc(a)
  31. #define _mm_free(a) free(a)
  32. typedef union {
  33. uint64_t u64[2];
  34. uint32_t u32[4];
  35. uint16_t u16[8];
  36. uint8_t u8[16];
  37. } __m128i;
  38. static const char* platformError = "Platform doesn't support hardware AES";
  39. inline __m128i _mm_aeskeygenassist_si128(__m128i key, uint8_t rcon) {
  40. throw std::runtime_error(platformError);
  41. }
  42. inline __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) {
  43. throw std::runtime_error(platformError);
  44. }
  45. inline __m128i _mm_aesdec_si128(__m128i v, __m128i rkey) {
  46. throw std::runtime_error(platformError);
  47. }
  48. inline int _mm_cvtsi128_si32(__m128i v) {
  49. return v.u32[0];
  50. }
  51. inline __m128i _mm_cvtsi32_si128(int si32) {
  52. __m128i v;
  53. v.u32[0] = si32;
  54. v.u32[1] = 0;
  55. v.u32[2] = 0;
  56. v.u32[3] = 0;
  57. return v;
  58. }
  59. inline __m128i _mm_set_epi64x(int64_t _I1, int64_t _I0) {
  60. __m128i v;
  61. v.u64[0] = _I0;
  62. v.u64[1] = _I1;
  63. return v;
  64. }
  65. inline __m128i _mm_set_epi32(int _I3, int _I2, int _I1, int _I0) {
  66. __m128i v;
  67. v.u32[0] = _I0;
  68. v.u32[1] = _I1;
  69. v.u32[2] = _I2;
  70. v.u32[3] = _I3;
  71. return v;
  72. };
  73. inline __m128i _mm_xor_si128(__m128i _A, __m128i _B) {
  74. __m128i c;
  75. c.u32[0] = _A.u32[0] ^ _B.u32[0];
  76. c.u32[1] = _A.u32[1] ^ _B.u32[1];
  77. c.u32[2] = _A.u32[2] ^ _B.u32[2];
  78. c.u32[3] = _A.u32[3] ^ _B.u32[3];
  79. return c;
  80. }
  81. inline __m128i _mm_shuffle_epi32(__m128i _A, int _Imm) {
  82. __m128i c;
  83. c.u32[0] = _A.u32[_Imm & 3];
  84. c.u32[1] = _A.u32[(_Imm >> 2) & 3];
  85. c.u32[2] = _A.u32[(_Imm >> 4) & 3];
  86. c.u32[3] = _A.u32[(_Imm >> 6) & 3];
  87. return c;
  88. }
  89. inline __m128i _mm_load_si128(__m128i const*_P) {
  90. return *_P;
  91. }
  92. inline void _mm_store_si128(__m128i *_P, __m128i _B) {
  93. *_P = _B;
  94. }
  95. inline __m128i _mm_slli_si128(__m128i _A, int _Imm) {
  96. _Imm &= 255;
  97. if (_Imm > 15) {
  98. _A.u64[0] = 0;
  99. _A.u64[1] = 0;
  100. }
  101. else {
  102. for (int i = 15; i >= _Imm; --i) {
  103. _A.u8[i] = _A.u8[i - _Imm];
  104. }
  105. for (int i = 0; i < _Imm; ++i) {
  106. _A.u8[i] = 0;
  107. }
  108. }
  109. return _A;
  110. }
  111. #endif