vec_ext.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP_EXPERIMENTAL___SIMD_VEC_EXT_H
  10. #define _LIBCPP_EXPERIMENTAL___SIMD_VEC_EXT_H
  11. #include <__bit/bit_ceil.h>
  12. #include <__utility/forward.h>
  13. #include <cstddef>
  14. #include <experimental/__simd/internal_declaration.h>
  15. #include <experimental/__simd/utility.h>
  16. #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
  17. _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
  18. inline namespace parallelism_v2 {
  19. namespace simd_abi {
  20. template <int _Np>
  21. struct __vec_ext {
  22. static constexpr size_t __simd_size = _Np;
  23. };
  24. } // namespace simd_abi
  25. template <class _Tp, int _Np>
  26. struct __simd_storage<_Tp, simd_abi::__vec_ext<_Np>> {
  27. _Tp __data __attribute__((__vector_size__(std::__bit_ceil((sizeof(_Tp) * _Np)))));
  28. _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __idx) const noexcept {
  29. _LIBCPP_ASSERT_UNCATEGORIZED(__idx >= 0 && __idx < _Np, "Index is out of bounds");
  30. return __data[__idx];
  31. }
  32. _LIBCPP_HIDE_FROM_ABI void __set(size_t __idx, _Tp __v) noexcept {
  33. _LIBCPP_ASSERT_UNCATEGORIZED(__idx >= 0 && __idx < _Np, "Index is out of bounds");
  34. __data[__idx] = __v;
  35. }
  36. };
  37. template <class _Tp, int _Np>
  38. struct __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>
  39. : __simd_storage<decltype(experimental::__choose_mask_type<_Tp>()), simd_abi::__vec_ext<_Np>> {};
  40. template <class _Tp, int _Np>
  41. struct __simd_operations<_Tp, simd_abi::__vec_ext<_Np>> {
  42. using _SimdStorage = __simd_storage<_Tp, simd_abi::__vec_ext<_Np>>;
  43. using _MaskStorage = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>;
  44. static _LIBCPP_HIDE_FROM_ABI _SimdStorage __broadcast(_Tp __v) noexcept {
  45. _SimdStorage __result;
  46. for (int __i = 0; __i < _Np; ++__i) {
  47. __result.__set(__i, __v);
  48. }
  49. return __result;
  50. }
  51. template <class _Generator, size_t... _Is>
  52. static _LIBCPP_HIDE_FROM_ABI _SimdStorage __generate_init(_Generator&& __g, std::index_sequence<_Is...>) {
  53. return _SimdStorage{{__g(std::integral_constant<size_t, _Is>())...}};
  54. }
  55. template <class _Generator>
  56. static _LIBCPP_HIDE_FROM_ABI _SimdStorage __generate(_Generator&& __g) noexcept {
  57. return __generate_init(std::forward<_Generator>(__g), std::make_index_sequence<_Np>());
  58. }
  59. };
  60. template <class _Tp, int _Np>
  61. struct __mask_operations<_Tp, simd_abi::__vec_ext<_Np>> {
  62. using _MaskStorage = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>;
  63. static _LIBCPP_HIDE_FROM_ABI _MaskStorage __broadcast(bool __v) noexcept {
  64. _MaskStorage __result;
  65. auto __all_bits_v = experimental::__set_all_bits<_Tp>(__v);
  66. for (int __i = 0; __i < _Np; ++__i) {
  67. __result.__set(__i, __all_bits_v);
  68. }
  69. return __result;
  70. }
  71. };
  72. } // namespace parallelism_v2
  73. _LIBCPP_END_NAMESPACE_EXPERIMENTAL
  74. #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
  75. #endif // _LIBCPP_EXPERIMENTAL___SIMD_VEC_EXT_H