aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-12-10 11:25:22 -0500
committerJack Lloyd <[email protected]>2017-12-10 11:51:38 -0500
commit5e69b9a4e4b703247189e46652a41b901de06dae (patch)
tree688ffe88f81613facbb0d4d44f4b21909290eba8
parent6284d7507130288fa8cc7ece096ecac56a81f8cd (diff)
Enable using NEON on Clang
Clang doesn't like the way SIMD shifts were implemented, I guess it fails to inline the constant. Make it a template parameter instead.
-rw-r--r--src/build-data/cc/clang.txt3
-rw-r--r--src/lib/block/serpent/serpent_simd/serpent_simd.cpp8
-rw-r--r--src/lib/utils/simd/simd_32.h29
-rw-r--r--src/tests/test_simd.cpp4
4 files changed, 24 insertions, 20 deletions
diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt
index ec4da317d..44dd654f3 100644
--- a/src/build-data/cc/clang.txt
+++ b/src/build-data/cc/clang.txt
@@ -46,6 +46,9 @@ rdrand -> "-mrdrnd"
rdseed -> "-mrdseed"
sha -> "-msha"
altivec -> "-maltivec"
+
+arm32:neon -> "-mfpu=neon"
+arm64:neon -> ""
</isa_flags>
<mach_opt>
diff --git a/src/lib/block/serpent/serpent_simd/serpent_simd.cpp b/src/lib/block/serpent/serpent_simd/serpent_simd.cpp
index ad4871cf6..8148e321f 100644
--- a/src/lib/block/serpent/serpent_simd/serpent_simd.cpp
+++ b/src/lib/block/serpent/serpent_simd/serpent_simd.cpp
@@ -27,11 +27,11 @@ namespace Botan {
B0 = B0.rotl<13>(); \
B2 = B2.rotl<3>(); \
B1 ^= B0 ^ B2; \
- B3 ^= B2 ^ (B0 << 3); \
+ B3 ^= B2 ^ B0.shl<3>(); \
B1 = B1.rotl<1>(); \
B3 = B3.rotl<7>(); \
B0 ^= B1 ^ B3; \
- B2 ^= B3 ^ (B1 << 7); \
+ B2 ^= B3 ^ B1.shl<7>(); \
B0 = B0.rotl<5>(); \
B2 = B2.rotl<22>(); \
} while(0)
@@ -40,11 +40,11 @@ namespace Botan {
do { \
B2 = B2.rotr<22>(); \
B0 = B0.rotr<5>(); \
- B2 ^= B3 ^ (B1 << 7); \
+ B2 ^= B3 ^ B1.shl<7>(); \
B0 ^= B1 ^ B3; \
B3 = B3.rotr<7>(); \
B1 = B1.rotr<1>(); \
- B3 ^= B2 ^ (B0 << 3); \
+ B3 ^= B2 ^ B0.shl<3>(); \
B1 ^= B0 ^ B2; \
B2 = B2.rotr<3>(); \
B0 = B0.rotr<13>(); \
diff --git a/src/lib/utils/simd/simd_32.h b/src/lib/utils/simd/simd_32.h
index aca7a8e9a..d9a41c800 100644
--- a/src/lib/utils/simd/simd_32.h
+++ b/src/lib/utils/simd/simd_32.h
@@ -508,37 +508,38 @@ class SIMD_4x32 final
#endif
}
- SIMD_4x32 operator<<(size_t shift) const
+
+ template<int SHIFT> SIMD_4x32 shl() const
{
#if defined(BOTAN_SIMD_USE_SSE2)
- return SIMD_4x32(_mm_slli_epi32(m_sse, static_cast<int>(shift)));
+ return SIMD_4x32(_mm_slli_epi32(m_sse, SHIFT));
#elif defined(BOTAN_SIMD_USE_ALTIVEC)
- const unsigned int s = static_cast<unsigned int>(shift);
+ const unsigned int s = static_cast<unsigned int>(SHIFT);
return SIMD_4x32(vec_sl(m_vmx, (__vector unsigned int){s, s, s, s}));
#elif defined(BOTAN_SIMD_USE_NEON)
- return SIMD_4x32(vshlq_n_u32(m_neon, static_cast<int>(shift)));
+ return SIMD_4x32(vshlq_n_u32(m_neon, SHIFT));
#else
- return SIMD_4x32(m_scalar[0] << shift,
- m_scalar[1] << shift,
- m_scalar[2] << shift,
- m_scalar[3] << shift);
+ return SIMD_4x32(m_scalar[0] << SHIFT,
+ m_scalar[1] << SHIFT,
+ m_scalar[2] << SHIFT,
+ m_scalar[3] << SHIFT);
#endif
}
- SIMD_4x32 operator>>(size_t shift) const
+ template<int SHIFT> SIMD_4x32 shr() const
{
#if defined(BOTAN_SIMD_USE_SSE2)
- return SIMD_4x32(_mm_srli_epi32(m_sse, static_cast<int>(shift)));
+ return SIMD_4x32(_mm_srli_epi32(m_sse, SHIFT));
#elif defined(BOTAN_SIMD_USE_ALTIVEC)
- const unsigned int s = static_cast<unsigned int>(shift);
+ const unsigned int s = static_cast<unsigned int>(SHIFT);
return SIMD_4x32(vec_sr(m_vmx, (__vector unsigned int){s, s, s, s}));
#elif defined(BOTAN_SIMD_USE_NEON)
- return SIMD_4x32(vshrq_n_u32(m_neon, static_cast<int>(shift)));
+ return SIMD_4x32(vshrq_n_u32(m_neon, SHIFT));
#else
- return SIMD_4x32(m_scalar[0] >> shift, m_scalar[1] >> shift,
- m_scalar[2] >> shift, m_scalar[3] >> shift);
+ return SIMD_4x32(m_scalar[0] >> SHIFT, m_scalar[1] >> SHIFT,
+ m_scalar[2] >> SHIFT, m_scalar[3] >> SHIFT);
#endif
}
diff --git a/src/tests/test_simd.cpp b/src/tests/test_simd.cpp
index 1f192c6b6..60c46fc67 100644
--- a/src/tests/test_simd.cpp
+++ b/src/tests/test_simd.cpp
@@ -82,10 +82,10 @@ class SIMD_32_Tests final : public Test
blender = ~blender;
test_eq(result, "~", blender, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
- blender = blender >> 23;
+ blender = blender.shr<23>();
test_eq(result, ">>", blender, 0x1FF, 0x1FF, 0x1FF, 0x1FF);
- blender = blender << 27;
+ blender = blender.shl<27>();
test_eq(result, "<<", blender, 0xF8000000, 0xF8000000, 0xF8000000, 0xF8000000);
blender = ~blender;