107 #ifndef CRYPTOPP_PPC_CRYPTO_H
108 #define CRYPTOPP_PPC_CRYPTO_H
113 #if defined(__ALTIVEC__)
114 # include <altivec.h>
124 #if defined(_AIX) && defined(_ARCH_PWR7) && defined(__xlC__)
132 #if defined(_AIX) && defined(_ARCH_PWR8) && defined(__xlC__)
133 # define __CRYPTO__ 1
141 #define CONST_V8_CAST(x) ((unsigned char*)(x))
147 #define CONST_V32_CAST(x) ((unsigned int*)(x))
153 #define CONST_V64_CAST(x) ((unsigned long long*)(x))
159 #define NCONST_V8_CAST(x) ((unsigned char*)(x))
165 #define NCONST_V32_CAST(x) ((unsigned int*)(x))
171 #define NCONST_V64_CAST(x) ((unsigned long long*)(x))
175 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
176 # pragma GCC diagnostic push
177 # pragma GCC diagnostic ignored "-Wdeprecated"
182 #if defined(__ALTIVEC__) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
200 #if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
209 #endif // VSX or ARCH_PWR8
240 #if defined(CRYPTOPP_BIG_ENDIAN)
241 const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0};
242 return (T)vec_perm(data, data, mask);
244 const uint8x16_p mask = {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15};
245 return (T)vec_perm(data, data, mask);
261 #if defined(CRYPTOPP_LITTLE_ENDIAN)
262 const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0};
263 return (T)vec_perm(data, data, mask);
281 #if defined(CRYPTOPP_BIG_ENDIAN)
282 const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0};
283 return (T)vec_perm(data, data, mask);
307 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src);
338 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src)+off;
371 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src);
373 CRYPTOPP_UNUSED(addr);
375 #if defined(_ARCH_PWR9)
401 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src)+off;
403 CRYPTOPP_UNUSED(addr);
405 #if defined(_ARCH_PWR9)
430 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src);
432 CRYPTOPP_UNUSED(addr);
434 #if defined(_ARCH_PWR9)
436 #elif defined(__VSX__) || defined(_ARCH_PWR8)
462 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src)+off;
464 CRYPTOPP_UNUSED(addr);
466 #if defined(_ARCH_PWR9)
468 #elif defined(__VSX__) || defined(_ARCH_PWR8)
475 #if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
496 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src);
498 CRYPTOPP_UNUSED(addr);
500 #if defined(_ARCH_PWR9)
502 #elif defined(__VSX__) || defined(_ARCH_PWR8)
530 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src)+off;
532 CRYPTOPP_UNUSED(addr);
534 #if defined(_ARCH_PWR9)
536 #elif defined(__VSX__) || defined(_ARCH_PWR8)
544 #endif // VSX or ARCH_PWR8
562 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src);
564 CRYPTOPP_UNUSED(addr);
566 #if defined(_ARCH_PWR9)
590 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src)+off;
592 CRYPTOPP_UNUSED(addr);
594 #if defined(_ARCH_PWR9)
617 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src);
619 CRYPTOPP_UNUSED(addr);
621 #if defined(_ARCH_PWR9)
623 #elif defined(__VSX__) || defined(_ARCH_PWR8)
647 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src)+off;
649 CRYPTOPP_UNUSED(addr);
651 #if defined(_ARCH_PWR9)
653 #elif defined(__VSX__) || defined(_ARCH_PWR8)
660 #if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
678 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src);
680 CRYPTOPP_UNUSED(addr);
682 #if defined(_ARCH_PWR9)
684 #elif defined(__VSX__) || defined(_ARCH_PWR8)
709 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src)+off;
711 CRYPTOPP_UNUSED(addr);
713 #if defined(_ARCH_PWR9)
715 #elif defined(__VSX__) || defined(_ARCH_PWR8)
744 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src);
746 CRYPTOPP_UNUSED(addr);
748 #if defined(_ARCH_PWR9)
751 #elif defined(CRYPTOPP_BIG_ENDIAN)
778 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(src)+off;
780 CRYPTOPP_UNUSED(addr);
782 #if defined(_ARCH_PWR9)
785 #elif defined(CRYPTOPP_BIG_ENDIAN)
816 uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest);
856 uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest)+off;
897 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest);
899 CRYPTOPP_UNUSED(addr);
901 #if defined(_ARCH_PWR9)
924 inline void VecStore(
const T data,
int off,
byte dest[16])
930 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest)+off;
932 CRYPTOPP_UNUSED(addr);
934 #if defined(_ARCH_PWR9)
962 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest);
964 CRYPTOPP_UNUSED(addr);
966 #if defined(_ARCH_PWR9)
968 #elif defined(__VSX__) || defined(_ARCH_PWR8)
991 inline void VecStore(
const T data,
int off, word32 dest[4])
997 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest)+off;
999 CRYPTOPP_UNUSED(addr);
1001 #if defined(_ARCH_PWR9)
1003 #elif defined(__VSX__) || defined(_ARCH_PWR8)
1032 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest);
1034 CRYPTOPP_UNUSED(addr);
1036 #if defined(_ARCH_PWR9)
1038 #elif defined(__VSX__) || defined(_ARCH_PWR8)
1063 inline void VecStore(
const T data,
int off, word64 dest[2])
1069 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest)+off;
1071 CRYPTOPP_UNUSED(addr);
1073 #if defined(_ARCH_PWR9)
1075 #elif defined(__VSX__) || defined(_ARCH_PWR8)
1102 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest);
1104 CRYPTOPP_UNUSED(addr);
1106 #if defined(_ARCH_PWR9)
1133 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest)+off;
1135 CRYPTOPP_UNUSED(addr);
1137 #if defined(_ARCH_PWR9)
1164 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest);
1166 CRYPTOPP_UNUSED(addr);
1168 #if defined(_ARCH_PWR9)
1170 #elif defined(__VSX__) || defined(_ARCH_PWR8)
1198 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest)+off;
1200 CRYPTOPP_UNUSED(addr);
1202 #if defined(_ARCH_PWR9)
1204 #elif defined(__VSX__) || defined(_ARCH_PWR8)
1233 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest);
1235 CRYPTOPP_UNUSED(addr);
1237 #if defined(_ARCH_PWR9)
1239 #elif defined(CRYPTOPP_BIG_ENDIAN)
1269 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest)+off;
1271 CRYPTOPP_UNUSED(addr);
1273 #if defined(_ARCH_PWR9)
1275 #elif defined(CRYPTOPP_BIG_ENDIAN)
1304 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest);
1306 CRYPTOPP_UNUSED(addr);
1308 #if defined(_ARCH_PWR9)
1310 #elif defined(CRYPTOPP_BIG_ENDIAN)
1340 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(dest)+off;
1342 CRYPTOPP_UNUSED(addr);
1344 #if defined(_ARCH_PWR9)
1346 #elif defined(CRYPTOPP_BIG_ENDIAN)
1371 template <
class T1,
class T2>
1372 inline T1
VecAnd(
const T1 vec1,
const T2 vec2)
1374 return (T1)vec_and(vec1, (T1)vec2);
1390 template <
class T1,
class T2>
1391 inline T1
VecOr(
const T1 vec1,
const T2 vec2)
1393 return (T1)vec_or(vec1, (T1)vec2);
1409 template <
class T1,
class T2>
1410 inline T1
VecXor(
const T1 vec1,
const T2 vec2)
1412 return (T1)vec_xor(vec1, (T1)vec2);
1433 template <
class T1,
class T2>
1434 inline T1
VecAdd(
const T1 vec1,
const T2 vec2)
1436 return (T1)vec_add(vec1, (T1)vec2);
1451 template <
class T1,
class T2>
1452 inline T1
VecSub(
const T1 vec1,
const T2 vec2)
1454 return (T1)vec_sub(vec1, (T1)vec2);
1473 template <
class T1,
class T2>
1476 return (T1)vec_perm(vec, vec, (
uint8x16_p)mask);
1491 template <
class T1,
class T2>
1492 inline T1
VecPermute(
const T1 vec1,
const T1 vec2,
const T2 mask)
1494 return (T1)vec_perm(vec1, (T1)vec2, (
uint8x16_p)mask);
1523 template <
unsigned int C,
class T>
1539 #if defined(CRYPTOPP_BIG_ENDIAN)
1543 enum { R=(16-C)&0xf };
1570 template <
unsigned int C,
class T>
1586 #if defined(CRYPTOPP_BIG_ENDIAN)
1587 enum { R=(16-C)&0xf };
1609 template <
unsigned int C,
class T>
1612 #if defined(CRYPTOPP_BIG_ENDIAN)
1616 enum { R=(16-C)&0xf };
1634 template <
unsigned int C,
class T>
1637 #if defined(CRYPTOPP_BIG_ENDIAN)
1638 enum { R=(16-C)&0xf };
1655 template<
unsigned int C>
1659 return vec_rl(vec, m);
1671 template<
unsigned int C>
1674 const uint32x4_p m = {32-C, 32-C, 32-C, 32-C};
1675 return vec_rl(vec, m);
1687 template<
unsigned int C>
1691 return vec_sl(vec, m);
1703 template<
unsigned int C>
1707 return vec_sr(vec, m);
1711 #if defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
1724 template<
unsigned int C>
1728 return vec_rl(vec, m);
1742 template<
unsigned int C>
1746 return vec_sl(vec, m);
1760 template<
unsigned int C>
1764 return vec_rl(vec, m);
1778 template<
unsigned int C>
1782 return vec_sr(vec, m);
1803 return vec_mergel(vec1, vec2);
1817 return vec_mergeh(vec1, vec2);
1830 #if defined(_ARCH_PWR4) && defined(__GNUC__)
1831 return vec_splats(val);
1835 const word32 x[4] = {val};
1836 return vec_splat(
VecLoad(x),0);
1847 template <
unsigned int N>
1850 return vec_splat(val, N);
1853 #if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
1863 return vec_splats((
unsigned long long)val);
1873 template <
unsigned int N>
1876 #if defined(__VSX__) || defined(_ARCH_PWR8)
1877 return vec_splat(val, N);
1882 const uint8x16_p m = {0,1,2,3, 4,5,6,7, 0,1,2,3, 4,5,6,7};
1883 return vec_perm(val, val, m);
1887 const uint8x16_p m = {8,9,10,11, 12,13,14,15, 8,9,10,11, 12,13,14,15};
1888 return vec_perm(val, val, m);
1908 #if defined(CRYPTOPP_BIG_ENDIAN) && (defined(__VSX__) || defined(_ARCH_PWR8))
1912 return VecShiftRightOctet<8>(VecShiftLeftOctet<8>(val));
1930 #if defined(CRYPTOPP_BIG_ENDIAN) && (defined(__VSX__) || defined(_ARCH_PWR8))
1934 return VecShiftRightOctet<8>(val);
1967 template <
class T1,
class T2>
1984 template <
class T1,
class T2>
2010 #if defined(_ARCH_PWR8) && !defined(CRYPTOPP_DEBUG)
2016 #if defined(CRYPTOPP_BIG_ENDIAN)
2026 cy = vec_and(mask, cy);
2027 cy = vec_sld (cy, zero, 4);
2028 return vec_add(res, cy);
2032 #if defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
2048 #if defined(CRYPTOPP_DEBUG)
2072 #if defined(_ARCH_PWR8) && !defined(CRYPTOPP_DEBUG)
2079 #if defined(CRYPTOPP_BIG_ENDIAN)
2091 bw = vec_andc(mask, bw);
2092 bw = vec_sld (bw, zero, 4);
2093 return vec_sub(res, bw);
2097 #if defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
2112 #if defined(CRYPTOPP_DEBUG)
2134 template<
unsigned int C>
2137 #if defined(_ARCH_PWR8) && !defined(CRYPTOPP_DEBUG)
2142 enum {S64=C&63, S32=C&31, BR=(S64>=32)};
2151 const uint8x16_p m = {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15};
2156 const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11};
2161 const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11};
2166 const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11};
2170 return vec_or(t1, t2);
2186 #if (CRYPTOPP_BIG_ENDIAN)
2187 const uint8x16_p m = { 1,2,3,4, 5,6,7,0, 9,10,11,12, 13,14,15,8 };
2190 const uint8x16_p m = { 7,0,1,2, 3,4,5,6, 15,8,9,10, 11,12,13,14 };
2195 #if defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
2205 template<
unsigned int C>
2209 const uint64x2_p res = VecRotateLeft<C>(vec);
2211 #if defined(CRYPTOPP_DEBUG)
2232 template<
unsigned int C>
2235 #if defined(_ARCH_PWR8) && !defined(CRYPTOPP_DEBUG)
2240 enum {S64=C&63, S32=C&31, BR=(S64>=32)};
2249 const uint8x16_p m = {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15};
2254 const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11};
2259 const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11};
2264 const uint8x16_p m = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11};
2268 return vec_or(t1, t2);
2285 #if (CRYPTOPP_BIG_ENDIAN)
2286 const uint8x16_p m = { 7,0,1,2, 3,4,5,6, 15,8,9,10, 11,12,13,14 };
2289 const uint8x16_p m = { 1,2,3,4, 5,6,7,0, 9,10,11,12, 13,14,15,8 };
2294 #if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
2304 template<
unsigned int C>
2308 const uint64x2_p res = VecRotateRight<C>(vec);
2310 #if defined(CRYPTOPP_DEBUG)
2335 template <
class T1,
class T2>
2338 return (T1)vec_and(vec1, (T1)vec2);
2354 template <
class T1,
class T2>
2357 return (T1)vec_or(vec1, (T1)vec2);
2373 template <
class T1,
class T2>
2376 return (T1)vec_xor(vec1, (T1)vec2);
2387 #if defined(_ARCH_PWR8)
2389 return (
uint32x4_p)vec_splats((
unsigned long long)val);
2391 const word64 x[2] = {val,val};
2403 template <
unsigned int N>
2406 #if defined(__VSX__) || defined(_ARCH_PWR8)
2412 const uint8x16_p m = {0,1,2,3, 4,5,6,7, 0,1,2,3, 4,5,6,7};
2417 const uint8x16_p m = {8,9,10,11, 12,13,14,15, 8,9,10,11, 12,13,14,15};
2423 #if defined(__VSX__) || defined(_ARCH_PWR8) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
2429 template <
unsigned int N>
2432 return vec_splat(val, N);
2442 #if (defined(_ARCH_PWR8) && defined(__CRYPTO__)) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
2463 #if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__))
2464 return __vpmsumw (a, b);
2465 #elif defined(__clang__)
2466 return __builtin_altivec_crypto_vpmsumw (a, b);
2468 return __builtin_crypto_vpmsumw (a, b);
2488 #if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__))
2489 return __vpmsumd (a, b);
2490 #elif defined(__clang__)
2491 return __builtin_altivec_crypto_vpmsumd (a, b);
2493 return __builtin_crypto_vpmsumd (a, b);
2512 #if defined(CRYPTOPP_BIG_ENDIAN)
2534 #if defined(CRYPTOPP_BIG_ENDIAN)
2556 #if defined(CRYPTOPP_BIG_ENDIAN)
2578 #if defined(CRYPTOPP_BIG_ENDIAN)
2601 template <
class T1,
class T2>
2604 #if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__))
2606 #elif defined(__clang__)
2608 #elif defined(__GNUC__)
2626 template <
class T1,
class T2>
2629 #if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__))
2631 #elif defined(__clang__)
2633 #elif defined(__GNUC__)
2651 template <
class T1,
class T2>
2654 #if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__))
2656 #elif defined(__clang__)
2658 #elif defined(__GNUC__)
2676 template <
class T1,
class T2>
2679 #if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__))
2681 #elif defined(__clang__)
2683 #elif defined(__GNUC__)
2706 template <
int func,
int fmask,
class T>
2709 #if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__))
2710 return (T)__vshasigmaw((
uint32x4_p)data, func, fmask);
2711 #elif defined(__clang__)
2712 return (T)__builtin_altivec_crypto_vshasigmaw((
uint32x4_p)data, func, fmask);
2713 #elif defined(__GNUC__)
2714 return (T)__builtin_crypto_vshasigmaw((
uint32x4_p)data, func, fmask);
2731 template <
int func,
int fmask,
class T>
2734 #if defined(__ibmxl__) || (defined(_AIX) && defined(__xlC__))
2735 return (T)__vshasigmad((
uint64x2_p)data, func, fmask);
2736 #elif defined(__clang__)
2737 return (T)__builtin_altivec_crypto_vshasigmad((
uint64x2_p)data, func, fmask);
2738 #elif defined(__GNUC__)
2739 return (T)__builtin_crypto_vshasigmad((
uint64x2_p)data, func, fmask);
2747 #endif // __CRYPTO__
2753 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
2754 # pragma GCC diagnostic pop
2757 #endif // CRYPTOPP_PPC_CRYPTO_H