Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-28 09:11:40

0001 /***************************************************************************
0002  * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and         *
0003  * Martin Renou                                                             *
0004  * Copyright (c) QuantStack                                                 *
0005  * Copyright (c) Serge Guelton                                              *
0006  *                                                                          *
0007  * Distributed under the terms of the BSD 3-Clause License.                 *
0008  *                                                                          *
0009  * The full license is in the file LICENSE, distributed with this software. *
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      * @ingroup architectures
0026      *
0027      * NEON instructions for arm32
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