Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:37:14

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_CPU_FEATURES_RISCV_HPP
0013 #define XSIMD_CPU_FEATURES_RISCV_HPP
0014 
0015 #include "./xsimd_config.hpp"
0016 #include "./xsimd_getauxval.hpp"
0017 
0018 #include <cstddef>
0019 #include <cstdint>
0020 
0021 #if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
0022 // HWCAP_XXX masks to use on getauxval results.
0023 // Header does not exists on all architectures and masks are architecture
0024 // specific.
0025 #include <asm/hwcap.h>
0026 #endif // XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
0027 
0028 namespace xsimd
0029 {
0030     namespace detail
0031     {
0032         using riscv_reg64_t = std::uint64_t;
0033 
0034         /**
0035          * Return the RVV vector length in bytes.
0036          *
0037          * This does not require to be compiles with SVE, which should not
0038          * be done in a dynamic dispatch jump function.
0039          *
0040          * Safety: It is the user responsibility to first make sure that RVV is
0041          * available.
0042          */
0043         inline riscv_reg64_t riscv_csrr_unsafe();
0044     }
0045 
0046     class riscv_cpu_features : private linux_hwcap_backend_default
0047     {
0048     public:
0049         inline bool rvv() const noexcept;
0050         inline std::size_t rvv_size_bytes() const noexcept;
0051     };
0052 
0053     /********************
0054      *  Implementation  *
0055      ********************/
0056 
0057     namespace detail
0058     {
0059 #if XSIMD_TARGET_RISCV && (defined(__GNUC__) || defined(__clang__))
0060         __attribute__((target("arch=+v"))) inline riscv_reg64_t riscv_csrr_unsafe()
0061         {
0062             riscv_reg64_t vlenb;
0063             __asm__ volatile("csrr %0, vlenb" : "=r"(vlenb));
0064             return vlenb;
0065         }
0066 #else
0067         inline riscv_reg64_t riscv_csrr_unsafe() { return 0; }
0068 #endif
0069     }
0070 
0071     inline bool riscv_cpu_features::rvv() const noexcept
0072     {
0073 #if XSIMD_TARGET_RISCV && XSIMD_HAVE_LINUX_GETAUXVAL
0074 #ifdef HWCAP_V
0075         return hwcap().has_feature(HWCAP_V);
0076 #else
0077         // Possibly missing on older Linux distributions
0078         return hwcap().has_feature(1 << ('V' - 'A'));
0079 #endif
0080 #else
0081         return false;
0082 #endif
0083     }
0084 
0085     inline std::size_t riscv_cpu_features::rvv_size_bytes() const noexcept
0086     {
0087         if (rvv())
0088         {
0089             return detail::riscv_csrr_unsafe();
0090         }
0091         return 0;
0092     }
0093 }
0094 
0095 #endif