timshen created this revision. timshen added a reviewer: mclow.lists. Herald added subscribers: christof, kristof.beyls, sanjoy. Herald added a reviewer: EricWF.
Currently x86, PowerPC, and ARM are supported. https://reviews.llvm.org/D44656 Files: libcxx/include/experimental/__config libcxx/include/experimental/simd libcxx/test/std/experimental/simd/simd.abi/raw.pass.cpp
Index: libcxx/test/std/experimental/simd/simd.abi/raw.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/experimental/simd/simd.abi/raw.pass.cpp @@ -0,0 +1,122 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/simd> +// +// [simd.abi] + +#include <experimental/simd> +#include <cstdint> + +using namespace std::experimental::parallelism_v2; + +template <class SimdType, class ExpectedRawType> +void compile_raw() { + static_assert(std::is_same<decltype(std::declval<SimdType>().__raw()), + ExpectedRawType>::value, + ""); + (void)SimdType(ExpectedRawType()); + (void)static_cast<ExpectedRawType>(SimdType()); +} + +int main() { +#if defined(__AVX__) + compile_raw<native_simd<int8_t>, __m256i>(); + compile_raw<native_simd<int16_t>, __m256i>(); + compile_raw<native_simd<int32_t>, __m256i>(); + compile_raw<native_simd<int64_t>, __m256i>(); + compile_raw<native_simd<uint8_t>, __m256i>(); + compile_raw<native_simd<uint16_t>, __m256i>(); + compile_raw<native_simd<uint32_t>, __m256i>(); + compile_raw<native_simd<uint64_t>, __m256i>(); + compile_raw<native_simd<float>, __m256>(); + compile_raw<native_simd<double>, __m256d>(); +#elif defined(__SSE2__) + compile_raw<native_simd<int8_t>, __m128i>(); + compile_raw<native_simd<int16_t>, __m128i>(); + compile_raw<native_simd<int32_t>, __m128i>(); + compile_raw<native_simd<int64_t>, __m128i>(); + compile_raw<native_simd<uint8_t>, __m128i>(); + compile_raw<native_simd<uint16_t>, __m128i>(); + compile_raw<native_simd<uint32_t>, __m128i>(); + compile_raw<native_simd<uint64_t>, __m128i>(); + compile_raw<native_simd<float>, __m128>(); + compile_raw<native_simd<double>, __m128d>(); +#elif defined(__ALTIVEC__) || defined(__VSX__) + compile_raw<native_simd<char>, __vector char>(); + compile_raw<native_simd<char16_t>, __vector char16_t>(); + compile_raw<native_simd<char32_t>, __vector char32_t>(); + compile_raw<native_simd<wchar_t>, __vector wchar_t>(); + compile_raw<native_simd<signed char>, __vector signed char>(); + compile_raw<native_simd<signed short>, __vector signed short>(); + compile_raw<native_simd<signed int>, __vector signed int>(); + compile_raw<native_simd<signed long>, __vector signed long>(); + compile_raw<native_simd<signed long long>, __vector signed long long>(); + compile_raw<native_simd<unsigned char>, __vector unsigned char>(); + compile_raw<native_simd<unsigned short>, __vector unsigned short>(); + compile_raw<native_simd<unsigned int>, __vector unsigned int>(); + compile_raw<native_simd<unsigned long>, __vector unsigned long>(); + compile_raw<native_simd<unsigned long long>, __vector unsigned long long>(); + compile_raw<native_simd<float>, __vector float>(); + compile_raw<native_simd<double>, __vector double>(); +#elif defined(__ARM_NEON) + compile_raw<native_simd<int8_t>, int8x16_t>(); + compile_raw<native_simd<int16_t>, int16x8_t>(); + compile_raw<native_simd<int32_t>, int32x4_t>(); + compile_raw<native_simd<int64_t>, int64x2_t>(); + compile_raw<native_simd<uint8_t>, uint8x16_t>(); + compile_raw<native_simd<uint16_t>, uint16x8_t>(); + compile_raw<native_simd<uint32_t>, uint32x4_t>(); + compile_raw<native_simd<uint64_t>, uint64x2_t>(); + compile_raw<native_simd<float>, float32x4_t>(); + compile_raw<native_simd<double>, float64x2_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<int8_t>())[0])>::type, + int8x8_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<int16_t>())[0])>::type, + int16x4_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<int32_t>())[0])>::type, + int32x2_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<int64_t>())[0])>::type, + int64x1_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<uint8_t>())[0])>::type, + uint8x8_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<uint16_t>())[0])>::type, + uint16x4_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<uint32_t>())[0])>::type, + uint32x2_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<uint64_t>())[0])>::type, + uint64x1_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<float>())[0])>::type, + float32x2_t>(); + + compile_raw<typename std::remove_reference<decltype( + split_by<2>(native_simd<double>())[0])>::type, + float64x1_t>(); +#endif +} Index: libcxx/include/experimental/simd =================================================================== --- libcxx/include/experimental/simd +++ libcxx/include/experimental/simd @@ -596,6 +596,17 @@ #include <functional> #include <limits> +#if defined(_LIBCPP_MICROARCH_SSE2) +#include <emmintrin.h> +#if defined(_LIBCPP_MICROARCH_AVX) +#include <immintrin.h> +#endif +#elif defined(_LIBCPP_MICROARCH_ALTIVEC) +#include <altivec.h> +#elif defined(_LIBCPP_MICROARCH_NEON) +#include <arm_neon.h> +#endif + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif @@ -680,59 +691,91 @@ _TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT))); \ } -#define _SPECIALIZE_VEC_EXT_32(_TYPE) \ - _SPECIALIZE_VEC_EXT(_TYPE, 1); \ - _SPECIALIZE_VEC_EXT(_TYPE, 2); \ - _SPECIALIZE_VEC_EXT(_TYPE, 3); \ - _SPECIALIZE_VEC_EXT(_TYPE, 4); \ - _SPECIALIZE_VEC_EXT(_TYPE, 5); \ - _SPECIALIZE_VEC_EXT(_TYPE, 6); \ - _SPECIALIZE_VEC_EXT(_TYPE, 7); \ - _SPECIALIZE_VEC_EXT(_TYPE, 8); \ - _SPECIALIZE_VEC_EXT(_TYPE, 9); \ - _SPECIALIZE_VEC_EXT(_TYPE, 10); \ - _SPECIALIZE_VEC_EXT(_TYPE, 11); \ - _SPECIALIZE_VEC_EXT(_TYPE, 12); \ - _SPECIALIZE_VEC_EXT(_TYPE, 13); \ - _SPECIALIZE_VEC_EXT(_TYPE, 14); \ - _SPECIALIZE_VEC_EXT(_TYPE, 15); \ - _SPECIALIZE_VEC_EXT(_TYPE, 16); \ - _SPECIALIZE_VEC_EXT(_TYPE, 17); \ - _SPECIALIZE_VEC_EXT(_TYPE, 18); \ - _SPECIALIZE_VEC_EXT(_TYPE, 19); \ - _SPECIALIZE_VEC_EXT(_TYPE, 20); \ - _SPECIALIZE_VEC_EXT(_TYPE, 21); \ - _SPECIALIZE_VEC_EXT(_TYPE, 22); \ - _SPECIALIZE_VEC_EXT(_TYPE, 23); \ - _SPECIALIZE_VEC_EXT(_TYPE, 24); \ - _SPECIALIZE_VEC_EXT(_TYPE, 25); \ - _SPECIALIZE_VEC_EXT(_TYPE, 26); \ - _SPECIALIZE_VEC_EXT(_TYPE, 27); \ - _SPECIALIZE_VEC_EXT(_TYPE, 28); \ - _SPECIALIZE_VEC_EXT(_TYPE, 29); \ - _SPECIALIZE_VEC_EXT(_TYPE, 30); \ - _SPECIALIZE_VEC_EXT(_TYPE, 31); \ - _SPECIALIZE_VEC_EXT(_TYPE, 32); - -_SPECIALIZE_VEC_EXT_32(char); -_SPECIALIZE_VEC_EXT_32(char16_t); -_SPECIALIZE_VEC_EXT_32(char32_t); -_SPECIALIZE_VEC_EXT_32(wchar_t); -_SPECIALIZE_VEC_EXT_32(signed char); -_SPECIALIZE_VEC_EXT_32(signed short); -_SPECIALIZE_VEC_EXT_32(signed int); -_SPECIALIZE_VEC_EXT_32(signed long); -_SPECIALIZE_VEC_EXT_32(signed long long); -_SPECIALIZE_VEC_EXT_32(unsigned char); -_SPECIALIZE_VEC_EXT_32(unsigned short); -_SPECIALIZE_VEC_EXT_32(unsigned int); -_SPECIALIZE_VEC_EXT_32(unsigned long); -_SPECIALIZE_VEC_EXT_32(unsigned long long); -_SPECIALIZE_VEC_EXT_32(float); -_SPECIALIZE_VEC_EXT_32(double); -_SPECIALIZE_VEC_EXT_32(long double); - -#undef _SPECIALIZE_VEC_EXT_32 +#define _SPECIALIZE_VEC_EXT_FOR_SIZES(_TYPE) \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x01); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x02); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x03); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x04); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x05); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x06); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x07); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x08); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x09); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x0a); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x0b); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x0c); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x0d); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x0e); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x0f); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x10); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x11); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x12); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x13); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x14); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x15); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x16); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x17); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x18); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x19); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x1a); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x1b); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x1c); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x1d); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x1e); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x1f); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x20); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x21); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x22); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x23); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x24); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x25); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x26); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x27); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x28); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x29); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x2a); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x2b); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x2c); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x2d); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x2e); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x2f); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x30); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x31); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x32); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x33); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x34); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x35); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x36); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x37); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x38); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x39); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x3a); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x3b); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x3c); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x3d); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x3e); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x3f); \ + _SPECIALIZE_VEC_EXT(_TYPE, 0x40); + +_SPECIALIZE_VEC_EXT_FOR_SIZES(char); +_SPECIALIZE_VEC_EXT_FOR_SIZES(char16_t); +_SPECIALIZE_VEC_EXT_FOR_SIZES(char32_t); +_SPECIALIZE_VEC_EXT_FOR_SIZES(wchar_t); +_SPECIALIZE_VEC_EXT_FOR_SIZES(signed char); +_SPECIALIZE_VEC_EXT_FOR_SIZES(signed short); +_SPECIALIZE_VEC_EXT_FOR_SIZES(signed int); +_SPECIALIZE_VEC_EXT_FOR_SIZES(signed long); +_SPECIALIZE_VEC_EXT_FOR_SIZES(signed long long); +_SPECIALIZE_VEC_EXT_FOR_SIZES(unsigned char); +_SPECIALIZE_VEC_EXT_FOR_SIZES(unsigned short); +_SPECIALIZE_VEC_EXT_FOR_SIZES(unsigned int); +_SPECIALIZE_VEC_EXT_FOR_SIZES(unsigned long); +_SPECIALIZE_VEC_EXT_FOR_SIZES(unsigned long long); +_SPECIALIZE_VEC_EXT_FOR_SIZES(float); +_SPECIALIZE_VEC_EXT_FOR_SIZES(double); +_SPECIALIZE_VEC_EXT_FOR_SIZES(long double); + +#undef _SPECIALIZE_VEC_EXT_FOR_SIZES #undef _SPECIALIZE_VEC_EXT #endif @@ -761,6 +804,114 @@ #endif // _LIBCPP_HAS_NO_VECTOR_EXTENSION +template <class _Tp, size_t __bytes> +struct __native_type_traits {}; + +#if defined(_LIBCPP_MICROARCH_SSE2) + +template <class _Tp> +struct __native_type_traits<_Tp, 16> { + static_assert(16 % sizeof(_Tp) == 0, ""); + using type = __m128i; +}; + +template <> +struct __native_type_traits<float, 16> { + using type = __m128; +}; + +template <> +struct __native_type_traits<double, 16> { + using type = __m128d; +}; + +#if defined(_LIBCPP_MICROARCH_AVX) + +template <class _Tp> +struct __native_type_traits<_Tp, 32> { + static_assert(32 % sizeof(_Tp) == 0, ""); + using type = __m256i; +}; + +template <> +struct __native_type_traits<float, 32> { + using type = __m256; +}; + +template <> +struct __native_type_traits<double, 32> { + using type = __m256d; +}; +#endif // _LIBCPP_MICROARCH_AVX +#elif defined(_LIBCPP_MICROARCH_ALTIVEC) + +#define _SPECIALIZE_ALTIVEC_TRAITS(_TYPE) \ + template <> \ + struct __native_type_traits<_TYPE, 16> { \ + using type = __vector _TYPE; \ + } + +_SPECIALIZE_ALTIVEC_TRAITS(char); +_SPECIALIZE_ALTIVEC_TRAITS(char16_t); +_SPECIALIZE_ALTIVEC_TRAITS(char32_t); +_SPECIALIZE_ALTIVEC_TRAITS(wchar_t); +_SPECIALIZE_ALTIVEC_TRAITS(signed char); +_SPECIALIZE_ALTIVEC_TRAITS(signed short); +_SPECIALIZE_ALTIVEC_TRAITS(signed int); +_SPECIALIZE_ALTIVEC_TRAITS(signed long); +_SPECIALIZE_ALTIVEC_TRAITS(signed long long); +_SPECIALIZE_ALTIVEC_TRAITS(unsigned char); +_SPECIALIZE_ALTIVEC_TRAITS(unsigned short); +_SPECIALIZE_ALTIVEC_TRAITS(unsigned int); +_SPECIALIZE_ALTIVEC_TRAITS(unsigned long); +_SPECIALIZE_ALTIVEC_TRAITS(unsigned long long); +_SPECIALIZE_ALTIVEC_TRAITS(float); +_SPECIALIZE_ALTIVEC_TRAITS(double); + +#undef _SPECIALIZE_ALTIVEC_TRAITS +#elif defined(_LIBCPP_MICROARCH_NEON) +#define _SPECIALIZE_NEON_TRAITS(_TYPE, _NUM_BYTES, _UNDERLYING_TYPE) \ + template <> \ + struct __native_type_traits<_TYPE, _NUM_BYTES> { \ + using type = _UNDERLYING_TYPE; \ + } + +_SPECIALIZE_NEON_TRAITS(char, 16, int8x16_t); +_SPECIALIZE_NEON_TRAITS(char16_t, 16, int16x8_t); +_SPECIALIZE_NEON_TRAITS(char32_t, 16, int32x4_t); +_SPECIALIZE_NEON_TRAITS(wchar_t, 16, int16x8_t); +_SPECIALIZE_NEON_TRAITS(signed char, 16, int8x16_t); +_SPECIALIZE_NEON_TRAITS(signed short, 16, int16x8_t); +_SPECIALIZE_NEON_TRAITS(signed int, 16, int32x4_t); +_SPECIALIZE_NEON_TRAITS(signed long, 16, int64x2_t); +_SPECIALIZE_NEON_TRAITS(signed long long, 16, int64x2_t); +_SPECIALIZE_NEON_TRAITS(unsigned char, 16, uint8x16_t); +_SPECIALIZE_NEON_TRAITS(unsigned short, 16, uint16x8_t); +_SPECIALIZE_NEON_TRAITS(unsigned int, 16, uint32x4_t); +_SPECIALIZE_NEON_TRAITS(unsigned long, 16, uint64x2_t); +_SPECIALIZE_NEON_TRAITS(unsigned long long, 16, uint64x2_t); +_SPECIALIZE_NEON_TRAITS(float, 16, float32x4_t); +_SPECIALIZE_NEON_TRAITS(double, 16, float64x2_t); +_SPECIALIZE_NEON_TRAITS(char, 8, int8x8_t); +_SPECIALIZE_NEON_TRAITS(char16_t, 8, int16x4_t); +_SPECIALIZE_NEON_TRAITS(char32_t, 8, int32x2_t); +_SPECIALIZE_NEON_TRAITS(wchar_t, 8, int16x4_t); +_SPECIALIZE_NEON_TRAITS(signed char, 8, int8x8_t); +_SPECIALIZE_NEON_TRAITS(signed short, 8, int16x4_t); +_SPECIALIZE_NEON_TRAITS(signed int, 8, int32x2_t); +_SPECIALIZE_NEON_TRAITS(signed long, 8, int64x1_t); +_SPECIALIZE_NEON_TRAITS(signed long long, 8, int64x1_t); +_SPECIALIZE_NEON_TRAITS(unsigned char, 8, uint8x8_t); +_SPECIALIZE_NEON_TRAITS(unsigned short, 8, uint16x4_t); +_SPECIALIZE_NEON_TRAITS(unsigned int, 8, uint32x2_t); +_SPECIALIZE_NEON_TRAITS(unsigned long, 8, uint64x1_t); +_SPECIALIZE_NEON_TRAITS(unsigned long long, 8, uint64x1_t); +_SPECIALIZE_NEON_TRAITS(float, 8, float32x2_t); +_SPECIALIZE_NEON_TRAITS(double, 8, float64x1_t); + +#undef _SPECIALIZE_VEC_EXT +#endif // _LIBCPP_MICROARCH_NEON + template <class _Vp, class _Tp, class _Abi> class __simd_reference { static_assert(std::is_same<_Vp, _Tp>::value || @@ -964,7 +1115,7 @@ #if _LIBCPP_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> -_LIBCPP_INLINE_VAR constexpr size_t max_fixed_size = 32; +_LIBCPP_INLINE_VAR constexpr size_t max_fixed_size = 64; #endif template <class _Tp, size_t _Np> @@ -982,7 +1133,13 @@ using compatible = __compatible<_Tp, 16 / sizeof(_Tp)>; template <class _Tp> -using native = __native<_Tp, _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(_Tp)>; +using native = __native<_Tp, +#if defined(_LIBCPP_MICROARCH_AVX) + 32 +#else + 16 +#endif + / sizeof(_Tp)>; _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD @@ -1807,6 +1964,25 @@ std::make_index_sequence<size()>()); } + template <class _Up = _Tp> + simd(typename __native_type_traits<_Up, sizeof(_Up) * size()>::type __r) { + __s_.__assign(typename __simd_storage<_Tp, _Abi>::__raw_type(__r)); + } + + template <class _Up = _Tp> + typename __native_type_traits<_Up, sizeof(_Up) * size()>::type __raw() const { + return typename __native_type_traits<_Tp, sizeof(_Tp) * size()>::type( + __s_.__raw()); + } + + template <class _Up = _Tp, class _RetType, + class = typename std::enable_if<std::is_same< + typename __native_type_traits<_Up, sizeof(_Up) * size()>::type, + _RetType>::value>::type> + operator _RetType() const { + return __raw(); + } + // load constructor template < class _Up, class _Flags, @@ -2130,6 +2306,26 @@ } } + template <class _Up = _Tp> + simd_mask(typename __native_type_traits<__element_type, + sizeof(_Up) * size()>::type __r) + : __s_(__r) {} + + template <class _Up = _Tp> + typename __native_type_traits<__element_type, sizeof(_Up) * size()>::type + __raw() const { + return __s_.__raw(); + } + + template <class _Up = _Tp, class _RetType, + class = typename std::enable_if< + std::is_same<typename __native_type_traits< + __element_type, sizeof(_Up) * size()>::type, + _RetType>::value>::type> + operator _RetType() const { + return __raw(); + } + // loads [simd.mask.copy] template <class _Flags> typename std::enable_if<is_simd_flag_type<_Flags>::value>::type Index: libcxx/include/experimental/__config =================================================================== --- libcxx/include/experimental/__config +++ libcxx/include/experimental/__config @@ -66,11 +66,15 @@ #define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI \ } _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD -// TODO: support more targets +#if defined(__SSE2__) +#define _LIBCPP_MICROARCH_SSE2 #if defined(__AVX__) -#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 32 -#else -#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 16 +#define _LIBCPP_MICROARCH_AVX +#endif +#elif defined(__ALTIVEC__) || defined(__VSX__) +#define _LIBCPP_MICROARCH_ALTIVEC +#elif defined(__ARM_NEON) +#define _LIBCPP_MICROARCH_NEON #endif #endif
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits