aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/utils')
-rw-r--r--src/lib/utils/cpuid/cpuid.h15
-rw-r--r--src/lib/utils/simd/simd_32.h42
2 files changed, 49 insertions, 8 deletions
diff --git a/src/lib/utils/cpuid/cpuid.h b/src/lib/utils/cpuid/cpuid.h
index bb6af55a2..d998d5364 100644
--- a/src/lib/utils/cpuid/cpuid.h
+++ b/src/lib/utils/cpuid/cpuid.h
@@ -315,6 +315,21 @@ class BOTAN_PUBLIC_API(2,1) CPUID final
{ return has_cpuid_bit(CPUID_RDSEED_BIT); }
#endif
+ /**
+ * Check if the processor supports byte-level vector permutes
+ * (SSSE3, NEON, Altivec)
+ */
+ static bool has_vperm()
+ {
+#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
+ return has_ssse3();
+#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
+ return has_neon();
+#else
+ return false;
+#endif
+ }
+
/*
* Clear a CPUID bit
* Call CPUID::initialize to reset
diff --git a/src/lib/utils/simd/simd_32.h b/src/lib/utils/simd/simd_32.h
index 7934e0c93..de02e84f1 100644
--- a/src/lib/utils/simd/simd_32.h
+++ b/src/lib/utils/simd/simd_32.h
@@ -169,7 +169,15 @@ class SIMD_4x32 final
#elif defined(BOTAN_SIMD_USE_NEON)
SIMD_4x32 l(vld1q_u32(static_cast<const uint32_t*>(in)));
+
+#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+ return l.bswap();
+#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+ return l;
+#else
return CPUID::is_big_endian() ? l.bswap() : l;
+#endif
+
#else
SIMD_4x32 out;
Botan::load_le(out.m_simd.val, static_cast<const uint8_t*>(in), 4);
@@ -183,11 +191,9 @@ class SIMD_4x32 final
static SIMD_4x32 load_be(const void* in)
{
#if defined(BOTAN_SIMD_USE_SSE2)
-
return load_le(in).bswap();
#elif defined(BOTAN_SIMD_USE_ALTIVEC)
-
uint32_t R[4];
Botan::load_be(R, static_cast<const uint8_t*>(in), 4);
return SIMD_4x32(R);
@@ -195,7 +201,14 @@ class SIMD_4x32 final
#elif defined(BOTAN_SIMD_USE_NEON)
SIMD_4x32 l(vld1q_u32(static_cast<const uint32_t*>(in)));
+
+#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+ return l.bswap();
+#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+ return l;
+#else
return CPUID::is_little_endian() ? l.bswap() : l;
+#endif
#else
SIMD_4x32 out;
@@ -216,7 +229,7 @@ class SIMD_4x32 final
{
#if defined(BOTAN_SIMD_USE_SSE2)
- _mm_storeu_si128(reinterpret_cast<__m128i*>(out), m_simd);
+ _mm_storeu_si128(reinterpret_cast<__m128i*>(out), raw());
#elif defined(BOTAN_SIMD_USE_ALTIVEC)
@@ -224,19 +237,26 @@ class SIMD_4x32 final
__vector unsigned int V;
uint32_t R[4];
} vec;
- vec.V = m_simd;
+ vec.V = raw();
Botan::store_le(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]);
#elif defined(BOTAN_SIMD_USE_NEON)
- if(CPUID::is_big_endian())
+#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+ vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
+#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+ vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
+#else
+ if(CPUID::is_little_endian())
{
- bswap().store_le(out);
+ vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
}
else
{
- vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
+ vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
}
+#endif
+
#else
Botan::store_le(out, m_simd.val[0], m_simd.val[1], m_simd.val[2], m_simd.val[3]);
#endif
@@ -262,14 +282,20 @@ class SIMD_4x32 final
#elif defined(BOTAN_SIMD_USE_NEON)
+#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+ vst1q_u8(out, vreinterpretq_u8_u32(m_simd);
+#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+ vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
+#else
if(CPUID::is_little_endian())
{
- bswap().store_le(out);
+ vst1q_u8(out, vreinterpretq_u8_u32(bswap().m_simd));
}
else
{
vst1q_u8(out, vreinterpretq_u8_u32(m_simd));
}
+#endif
#else
Botan::store_be(out, m_simd.val[0], m_simd.val[1], m_simd.val[2], m_simd.val[3]);