File indexing completed on 2025-08-28 09:11:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef XSIMD_SVE_REGISTER_HPP
0014 #define XSIMD_SVE_REGISTER_HPP
0015
0016 #include "xsimd_generic_arch.hpp"
0017 #include "xsimd_register.hpp"
0018
0019 #if XSIMD_WITH_SVE
0020 #include <arm_sve.h>
0021 #endif
0022
0023 namespace xsimd
0024 {
0025 namespace detail
0026 {
0027
0028
0029
0030
0031
0032 template <size_t Width>
0033 struct sve : xsimd::generic
0034 {
0035 static constexpr bool supported() noexcept { return Width == XSIMD_SVE_BITS; }
0036 static constexpr bool available() noexcept { return true; }
0037 static constexpr bool requires_alignment() noexcept { return true; }
0038 static constexpr std::size_t alignment() noexcept { return 16; }
0039 static constexpr char const* name() noexcept { return "arm64+sve"; }
0040 };
0041 }
0042
0043 #if XSIMD_WITH_SVE
0044
0045 using sve = detail::sve<__ARM_FEATURE_SVE_BITS>;
0046
0047 namespace types
0048 {
0049 namespace detail
0050 {
0051
0052 #define SVE_TO_FIXED_SIZE(ty) ty __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)))
0053 using sve_int8_t = SVE_TO_FIXED_SIZE(svint8_t);
0054 using sve_uint8_t = SVE_TO_FIXED_SIZE(svuint8_t);
0055 using sve_int16_t = SVE_TO_FIXED_SIZE(svint16_t);
0056 using sve_uint16_t = SVE_TO_FIXED_SIZE(svuint16_t);
0057 using sve_int32_t = SVE_TO_FIXED_SIZE(svint32_t);
0058 using sve_uint32_t = SVE_TO_FIXED_SIZE(svuint32_t);
0059 using sve_int64_t = SVE_TO_FIXED_SIZE(svint64_t);
0060 using sve_uint64_t = SVE_TO_FIXED_SIZE(svuint64_t);
0061 using sve_float32_t = SVE_TO_FIXED_SIZE(svfloat32_t);
0062 using sve_float64_t = SVE_TO_FIXED_SIZE(svfloat64_t);
0063 using sve_bool_t = SVE_TO_FIXED_SIZE(svbool_t);
0064 #undef SVE_TO_FIXED_SIZE
0065
0066 template <size_t S>
0067 struct sve_vector_type_impl;
0068
0069 template <>
0070 struct sve_vector_type_impl<8>
0071 {
0072 using signed_type = sve_int8_t;
0073 using unsigned_type = sve_uint8_t;
0074 using floating_point_type = void;
0075 };
0076
0077 template <>
0078 struct sve_vector_type_impl<16>
0079 {
0080 using signed_type = sve_int16_t;
0081 using unsigned_type = sve_uint16_t;
0082 using floating_point_type = void;
0083 };
0084
0085 template <>
0086 struct sve_vector_type_impl<32>
0087 {
0088 using signed_type = sve_int32_t;
0089 using unsigned_type = sve_uint32_t;
0090 using floating_point_type = sve_float32_t;
0091 };
0092
0093 template <>
0094 struct sve_vector_type_impl<64>
0095 {
0096 using signed_type = sve_int64_t;
0097 using unsigned_type = sve_uint64_t;
0098 using floating_point_type = sve_float64_t;
0099 };
0100
0101 template <class T>
0102 using signed_int_sve_vector_type = typename sve_vector_type_impl<8 * sizeof(T)>::signed_type;
0103
0104 template <class T>
0105 using unsigned_int_sve_vector_type = typename sve_vector_type_impl<8 * sizeof(T)>::unsigned_type;
0106
0107 template <class T>
0108 using floating_point_sve_vector_type = typename sve_vector_type_impl<8 * sizeof(T)>::floating_point_type;
0109
0110 template <class T>
0111 using signed_int_or_floating_point_sve_vector_type = typename std::conditional<std::is_floating_point<T>::value,
0112 floating_point_sve_vector_type<T>,
0113 signed_int_sve_vector_type<T>>::type;
0114
0115 template <class T>
0116 using sve_vector_type = typename std::conditional<std::is_signed<T>::value,
0117 signed_int_or_floating_point_sve_vector_type<T>,
0118 unsigned_int_sve_vector_type<T>>::type;
0119 }
0120
0121 XSIMD_DECLARE_SIMD_REGISTER(signed char, sve, detail::sve_vector_type<signed char>);
0122 XSIMD_DECLARE_SIMD_REGISTER(unsigned char, sve, detail::sve_vector_type<unsigned char>);
0123 XSIMD_DECLARE_SIMD_REGISTER(char, sve, detail::sve_vector_type<char>);
0124 XSIMD_DECLARE_SIMD_REGISTER(short, sve, detail::sve_vector_type<short>);
0125 XSIMD_DECLARE_SIMD_REGISTER(unsigned short, sve, detail::sve_vector_type<unsigned short>);
0126 XSIMD_DECLARE_SIMD_REGISTER(int, sve, detail::sve_vector_type<int>);
0127 XSIMD_DECLARE_SIMD_REGISTER(unsigned int, sve, detail::sve_vector_type<unsigned int>);
0128 XSIMD_DECLARE_SIMD_REGISTER(long int, sve, detail::sve_vector_type<long int>);
0129 XSIMD_DECLARE_SIMD_REGISTER(unsigned long int, sve, detail::sve_vector_type<unsigned long int>);
0130 XSIMD_DECLARE_SIMD_REGISTER(long long int, sve, detail::sve_vector_type<long long int>);
0131 XSIMD_DECLARE_SIMD_REGISTER(unsigned long long int, sve, detail::sve_vector_type<unsigned long long int>);
0132 XSIMD_DECLARE_SIMD_REGISTER(float, sve, detail::sve_vector_type<float>);
0133 XSIMD_DECLARE_SIMD_REGISTER(double, sve, detail::sve_vector_type<double>);
0134
0135 namespace detail
0136 {
0137 struct sve_bool_simd_register
0138 {
0139 using register_type = sve_bool_t;
0140 register_type data;
0141 operator register_type() const noexcept { return data; }
0142 };
0143 }
0144
0145 template <class T>
0146 struct get_bool_simd_register<T, sve>
0147 {
0148 using type = detail::sve_bool_simd_register;
0149 };
0150 }
0151 #else
0152 using sve = detail::sve<0xFFFFFFFF>;
0153 #endif
0154 }
0155
0156 #endif