File indexing completed on 2025-08-28 09:11:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef XSIMD_NEON_REGISTER_HPP
0013 #define XSIMD_NEON_REGISTER_HPP
0014
0015 #include "xsimd_generic_arch.hpp"
0016 #include "xsimd_register.hpp"
0017
0018 #if XSIMD_WITH_NEON
0019 #include <arm_neon.h>
0020 #endif
0021
0022 namespace xsimd
0023 {
0024
0025
0026
0027
0028
0029 struct neon : generic
0030 {
0031 static constexpr bool supported() noexcept { return XSIMD_WITH_NEON; }
0032 static constexpr bool available() noexcept { return true; }
0033 static constexpr bool requires_alignment() noexcept { return true; }
0034 static constexpr std::size_t alignment() noexcept { return 16; }
0035 static constexpr char const* name() noexcept { return "arm32+neon"; }
0036 };
0037
0038 #if XSIMD_WITH_NEON
0039 namespace types
0040 {
0041 namespace detail
0042 {
0043 template <size_t S>
0044 struct neon_vector_type_impl;
0045
0046 template <>
0047 struct neon_vector_type_impl<8>
0048 {
0049 using signed_type = int8x16_t;
0050 using unsigned_type = uint8x16_t;
0051 };
0052
0053 template <>
0054 struct neon_vector_type_impl<16>
0055 {
0056 using signed_type = int16x8_t;
0057 using unsigned_type = uint16x8_t;
0058 };
0059
0060 template <>
0061 struct neon_vector_type_impl<32>
0062 {
0063 using signed_type = int32x4_t;
0064 using unsigned_type = uint32x4_t;
0065 };
0066
0067 template <>
0068 struct neon_vector_type_impl<64>
0069 {
0070 using signed_type = int64x2_t;
0071 using unsigned_type = uint64x2_t;
0072 };
0073
0074 template <class T>
0075 using signed_neon_vector_type = typename neon_vector_type_impl<8 * sizeof(T)>::signed_type;
0076
0077 template <class T>
0078 using unsigned_neon_vector_type = typename neon_vector_type_impl<8 * sizeof(T)>::unsigned_type;
0079
0080 template <class T>
0081 using neon_vector_type = typename std::conditional<std::is_signed<T>::value,
0082 signed_neon_vector_type<T>,
0083 unsigned_neon_vector_type<T>>::type;
0084
0085 using char_neon_vector_type = typename std::conditional<std::is_signed<char>::value,
0086 signed_neon_vector_type<char>,
0087 unsigned_neon_vector_type<char>>::type;
0088 }
0089
0090 XSIMD_DECLARE_SIMD_REGISTER(signed char, neon, detail::neon_vector_type<signed char>);
0091 XSIMD_DECLARE_SIMD_REGISTER(unsigned char, neon, detail::neon_vector_type<unsigned char>);
0092 XSIMD_DECLARE_SIMD_REGISTER(char, neon, detail::char_neon_vector_type);
0093 XSIMD_DECLARE_SIMD_REGISTER(short, neon, detail::neon_vector_type<short>);
0094 XSIMD_DECLARE_SIMD_REGISTER(unsigned short, neon, detail::neon_vector_type<unsigned short>);
0095 XSIMD_DECLARE_SIMD_REGISTER(int, neon, detail::neon_vector_type<int>);
0096 XSIMD_DECLARE_SIMD_REGISTER(unsigned int, neon, detail::neon_vector_type<unsigned int>);
0097 XSIMD_DECLARE_SIMD_REGISTER(long int, neon, detail::neon_vector_type<long int>);
0098 XSIMD_DECLARE_SIMD_REGISTER(unsigned long int, neon, detail::neon_vector_type<unsigned long int>);
0099 XSIMD_DECLARE_SIMD_REGISTER(long long int, neon, detail::neon_vector_type<long long int>);
0100 XSIMD_DECLARE_SIMD_REGISTER(unsigned long long int, neon, detail::neon_vector_type<unsigned long long int>);
0101 XSIMD_DECLARE_SIMD_REGISTER(float, neon, float32x4_t);
0102 XSIMD_DECLARE_INVALID_SIMD_REGISTER(double, neon);
0103
0104 namespace detail
0105 {
0106 template <size_t S>
0107 struct get_unsigned_type;
0108
0109 template <>
0110 struct get_unsigned_type<1>
0111 {
0112 using type = uint8_t;
0113 };
0114
0115 template <>
0116 struct get_unsigned_type<2>
0117 {
0118 using type = uint16_t;
0119 };
0120
0121 template <>
0122 struct get_unsigned_type<4>
0123 {
0124 using type = uint32_t;
0125 };
0126
0127 template <>
0128 struct get_unsigned_type<8>
0129 {
0130 using type = uint64_t;
0131 };
0132
0133 template <size_t S>
0134 using get_unsigned_type_t = typename get_unsigned_type<S>::type;
0135
0136 template <class T, class A>
0137 struct neon_bool_simd_register
0138 {
0139 using type = simd_register<get_unsigned_type_t<sizeof(T)>, A>;
0140 };
0141 }
0142
0143 template <class T>
0144 struct get_bool_simd_register<T, neon>
0145 : detail::neon_bool_simd_register<T, neon>
0146 {
0147 };
0148
0149 }
0150 #endif
0151
0152 }
0153
0154 #endif