1403c667bSTim Shen// -*- C++ -*- 2403c667bSTim Shen//===------------------------------- simd ---------------------------------===// 3403c667bSTim Shen// 4403c667bSTim Shen// The LLVM Compiler Infrastructure 5403c667bSTim Shen// 6403c667bSTim Shen// This file is dual licensed under the MIT and the University of Illinois Open 7403c667bSTim Shen// Source Licenses. See LICENSE.TXT for details. 8403c667bSTim Shen// 9403c667bSTim Shen//===----------------------------------------------------------------------===// 10403c667bSTim Shen#ifndef _LIBCPP_EXPERIMENTAL_SIMD 11403c667bSTim Shen#define _LIBCPP_EXPERIMENTAL_SIMD 12403c667bSTim Shen 13403c667bSTim Shen/* 14403c667bSTim Shen experimental/simd synopsis 15403c667bSTim Shen 16403c667bSTim Shennamespace std::experimental { 17403c667bSTim Shen 18403c667bSTim Sheninline namespace parallelism_v2 { 19403c667bSTim Shen 20403c667bSTim Shennamespace simd_abi { 21403c667bSTim Shen 22403c667bSTim Shenstruct scalar {}; 23403c667bSTim Shentemplate <int N> struct fixed_size {}; 24403c667bSTim Shentemplate <typename T> inline constexpr int max_fixed_size = implementation-defined; 25403c667bSTim Shentemplate <typename T> using compatible = implementation-defined; 26403c667bSTim Shentemplate <typename T> using native = implementation-defined; 27403c667bSTim Shen 28403c667bSTim Shen} // simd_abi 29403c667bSTim Shen 30403c667bSTim Shenstruct element_aligned_tag {}; 31403c667bSTim Shenstruct vector_aligned_tag {}; 32403c667bSTim Shentemplate <size_t> struct overaligned_tag {}; 33403c667bSTim Sheninline constexpr element_aligned_tag element_aligned{}; 34403c667bSTim Sheninline constexpr vector_aligned_tag vector_aligned{}; 35403c667bSTim Shentemplate <size_t N> inline constexpr overaligned_tag<N> overaligned{}; 36403c667bSTim Shen 37403c667bSTim Shen// traits [simd.traits] 38403c667bSTim Shentemplate <class T> struct is_abi_tag; 39403c667bSTim Shentemplate <class T> inline constexpr bool is_abi_tag_v = is_abi_tag<T>::value; 40403c667bSTim Shen 41403c667bSTim Shentemplate <class T> struct is_simd; 42403c667bSTim Shentemplate <class T> inline constexpr bool is_simd_v = is_simd<T>::value; 43403c667bSTim Shen 44403c667bSTim Shentemplate <class T> struct is_simd_mask; 45403c667bSTim Shentemplate <class T> inline constexpr bool is_simd_mask_v = is_simd_mask<T>::value; 46403c667bSTim Shen 47403c667bSTim Shentemplate <class T> struct is_simd_flag_type; 48403c667bSTim Shentemplate <class T> inline constexpr bool is_simd_flag_type_v = is_simd_flag_type<T>::value; 49403c667bSTim Shen 50403c667bSTim Shentemplate <class T, size_t N> struct abi_for_size { using type = see below; }; 51403c667bSTim Shentemplate <class T, size_t N> using abi_for_size_t = typename abi_for_size<T, N>::type; 52403c667bSTim Shen 53403c667bSTim Shentemplate <class T, class Abi = simd_abi::compatible<T>> struct simd_size; 54403c667bSTim Shentemplate <class T, class Abi = simd_abi::compatible<T>> 55403c667bSTim Sheninline constexpr size_t simd_size_v = simd_size<T, Abi>::value; 56403c667bSTim Shen 57403c667bSTim Shentemplate <class T, class U = typename T::value_type> struct memory_alignment; 58403c667bSTim Shentemplate <class T, class U = typename T::value_type> 59403c667bSTim Sheninline constexpr size_t memory_alignment_v = memory_alignment<T, U>::value; 60403c667bSTim Shen 61403c667bSTim Shen// class template simd [simd.class] 62403c667bSTim Shentemplate <class T, class Abi = simd_abi::compatible<T>> class simd; 63403c667bSTim Shentemplate <class T> using native_simd = simd<T, simd_abi::native<T>>; 64403c667bSTim Shentemplate <class T, int N> using fixed_size_simd = simd<T, simd_abi::fixed_size<N>>; 65403c667bSTim Shen 66403c667bSTim Shen// class template simd_mask [simd.mask.class] 67403c667bSTim Shentemplate <class T, class Abi = simd_abi::compatible<T>> class simd_mask; 68403c667bSTim Shentemplate <class T> using native_simd_mask = simd_mask<T, simd_abi::native<T>>; 69403c667bSTim Shentemplate <class T, int N> using fixed_size_simd_mask = simd_mask<T, simd_abi::fixed_size<N>>; 70403c667bSTim Shen 71403c667bSTim Shen// casts [simd.casts] 72403c667bSTim Shentemplate <class T, class U, class Abi> see below simd_cast(const simd<U, Abi>&); 73403c667bSTim Shentemplate <class T, class U, class Abi> see below static_simd_cast(const simd<U, Abi>&); 74403c667bSTim Shen 75403c667bSTim Shentemplate <class T, class Abi> 76403c667bSTim Shenfixed_size_simd<T, simd_size_v<T, Abi>> to_fixed_size(const simd<T, Abi>&) noexcept; 77403c667bSTim Shentemplate <class T, class Abi> 78403c667bSTim Shenfixed_size_simd_mask<T, simd_size_v<T, Abi>> to_fixed_size(const simd_mask<T, Abi>&) noexcept; 79403c667bSTim Shentemplate <class T, size_t N> native_simd<T> to_native(const fixed_size_simd<T, N>&) noexcept; 80403c667bSTim Shentemplate <class T, size_t N> 81403c667bSTim Shennative_simd_mask<T> to_native(const fixed_size_simd_mask<T, N>> &) noexcept; 82403c667bSTim Shentemplate <class T, size_t N> simd<T> to_compatible(const fixed_size_simd<T, N>&) noexcept; 83403c667bSTim Shentemplate <class T, size_t N> simd_mask<T> to_compatible(const fixed_size_simd_mask<T, N>&) noexcept; 84403c667bSTim Shen 85403c667bSTim Shentemplate <size_t... Sizes, class T, class Abi> 86403c667bSTim Shentuple<simd<T, abi_for_size_t<Sizes>>...> split(const simd<T, Abi>&); 87403c667bSTim Shentemplate <size_t... Sizes, class T, class Abi> 88403c667bSTim Shentuple<simd_mask<T, abi_for_size_t<Sizes>>...> split(const simd_mask<T, Abi>&); 89403c667bSTim Shentemplate <class V, class Abi> 90403c667bSTim Shenarray<V, simd_size_v<typename V::value_type, Abi> / V::size()> split( 91403c667bSTim Shenconst simd<typename V::value_type, Abi>&); 92403c667bSTim Shentemplate <class V, class Abi> 93403c667bSTim Shenarray<V, simd_size_v<typename V::value_type, Abi> / V::size()> split( 94403c667bSTim Shenconst simd_mask<typename V::value_type, Abi>&); 95403c667bSTim Shen 96403c667bSTim Shentemplate <class T, class... Abis> 97403c667bSTim Shensimd<T, abi_for_size_t<T, (simd_size_v<T, Abis> + ...)>> concat(const simd<T, Abis>&...); 98403c667bSTim Shentemplate <class T, class... Abis> 99403c667bSTim Shensimd_mask<T, abi_for_size_t<T, (simd_size_v<T, Abis> + ...)>> concat(const simd_mask<T, Abis>&...); 100403c667bSTim Shen 101403c667bSTim Shen// reductions [simd.mask.reductions] 102403c667bSTim Shentemplate <class T, class Abi> bool all_of(const simd_mask<T, Abi>&) noexcept; 103403c667bSTim Shentemplate <class T, class Abi> bool any_of(const simd_mask<T, Abi>&) noexcept; 104403c667bSTim Shentemplate <class T, class Abi> bool none_of(const simd_mask<T, Abi>&) noexcept; 105403c667bSTim Shentemplate <class T, class Abi> bool some_of(const simd_mask<T, Abi>&) noexcept; 106403c667bSTim Shentemplate <class T, class Abi> int popcount(const simd_mask<T, Abi>&) noexcept; 107403c667bSTim Shentemplate <class T, class Abi> int find_first_set(const simd_mask<T, Abi>&); 108403c667bSTim Shentemplate <class T, class Abi> int find_last_set(const simd_mask<T, Abi>&); 109403c667bSTim Shen 110403c667bSTim Shenbool all_of(see below) noexcept; 111403c667bSTim Shenbool any_of(see below) noexcept; 112403c667bSTim Shenbool none_of(see below) noexcept; 113403c667bSTim Shenbool some_of(see below) noexcept; 114403c667bSTim Shenint popcount(see below) noexcept; 115403c667bSTim Shenint find_first_set(see below) noexcept; 116403c667bSTim Shenint find_last_set(see below) noexcept; 117403c667bSTim Shen 118403c667bSTim Shen// masked assignment [simd.whereexpr] 119403c667bSTim Shentemplate <class M, class T> class const_where_expression; 120403c667bSTim Shentemplate <class M, class T> class where_expression; 121403c667bSTim Shen 122403c667bSTim Shen// masked assignment [simd.mask.where] 123403c667bSTim Shentemplate <class T> struct nodeduce { using type = T; }; // exposition only 124403c667bSTim Shen 125403c667bSTim Shentemplate <class T> using nodeduce_t = typename nodeduce<T>::type; // exposition only 126403c667bSTim Shen 127403c667bSTim Shentemplate <class T, class Abi> 128403c667bSTim Shenwhere_expression<simd_mask<T, Abi>, simd<T, Abi>> 129403c667bSTim Shenwhere(const typename simd<T, Abi>::mask_type&, simd<T, Abi>&) noexcept; 130403c667bSTim Shen 131403c667bSTim Shentemplate <class T, class Abi> 132403c667bSTim Shenconst_where_expression<simd_mask<T, Abi>, const simd<T, Abi>> 133403c667bSTim Shenwhere(const typename simd<T, Abi>::mask_type&, const simd<T, Abi>&) noexcept; 134403c667bSTim Shen 135403c667bSTim Shentemplate <class T, class Abi> 136403c667bSTim Shenwhere_expression<simd_mask<T, Abi>, simd_mask<T, Abi>> 137403c667bSTim Shenwhere(const nodeduce_t<simd_mask<T, Abi>>&, simd_mask<T, Abi>&) noexcept; 138403c667bSTim Shen 139403c667bSTim Shentemplate <class T, class Abi> 140403c667bSTim Shenconst_where_expression<simd_mask<T, Abi>, const simd_mask<T, Abi>> 141403c667bSTim Shenwhere(const nodeduce_t<simd_mask<T, Abi>>&, const simd_mask<T, Abi>&) noexcept; 142403c667bSTim Shen 143403c667bSTim Shentemplate <class T> where_expression<bool, T> where(see below k, T& d) noexcept; 144403c667bSTim Shen 145403c667bSTim Shentemplate <class T> 146403c667bSTim Shenconst_where_expression<bool, const T> where(see below k, const T& d) noexcept; 147403c667bSTim Shen 148403c667bSTim Shen// reductions [simd.reductions] 149403c667bSTim Shentemplate <class T, class Abi, class BinaryOperation = std::plus<>> 150403c667bSTim ShenT reduce(const simd<T, Abi>&, BinaryOperation = BinaryOperation()); 151403c667bSTim Shen 152403c667bSTim Shentemplate <class M, class V, class BinaryOperation> 153403c667bSTim Shentypename V::value_type reduce(const const_where_expression<M, V>& x, 154403c667bSTim Shentypename V::value_type neutral_element, BinaryOperation binary_op); 155403c667bSTim Shen 156403c667bSTim Shentemplate <class M, class V> 157403c667bSTim Shentypename V::value_type reduce(const const_where_expression<M, V>& x, plus<> binary_op = plus<>()); 158403c667bSTim Shen 159403c667bSTim Shentemplate <class M, class V> 160403c667bSTim Shentypename V::value_type reduce(const const_where_expression<M, V>& x, multiplies<> binary_op); 161403c667bSTim Shen 162403c667bSTim Shentemplate <class M, class V> 163403c667bSTim Shentypename V::value_type reduce(const const_where_expression<M, V>& x, bit_and<> binary_op); 164403c667bSTim Shen 165403c667bSTim Shentemplate <class M, class V> 166403c667bSTim Shentypename V::value_type reduce(const const_where_expression<M, V>& x, bit_or<> binary_op); 167403c667bSTim Shen 168403c667bSTim Shentemplate <class M, class V> 169403c667bSTim Shentypename V::value_type reduce(const const_where_expression<M, V>& x, bit_xor<> binary_op); 170403c667bSTim Shen 171403c667bSTim Shentemplate <class T, class Abi> T hmin(const simd<T, Abi>&); 172403c667bSTim Shentemplate <class M, class V> T hmin(const const_where_expression<M, V>&); 173403c667bSTim Shentemplate <class T, class Abi> T hmax(const simd<T, Abi>&); 174403c667bSTim Shentemplate <class M, class V> T hmax(const const_where_expression<M, V>&); 175403c667bSTim Shen 176403c667bSTim Shen// algorithms [simd.alg] 177403c667bSTim Shentemplate <class T, class Abi> simd<T, Abi> min(const simd<T, Abi>&, const simd<T, Abi>&) noexcept; 178403c667bSTim Shen 179403c667bSTim Shentemplate <class T, class Abi> simd<T, Abi> max(const simd<T, Abi>&, const simd<T, Abi>&) noexcept; 180403c667bSTim Shen 181403c667bSTim Shentemplate <class T, class Abi> 182403c667bSTim Shenstd::pair<simd<T, Abi>, simd<T, Abi>> minmax(const simd<T, Abi>&, const simd<T, Abi>&) noexcept; 183403c667bSTim Shen 184403c667bSTim Shentemplate <class T, class Abi> 185403c667bSTim Shensimd<T, Abi> clamp(const simd<T, Abi>& v, const simd<T, Abi>& lo, const simd<T, Abi>& hi); 186403c667bSTim Shen 187403c667bSTim Shen// [simd.whereexpr] 188403c667bSTim Shentemplate <class M, class T> 189403c667bSTim Shenclass const_where_expression { 190403c667bSTim Shen const M& mask; // exposition only 191403c667bSTim Shen T& data; // exposition only 192403c667bSTim Shenpublic: 193403c667bSTim Shen const_where_expression(const const_where_expression&) = delete; 194403c667bSTim Shen const_where_expression& operator=(const const_where_expression&) = delete; 195403c667bSTim Shen remove_const_t<T> operator-() const &&; 196403c667bSTim Shen template <class U, class Flags> void copy_to(U* mem, Flags f) const &&; 197403c667bSTim Shen}; 198403c667bSTim Shen 199403c667bSTim Shentemplate <class M, class T> 200403c667bSTim Shenclass where_expression : public const_where_expression<M, T> { 201403c667bSTim Shenpublic: 202403c667bSTim Shen where_expression(const where_expression&) = delete; 203403c667bSTim Shen where_expression& operator=(const where_expression&) = delete; 204403c667bSTim Shen template <class U> void operator=(U&& x); 205403c667bSTim Shen template <class U> void operator+=(U&& x); 206403c667bSTim Shen template <class U> void operator-=(U&& x); 207403c667bSTim Shen template <class U> void operator*=(U&& x); 208403c667bSTim Shen template <class U> void operator/=(U&& x); 209403c667bSTim Shen template <class U> void operator%=(U&& x); 210403c667bSTim Shen template <class U> void operator&=(U&& x); 211403c667bSTim Shen template <class U> void operator|=(U&& x); 212403c667bSTim Shen template <class U> void operator^=(U&& x); 213403c667bSTim Shen template <class U> void operator<<=(U&& x); 214403c667bSTim Shen template <class U> void operator>>=(U&& x); 215403c667bSTim Shen void operator++(); 216403c667bSTim Shen void operator++(int); 217403c667bSTim Shen void operator--(); 218403c667bSTim Shen void operator--(int); 219403c667bSTim Shen template <class U, class Flags> void copy_from(const U* mem, Flags); 220403c667bSTim Shen}; 221403c667bSTim Shen 222403c667bSTim Shen// [simd.class] 223403c667bSTim Shentemplate <class T, class Abi> class simd { 224403c667bSTim Shenpublic: 225403c667bSTim Shen using value_type = T; 226403c667bSTim Shen using reference = see below; 227403c667bSTim Shen using mask_type = simd_mask<T, Abi>; 228403c667bSTim Shen 229403c667bSTim Shen using abi_type = Abi; 230403c667bSTim Shen static constexpr size_t size() noexcept; 231403c667bSTim Shen simd() = default; 232403c667bSTim Shen 233403c667bSTim Shen // implicit type conversion constructor 234403c667bSTim Shen template <class U> simd(const simd<U, simd_abi::fixed_size<size()>>&); 235403c667bSTim Shen 236403c667bSTim Shen // implicit broadcast constructor (see below for constraints) 237403c667bSTim Shen template <class U> simd(U&& value); 238403c667bSTim Shen 239403c667bSTim Shen // generator constructor (see below for constraints) 240403c667bSTim Shen template <class G> explicit simd(G&& gen); 241403c667bSTim Shen 242403c667bSTim Shen // load constructor 243403c667bSTim Shen template <class U, class Flags> simd(const U* mem, Flags f); 244403c667bSTim Shen 245403c667bSTim Shen // loads [simd.load] 246403c667bSTim Shen template <class U, class Flags> void copy_from(const U* mem, Flags f); 247403c667bSTim Shen 248403c667bSTim Shen // stores [simd.store] 249403c667bSTim Shen template <class U, class Flags> void copy_to(U* mem, Flags f) const; 250403c667bSTim Shen 251403c667bSTim Shen // scalar access [simd.subscr] 252403c667bSTim Shen reference operator[](size_t); 253403c667bSTim Shen value_type operator[](size_t) const; 254403c667bSTim Shen 255403c667bSTim Shen // unary operators [simd.unary] 256403c667bSTim Shen simd& operator++(); 257403c667bSTim Shen simd operator++(int); 258403c667bSTim Shen simd& operator--(); 259403c667bSTim Shen simd operator--(int); 260403c667bSTim Shen mask_type operator!() const; 261403c667bSTim Shen simd operator~() const; // see below 262403c667bSTim Shen simd operator+() const; 263403c667bSTim Shen simd operator-() const; 264403c667bSTim Shen 265403c667bSTim Shen // binary operators [simd.binary] 266403c667bSTim Shen friend simd operator+ (const simd&, const simd&); 267403c667bSTim Shen friend simd operator- (const simd&, const simd&); 268403c667bSTim Shen friend simd operator* (const simd&, const simd&); 269403c667bSTim Shen friend simd operator/ (const simd&, const simd&); 270403c667bSTim Shen friend simd operator% (const simd&, const simd&); 271403c667bSTim Shen friend simd operator& (const simd&, const simd&); 272403c667bSTim Shen friend simd operator| (const simd&, const simd&); 273403c667bSTim Shen friend simd operator^ (const simd&, const simd&); 274403c667bSTim Shen friend simd operator<<(const simd&, const simd&); 275403c667bSTim Shen friend simd operator>>(const simd&, const simd&); 276403c667bSTim Shen friend simd operator<<(const simd&, int); 277403c667bSTim Shen friend simd operator>>(const simd&, int); 278403c667bSTim Shen 279403c667bSTim Shen // compound assignment [simd.cassign] 280403c667bSTim Shen friend simd& operator+= (simd&, const simd&); 281403c667bSTim Shen friend simd& operator-= (simd&, const simd&); 282403c667bSTim Shen friend simd& operator*= (simd&, const simd&); 283403c667bSTim Shen friend simd& operator/= (simd&, const simd&); 284403c667bSTim Shen friend simd& operator%= (simd&, const simd&); 285403c667bSTim Shen 286403c667bSTim Shen friend simd& operator&= (simd&, const simd&); 287403c667bSTim Shen friend simd& operator|= (simd&, const simd&); 288403c667bSTim Shen friend simd& operator^= (simd&, const simd&); 289403c667bSTim Shen friend simd& operator<<=(simd&, const simd&); 290403c667bSTim Shen friend simd& operator>>=(simd&, const simd&); 291403c667bSTim Shen friend simd& operator<<=(simd&, int); 292403c667bSTim Shen friend simd& operator>>=(simd&, int); 293403c667bSTim Shen 294403c667bSTim Shen // compares [simd.comparison] 295403c667bSTim Shen friend mask_type operator==(const simd&, const simd&); 296403c667bSTim Shen friend mask_type operator!=(const simd&, const simd&); 297403c667bSTim Shen friend mask_type operator>=(const simd&, const simd&); 298403c667bSTim Shen friend mask_type operator<=(const simd&, const simd&); 299403c667bSTim Shen friend mask_type operator> (const simd&, const simd&); 300403c667bSTim Shen friend mask_type operator< (const simd&, const simd&); 301403c667bSTim Shen}; 302403c667bSTim Shen 303403c667bSTim Shen// [simd.math] 304403c667bSTim Shentemplate <class Abi> using scharv = simd<signed char, Abi>; // exposition only 305403c667bSTim Shentemplate <class Abi> using shortv = simd<short, Abi>; // exposition only 306403c667bSTim Shentemplate <class Abi> using intv = simd<int, Abi>; // exposition only 307403c667bSTim Shentemplate <class Abi> using longv = simd<long int, Abi>; // exposition only 308403c667bSTim Shentemplate <class Abi> using llongv = simd<long long int, Abi>; // exposition only 309403c667bSTim Shentemplate <class Abi> using floatv = simd<float, Abi>; // exposition only 310403c667bSTim Shentemplate <class Abi> using doublev = simd<double, Abi>; // exposition only 311403c667bSTim Shentemplate <class Abi> using ldoublev = simd<long double, Abi>; // exposition only 312403c667bSTim Shentemplate <class T, class V> using samesize = fixed_size_simd<T, V::size()>; // exposition only 313403c667bSTim Shen 314403c667bSTim Shentemplate <class Abi> floatv<Abi> acos(floatv<Abi> x); 315403c667bSTim Shentemplate <class Abi> doublev<Abi> acos(doublev<Abi> x); 316403c667bSTim Shentemplate <class Abi> ldoublev<Abi> acos(ldoublev<Abi> x); 317403c667bSTim Shen 318403c667bSTim Shentemplate <class Abi> floatv<Abi> asin(floatv<Abi> x); 319403c667bSTim Shentemplate <class Abi> doublev<Abi> asin(doublev<Abi> x); 320403c667bSTim Shentemplate <class Abi> ldoublev<Abi> asin(ldoublev<Abi> x); 321403c667bSTim Shen 322403c667bSTim Shentemplate <class Abi> floatv<Abi> atan(floatv<Abi> x); 323403c667bSTim Shentemplate <class Abi> doublev<Abi> atan(doublev<Abi> x); 324403c667bSTim Shentemplate <class Abi> ldoublev<Abi> atan(ldoublev<Abi> x); 325403c667bSTim Shen 326403c667bSTim Shentemplate <class Abi> floatv<Abi> atan2(floatv<Abi> y, floatv<Abi> x); 327403c667bSTim Shentemplate <class Abi> doublev<Abi> atan2(doublev<Abi> y, doublev<Abi> x); 328403c667bSTim Shentemplate <class Abi> ldoublev<Abi> atan2(ldoublev<Abi> y, ldoublev<Abi> x); 329403c667bSTim Shen 330403c667bSTim Shentemplate <class Abi> floatv<Abi> cos(floatv<Abi> x); 331403c667bSTim Shentemplate <class Abi> doublev<Abi> cos(doublev<Abi> x); 332403c667bSTim Shentemplate <class Abi> ldoublev<Abi> cos(ldoublev<Abi> x); 333403c667bSTim Shen 334403c667bSTim Shentemplate <class Abi> floatv<Abi> sin(floatv<Abi> x); 335403c667bSTim Shentemplate <class Abi> doublev<Abi> sin(doublev<Abi> x); 336403c667bSTim Shentemplate <class Abi> ldoublev<Abi> sin(ldoublev<Abi> x); 337403c667bSTim Shen 338403c667bSTim Shentemplate <class Abi> floatv<Abi> tan(floatv<Abi> x); 339403c667bSTim Shentemplate <class Abi> doublev<Abi> tan(doublev<Abi> x); 340403c667bSTim Shentemplate <class Abi> ldoublev<Abi> tan(ldoublev<Abi> x); 341403c667bSTim Shen 342403c667bSTim Shentemplate <class Abi> floatv<Abi> acosh(floatv<Abi> x); 343403c667bSTim Shentemplate <class Abi> doublev<Abi> acosh(doublev<Abi> x); 344403c667bSTim Shentemplate <class Abi> ldoublev<Abi> acosh(ldoublev<Abi> x); 345403c667bSTim Shen 346403c667bSTim Shentemplate <class Abi> floatv<Abi> asinh(floatv<Abi> x); 347403c667bSTim Shentemplate <class Abi> doublev<Abi> asinh(doublev<Abi> x); 348403c667bSTim Shentemplate <class Abi> ldoublev<Abi> asinh(ldoublev<Abi> x); 349403c667bSTim Shen 350403c667bSTim Shentemplate <class Abi> floatv<Abi> atanh(floatv<Abi> x); 351403c667bSTim Shentemplate <class Abi> doublev<Abi> atanh(doublev<Abi> x); 352403c667bSTim Shentemplate <class Abi> ldoublev<Abi> atanh(ldoublev<Abi> x); 353403c667bSTim Shen 354403c667bSTim Shentemplate <class Abi> floatv<Abi> cosh(floatv<Abi> x); 355403c667bSTim Shentemplate <class Abi> doublev<Abi> cosh(doublev<Abi> x); 356403c667bSTim Shentemplate <class Abi> ldoublev<Abi> cosh(ldoublev<Abi> x); 357403c667bSTim Shen 358403c667bSTim Shentemplate <class Abi> floatv<Abi> sinh(floatv<Abi> x); 359403c667bSTim Shentemplate <class Abi> doublev<Abi> sinh(doublev<Abi> x); 360403c667bSTim Shentemplate <class Abi> ldoublev<Abi> sinh(ldoublev<Abi> x); 361403c667bSTim Shen 362403c667bSTim Shentemplate <class Abi> floatv<Abi> tanh(floatv<Abi> x); 363403c667bSTim Shentemplate <class Abi> doublev<Abi> tanh(doublev<Abi> x); 364403c667bSTim Shentemplate <class Abi> ldoublev<Abi> tanh(ldoublev<Abi> x); 365403c667bSTim Shen 366403c667bSTim Shentemplate <class Abi> floatv<Abi> exp(floatv<Abi> x); 367403c667bSTim Shentemplate <class Abi> doublev<Abi> exp(doublev<Abi> x); 368403c667bSTim Shentemplate <class Abi> ldoublev<Abi> exp(ldoublev<Abi> x); 369403c667bSTim Shen 370403c667bSTim Shentemplate <class Abi> floatv<Abi> exp2(floatv<Abi> x); 371403c667bSTim Shentemplate <class Abi> doublev<Abi> exp2(doublev<Abi> x); 372403c667bSTim Shentemplate <class Abi> ldoublev<Abi> exp2(ldoublev<Abi> x); 373403c667bSTim Shen 374403c667bSTim Shentemplate <class Abi> floatv<Abi> expm1(floatv<Abi> x); 375403c667bSTim Shentemplate <class Abi> doublev<Abi> expm1(doublev<Abi> x); 376403c667bSTim Shentemplate <class Abi> ldoublev<Abi> expm1(ldoublev<Abi> x); 377403c667bSTim Shen 378403c667bSTim Shentemplate <class Abi> floatv<Abi> frexp(floatv<Abi> value, samesize<int, floatv<Abi>>* exp); 379403c667bSTim Shentemplate <class Abi> doublev<Abi> frexp(doublev<Abi> value, samesize<int, doublev<Abi>>* exp); 380403c667bSTim Shentemplate <class Abi> ldoublev<Abi> frexp(ldoublev<Abi> value, samesize<int, ldoublev<Abi>>* exp); 381403c667bSTim Shen 382403c667bSTim Shentemplate <class Abi> samesize<int, floatv<Abi>> ilogb(floatv<Abi> x); 383403c667bSTim Shentemplate <class Abi> samesize<int, doublev<Abi>> ilogb(doublev<Abi> x); 384403c667bSTim Shentemplate <class Abi> samesize<int, ldoublev<Abi>> ilogb(ldoublev<Abi> x); 385403c667bSTim Shen 386403c667bSTim Shentemplate <class Abi> floatv<Abi> ldexp(floatv<Abi> x, samesize<int, floatv<Abi>> exp); 387403c667bSTim Shentemplate <class Abi> doublev<Abi> ldexp(doublev<Abi> x, samesize<int, doublev<Abi>> exp); 388403c667bSTim Shentemplate <class Abi> ldoublev<Abi> ldexp(ldoublev<Abi> x, samesize<int, ldoublev<Abi>> exp); 389403c667bSTim Shen 390403c667bSTim Shentemplate <class Abi> floatv<Abi> log(floatv<Abi> x); 391403c667bSTim Shentemplate <class Abi> doublev<Abi> log(doublev<Abi> x); 392403c667bSTim Shentemplate <class Abi> ldoublev<Abi> log(ldoublev<Abi> x); 393403c667bSTim Shen 394403c667bSTim Shentemplate <class Abi> floatv<Abi> log10(floatv<Abi> x); 395403c667bSTim Shentemplate <class Abi> doublev<Abi> log10(doublev<Abi> x); 396403c667bSTim Shentemplate <class Abi> ldoublev<Abi> log10(ldoublev<Abi> x); 397403c667bSTim Shen 398403c667bSTim Shentemplate <class Abi> floatv<Abi> log1p(floatv<Abi> x); 399403c667bSTim Shentemplate <class Abi> doublev<Abi> log1p(doublev<Abi> x); 400403c667bSTim Shentemplate <class Abi> ldoublev<Abi> log1p(ldoublev<Abi> x); 401403c667bSTim Shen 402403c667bSTim Shentemplate <class Abi> floatv<Abi> log2(floatv<Abi> x); 403403c667bSTim Shentemplate <class Abi> doublev<Abi> log2(doublev<Abi> x); 404403c667bSTim Shentemplate <class Abi> ldoublev<Abi> log2(ldoublev<Abi> x); 405403c667bSTim Shen 406403c667bSTim Shentemplate <class Abi> floatv<Abi> logb(floatv<Abi> x); 407403c667bSTim Shentemplate <class Abi> doublev<Abi> logb(doublev<Abi> x); 408403c667bSTim Shentemplate <class Abi> ldoublev<Abi> logb(ldoublev<Abi> x); 409403c667bSTim Shen 410403c667bSTim Shentemplate <class Abi> floatv<Abi> modf(floatv<Abi> value, floatv<Abi>* iptr); 411403c667bSTim Shentemplate <class Abi> doublev<Abi> modf(doublev<Abi> value, doublev<Abi>* iptr); 412403c667bSTim Shentemplate <class Abi> ldoublev<Abi> modf(ldoublev<Abi> value, ldoublev<Abi>* iptr); 413403c667bSTim Shen 414403c667bSTim Shentemplate <class Abi> floatv<Abi> scalbn(floatv<Abi> x, samesize<int, floatv<Abi>> n); 415403c667bSTim Shentemplate <class Abi> doublev<Abi> scalbn(doublev<Abi> x, samesize<int, doublev<Abi>> n); 416403c667bSTim Shentemplate <class Abi> ldoublev<Abi> scalbn(ldoublev<Abi> x, samesize<int, ldoublev<Abi>> n); 417403c667bSTim Shentemplate <class Abi> floatv<Abi> scalbln(floatv<Abi> x, samesize<long int, floatv<Abi>> n); 418403c667bSTim Shentemplate <class Abi> doublev<Abi> scalbln(doublev<Abi> x, samesize<long int, doublev<Abi>> n); 419403c667bSTim Shentemplate <class Abi> ldoublev<Abi> scalbln(ldoublev<Abi> x, samesize<long int, ldoublev<Abi>> n); 420403c667bSTim Shen 421403c667bSTim Shentemplate <class Abi> floatv<Abi> cbrt(floatv<Abi> x); 422403c667bSTim Shentemplate <class Abi> doublev<Abi> cbrt(doublev<Abi> x); 423403c667bSTim Shentemplate <class Abi> ldoublev<Abi> cbrt(ldoublev<Abi> x); 424403c667bSTim Shen 425403c667bSTim Shentemplate <class Abi> scharv<Abi> abs(scharv<Abi> j); 426403c667bSTim Shentemplate <class Abi> shortv<Abi> abs(shortv<Abi> j); 427403c667bSTim Shentemplate <class Abi> intv<Abi> abs(intv<Abi> j); 428403c667bSTim Shentemplate <class Abi> longv<Abi> abs(longv<Abi> j); 429403c667bSTim Shentemplate <class Abi> llongv<Abi> abs(llongv<Abi> j); 430403c667bSTim Shentemplate <class Abi> floatv<Abi> abs(floatv<Abi> j); 431403c667bSTim Shentemplate <class Abi> doublev<Abi> abs(doublev<Abi> j); 432403c667bSTim Shentemplate <class Abi> ldoublev<Abi> abs(ldoublev<Abi> j); 433403c667bSTim Shen 434403c667bSTim Shentemplate <class Abi> floatv<Abi> hypot(floatv<Abi> x, floatv<Abi> y); 435403c667bSTim Shentemplate <class Abi> doublev<Abi> hypot(doublev<Abi> x, doublev<Abi> y); 436403c667bSTim Shentemplate <class Abi> ldoublev<Abi> hypot(doublev<Abi> x, doublev<Abi> y); 437403c667bSTim Shentemplate <class Abi> floatv<Abi> hypot(floatv<Abi> x, floatv<Abi> y, floatv<Abi> z); 438403c667bSTim Shentemplate <class Abi> doublev<Abi> hypot(doublev<Abi> x, doublev<Abi> y, doublev<Abi> z); 439403c667bSTim Shentemplate <class Abi> ldoublev<Abi> hypot(ldoublev<Abi> x, ldoublev<Abi> y, ldoublev<Abi> z); 440403c667bSTim Shen 441403c667bSTim Shentemplate <class Abi> floatv<Abi> pow(floatv<Abi> x, floatv<Abi> y); 442403c667bSTim Shentemplate <class Abi> doublev<Abi> pow(doublev<Abi> x, doublev<Abi> y); 443403c667bSTim Shentemplate <class Abi> ldoublev<Abi> pow(ldoublev<Abi> x, ldoublev<Abi> y); 444403c667bSTim Shen 445403c667bSTim Shentemplate <class Abi> floatv<Abi> sqrt(floatv<Abi> x); 446403c667bSTim Shentemplate <class Abi> doublev<Abi> sqrt(doublev<Abi> x); 447403c667bSTim Shentemplate <class Abi> ldoublev<Abi> sqrt(ldoublev<Abi> x); 448403c667bSTim Shen 449403c667bSTim Shentemplate <class Abi> floatv<Abi> erf(floatv<Abi> x); 450403c667bSTim Shentemplate <class Abi> doublev<Abi> erf(doublev<Abi> x); 451403c667bSTim Shentemplate <class Abi> ldoublev<Abi> erf(ldoublev<Abi> x); 452403c667bSTim Shentemplate <class Abi> floatv<Abi> erfc(floatv<Abi> x); 453403c667bSTim Shentemplate <class Abi> doublev<Abi> erfc(doublev<Abi> x); 454403c667bSTim Shentemplate <class Abi> ldoublev<Abi> erfc(ldoublev<Abi> x); 455403c667bSTim Shen 456403c667bSTim Shentemplate <class Abi> floatv<Abi> lgamma(floatv<Abi> x); 457403c667bSTim Shentemplate <class Abi> doublev<Abi> lgamma(doublev<Abi> x); 458403c667bSTim Shentemplate <class Abi> ldoublev<Abi> lgamma(ldoublev<Abi> x); 459403c667bSTim Shen 460403c667bSTim Shentemplate <class Abi> floatv<Abi> tgamma(floatv<Abi> x); 461403c667bSTim Shentemplate <class Abi> doublev<Abi> tgamma(doublev<Abi> x); 462403c667bSTim Shentemplate <class Abi> ldoublev<Abi> tgamma(ldoublev<Abi> x); 463403c667bSTim Shen 464403c667bSTim Shentemplate <class Abi> floatv<Abi> ceil(floatv<Abi> x); 465403c667bSTim Shentemplate <class Abi> doublev<Abi> ceil(doublev<Abi> x); 466403c667bSTim Shentemplate <class Abi> ldoublev<Abi> ceil(ldoublev<Abi> x); 467403c667bSTim Shen 468403c667bSTim Shentemplate <class Abi> floatv<Abi> floor(floatv<Abi> x); 469403c667bSTim Shentemplate <class Abi> doublev<Abi> floor(doublev<Abi> x); 470403c667bSTim Shentemplate <class Abi> ldoublev<Abi> floor(ldoublev<Abi> x); 471403c667bSTim Shen 472403c667bSTim Shentemplate <class Abi> floatv<Abi> nearbyint(floatv<Abi> x); 473403c667bSTim Shentemplate <class Abi> doublev<Abi> nearbyint(doublev<Abi> x); 474403c667bSTim Shentemplate <class Abi> ldoublev<Abi> nearbyint(ldoublev<Abi> x); 475403c667bSTim Shen 476403c667bSTim Shentemplate <class Abi> floatv<Abi> rint(floatv<Abi> x); 477403c667bSTim Shentemplate <class Abi> doublev<Abi> rint(doublev<Abi> x); 478403c667bSTim Shentemplate <class Abi> ldoublev<Abi> rint(ldoublev<Abi> x); 479403c667bSTim Shen 480403c667bSTim Shentemplate <class Abi> samesize<long int, floatv<Abi>> lrint(floatv<Abi> x); 481403c667bSTim Shentemplate <class Abi> samesize<long int, doublev<Abi>> lrint(doublev<Abi> x); 482403c667bSTim Shentemplate <class Abi> samesize<long int, ldoublev<Abi>> lrint(ldoublev<Abi> x); 483403c667bSTim Shentemplate <class Abi> samesize<long long int, floatv<Abi>> llrint(floatv<Abi> x); 484403c667bSTim Shentemplate <class Abi> samesize<long long int, doublev<Abi>> llrint(doublev<Abi> x); 485403c667bSTim Shentemplate <class Abi> samesize<long long int, ldoublev<Abi>> llrint(ldoublev<Abi> x); 486403c667bSTim Shen 487403c667bSTim Shentemplate <class Abi> floatv<Abi> round(floatv<Abi> x); 488403c667bSTim Shentemplate <class Abi> doublev<Abi> round(doublev<Abi> x); 489403c667bSTim Shentemplate <class Abi> ldoublev<Abi> round(ldoublev<Abi> x); 490403c667bSTim Shentemplate <class Abi> samesize<long int, floatv<Abi>> lround(floatv<Abi> x); 491403c667bSTim Shentemplate <class Abi> samesize<long int, doublev<Abi>> lround(doublev<Abi> x); 492403c667bSTim Shentemplate <class Abi> samesize<long int, ldoublev<Abi>> lround(ldoublev<Abi> x); 493403c667bSTim Shentemplate <class Abi> samesize<long long int, floatv<Abi>> llround(floatv<Abi> x); 494403c667bSTim Shentemplate <class Abi> samesize<long long int, doublev<Abi>> llround(doublev<Abi> x); 495403c667bSTim Shentemplate <class Abi> samesize<long long int, ldoublev<Abi>> llround(ldoublev<Abi> x); 496403c667bSTim Shen 497403c667bSTim Shentemplate <class Abi> floatv<Abi> trunc(floatv<Abi> x); 498403c667bSTim Shentemplate <class Abi> doublev<Abi> trunc(doublev<Abi> x); 499403c667bSTim Shentemplate <class Abi> ldoublev<Abi> trunc(ldoublev<Abi> x); 500403c667bSTim Shen 501403c667bSTim Shentemplate <class Abi> floatv<Abi> fmod(floatv<Abi> x, floatv<Abi> y); 502403c667bSTim Shentemplate <class Abi> doublev<Abi> fmod(doublev<Abi> x, doublev<Abi> y); 503403c667bSTim Shentemplate <class Abi> ldoublev<Abi> fmod(ldoublev<Abi> x, ldoublev<Abi> y); 504403c667bSTim Shen 505403c667bSTim Shentemplate <class Abi> floatv<Abi> remainder(floatv<Abi> x, floatv<Abi> y); 506403c667bSTim Shentemplate <class Abi> doublev<Abi> remainder(doublev<Abi> x, doublev<Abi> y); 507403c667bSTim Shentemplate <class Abi> ldoublev<Abi> remainder(ldoublev<Abi> x, ldoublev<Abi> y); 508403c667bSTim Shen 509403c667bSTim Shentemplate <class Abi> floatv<Abi> remquo(floatv<Abi> x, floatv<Abi> y, samesize<int, floatv<Abi>>* quo); 510403c667bSTim Shentemplate <class Abi> doublev<Abi> remquo(doublev<Abi> x, doublev<Abi> y, samesize<int, doublev<Abi>>* quo); 511403c667bSTim Shentemplate <class Abi> ldoublev<Abi> remquo(ldoublev<Abi> x, ldoublev<Abi> y, samesize<int, ldoublev<Abi>>* quo); 512403c667bSTim Shen 513403c667bSTim Shentemplate <class Abi> floatv<Abi> copysign(floatv<Abi> x, floatv<Abi> y); 514403c667bSTim Shentemplate <class Abi> doublev<Abi> copysign(doublev<Abi> x, doublev<Abi> y); 515403c667bSTim Shentemplate <class Abi> ldoublev<Abi> copysign(ldoublev<Abi> x, ldoublev<Abi> y); 516403c667bSTim Shen 517403c667bSTim Shentemplate <class Abi> doublev<Abi> nan(const char* tagp); 518403c667bSTim Shentemplate <class Abi> floatv<Abi> nanf(const char* tagp); 519403c667bSTim Shentemplate <class Abi> ldoublev<Abi> nanl(const char* tagp); 520403c667bSTim Shen 521403c667bSTim Shentemplate <class Abi> floatv<Abi> nextafter(floatv<Abi> x, floatv<Abi> y); 522403c667bSTim Shentemplate <class Abi> doublev<Abi> nextafter(doublev<Abi> x, doublev<Abi> y); 523403c667bSTim Shentemplate <class Abi> ldoublev<Abi> nextafter(ldoublev<Abi> x, ldoublev<Abi> y); 524403c667bSTim Shen 525403c667bSTim Shentemplate <class Abi> floatv<Abi> nexttoward(floatv<Abi> x, ldoublev<Abi> y); 526403c667bSTim Shentemplate <class Abi> doublev<Abi> nexttoward(doublev<Abi> x, ldoublev<Abi> y); 527403c667bSTim Shentemplate <class Abi> ldoublev<Abi> nexttoward(ldoublev<Abi> x, ldoublev<Abi> y); 528403c667bSTim Shen 529403c667bSTim Shentemplate <class Abi> floatv<Abi> fdim(floatv<Abi> x, floatv<Abi> y); 530403c667bSTim Shentemplate <class Abi> doublev<Abi> fdim(doublev<Abi> x, doublev<Abi> y); 531403c667bSTim Shentemplate <class Abi> ldoublev<Abi> fdim(ldoublev<Abi> x, ldoublev<Abi> y); 532403c667bSTim Shen 533403c667bSTim Shentemplate <class Abi> floatv<Abi> fmax(floatv<Abi> x, floatv<Abi> y); 534403c667bSTim Shentemplate <class Abi> doublev<Abi> fmax(doublev<Abi> x, doublev<Abi> y); 535403c667bSTim Shentemplate <class Abi> ldoublev<Abi> fmax(ldoublev<Abi> x, ldoublev<Abi> y); 536403c667bSTim Shen 537403c667bSTim Shentemplate <class Abi> floatv<Abi> fmin(floatv<Abi> x, floatv<Abi> y); 538403c667bSTim Shentemplate <class Abi> doublev<Abi> fmin(doublev<Abi> x, doublev<Abi> y); 539403c667bSTim Shentemplate <class Abi> ldoublev<Abi> fmin(ldoublev<Abi> x, ldoublev<Abi> y); 540403c667bSTim Shen 541403c667bSTim Shentemplate <class Abi> floatv<Abi> fma(floatv<Abi> x, floatv<Abi> y, floatv<Abi> z); 542403c667bSTim Shentemplate <class Abi> doublev<Abi> fma(doublev<Abi> x, doublev<Abi> y, doublev<Abi> z); 543403c667bSTim Shentemplate <class Abi> ldoublev<Abi> fma(ldoublev<Abi> x, ldoublev<Abi> y, ldoublev<Abi> z); 544403c667bSTim Shen 545403c667bSTim Shentemplate <class Abi> samesize<int, floatv<Abi>> fpclassify(floatv<Abi> x); 546403c667bSTim Shentemplate <class Abi> samesize<int, doublev<Abi>> fpclassify(doublev<Abi> x); 547403c667bSTim Shentemplate <class Abi> samesize<int, ldoublev<Abi>> fpclassify(ldoublev<Abi> x); 548403c667bSTim Shen 549403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> isfinite(floatv<Abi> x); 550403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> isfinite(doublev<Abi> x); 551403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> isfinite(ldoublev<Abi> x); 552403c667bSTim Shen 553403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> isinf(floatv<Abi> x); 554403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> isinf(doublev<Abi> x); 555403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> isinf(ldoublev<Abi> x); 556403c667bSTim Shen 557403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> isnan(floatv<Abi> x); 558403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> isnan(doublev<Abi> x); 559403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> isnan(ldoublev<Abi> x); 560403c667bSTim Shen 561403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> isnormal(floatv<Abi> x); 562403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> isnormal(doublev<Abi> x); 563403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> isnormal(ldoublev<Abi> x); 564403c667bSTim Shen 565403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> signbit(floatv<Abi> x); 566403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> signbit(doublev<Abi> x); 567403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> signbit(ldoublev<Abi> x); 568403c667bSTim Shen 569403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> isgreater(floatv<Abi> x, floatv<Abi> y); 570403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> isgreater(doublev<Abi> x, doublev<Abi> y); 571403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> isgreater(ldoublev<Abi> x, ldoublev<Abi> y); 572403c667bSTim Shen 573403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> isgreaterequal(floatv<Abi> x, floatv<Abi> y); 574403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> isgreaterequal(doublev<Abi> x, doublev<Abi> y); 575403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> isgreaterequal(ldoublev<Abi> x, ldoublev<Abi> y); 576403c667bSTim Shen 577403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> isless(floatv<Abi> x, floatv<Abi> y); 578403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> isless(doublev<Abi> x, doublev<Abi> y); 579403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> isless(ldoublev<Abi> x, ldoublev<Abi> y); 580403c667bSTim Shen 581403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> islessequal(floatv<Abi> x, floatv<Abi> y); 582403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> islessequal(doublev<Abi> x, doublev<Abi> y); 583403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> islessequal(ldoublev<Abi> x, ldoublev<Abi> y); 584403c667bSTim Shen 585403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> islessgreater(floatv<Abi> x, floatv<Abi> y); 586403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> islessgreater(doublev<Abi> x, doublev<Abi> y); 587403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> islessgreater(ldoublev<Abi> x, ldoublev<Abi> y); 588403c667bSTim Shen 589403c667bSTim Shentemplate <class Abi> simd_mask<float, Abi> isunordered(floatv<Abi> x, floatv<Abi> y); 590403c667bSTim Shentemplate <class Abi> simd_mask<double, Abi> isunordered(doublev<Abi> x, doublev<Abi> y); 591403c667bSTim Shentemplate <class Abi> simd_mask<long double, Abi> isunordered(ldoublev<Abi> x, ldoublev<Abi> y); 592403c667bSTim Shen 593403c667bSTim Shentemplate <class V> struct simd_div_t { V quot, rem; }; 594403c667bSTim Shentemplate <class Abi> simd_div_t<scharv<Abi>> div(scharv<Abi> numer, scharv<Abi> denom); 595403c667bSTim Shentemplate <class Abi> simd_div_t<shortv<Abi>> div(shortv<Abi> numer, shortv<Abi> denom); 596403c667bSTim Shentemplate <class Abi> simd_div_t<intv<Abi>> div(intv<Abi> numer, intv<Abi> denom); 597403c667bSTim Shentemplate <class Abi> simd_div_t<longv<Abi>> div(longv<Abi> numer, longv<Abi> denom); 598403c667bSTim Shentemplate <class Abi> simd_div_t<llongv<Abi>> div(llongv<Abi> numer, llongv<Abi> denom); 599403c667bSTim Shen 600403c667bSTim Shen// [simd.mask.class] 601403c667bSTim Shentemplate <class T, class Abi> 602403c667bSTim Shenclass simd_mask { 603403c667bSTim Shenpublic: 604403c667bSTim Shen using value_type = bool; 605403c667bSTim Shen using reference = see below; 606403c667bSTim Shen using simd_type = simd<T, Abi>; 607403c667bSTim Shen using abi_type = Abi; 608403c667bSTim Shen static constexpr size_t size() noexcept; 609403c667bSTim Shen simd_mask() = default; 610403c667bSTim Shen 611403c667bSTim Shen // broadcast constructor 612403c667bSTim Shen explicit simd_mask(value_type) noexcept; 613403c667bSTim Shen 614403c667bSTim Shen // implicit type conversion constructor 615403c667bSTim Shen template <class U> simd_mask(const simd_mask<U, simd_abi::fixed_size<size()>>&) noexcept; 616403c667bSTim Shen 617403c667bSTim Shen // load constructor 618403c667bSTim Shen template <class Flags> simd_mask(const value_type* mem, Flags); 619403c667bSTim Shen 620403c667bSTim Shen // loads [simd.mask.copy] 621403c667bSTim Shen template <class Flags> void copy_from(const value_type* mem, Flags); 622403c667bSTim Shen template <class Flags> void copy_to(value_type* mem, Flags) const; 623403c667bSTim Shen 624403c667bSTim Shen // scalar access [simd.mask.subscr] 625403c667bSTim Shen reference operator[](size_t); 626403c667bSTim Shen value_type operator[](size_t) const; 627403c667bSTim Shen 628403c667bSTim Shen // unary operators [simd.mask.unary] 629403c667bSTim Shen simd_mask operator!() const noexcept; 630403c667bSTim Shen 631403c667bSTim Shen // simd_mask binary operators [simd.mask.binary] 632403c667bSTim Shen friend simd_mask operator&&(const simd_mask&, const simd_mask&) noexcept; 633403c667bSTim Shen friend simd_mask operator||(const simd_mask&, const simd_mask&) noexcept; 634403c667bSTim Shen friend simd_mask operator& (const simd_mask&, const simd_mask&) noexcept; 635403c667bSTim Shen friend simd_mask operator| (const simd_mask&, const simd_mask&) noexcept; 636403c667bSTim Shen friend simd_mask operator^ (const simd_mask&, const simd_mask&) noexcept; 637403c667bSTim Shen 638403c667bSTim Shen // simd_mask compound assignment [simd.mask.cassign] 639403c667bSTim Shen friend simd_mask& operator&=(simd_mask&, const simd_mask&) noexcept; 640403c667bSTim Shen friend simd_mask& operator|=(simd_mask&, const simd_mask&) noexcept; 641403c667bSTim Shen friend simd_mask& operator^=(simd_mask&, const simd_mask&) noexcept; 642403c667bSTim Shen 643403c667bSTim Shen // simd_mask compares [simd.mask.comparison] 644403c667bSTim Shen friend simd_mask operator==(const simd_mask&, const simd_mask&) noexcept; 645403c667bSTim Shen friend simd_mask operator!=(const simd_mask&, const simd_mask&) noexcept; 646403c667bSTim Shen}; 647403c667bSTim Shen 648403c667bSTim Shen} // parallelism_v2 649403c667bSTim Shen} // std::experimental 650403c667bSTim Shen 651403c667bSTim Shen*/ 652403c667bSTim Shen 653403c667bSTim Shen#include <experimental/__config> 654403c667bSTim Shen#include <array> 655403c667bSTim Shen#include <cstddef> 656403c667bSTim Shen#include <functional> 657403c667bSTim Shen 658403c667bSTim Shen#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 659403c667bSTim Shen#pragma GCC system_header 660403c667bSTim Shen#endif 661403c667bSTim Shen 662403c667bSTim Shen_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD 663403c667bSTim Shen 664403c667bSTim Shenenum class _StorageKind { 665403c667bSTim Shen _Scalar, 666403c667bSTim Shen _Array, 667403c667bSTim Shen}; 668403c667bSTim Shen 669403c667bSTim Shentemplate <_StorageKind __kind, int _Np> 670403c667bSTim Shenstruct __simd_abi {}; 671403c667bSTim Shen 672403c667bSTim Shentemplate <class _Tp, class _Abi> 673*6f33ea4eSTim Shenstruct __simd_storage_traits {}; 674403c667bSTim Shen 675403c667bSTim Shentemplate <class _Tp, int __num_element> 676*6f33ea4eSTim Shenstruct __simd_storage_traits<_Tp, 677*6f33ea4eSTim Shen __simd_abi<_StorageKind::_Array, __num_element>> { 678*6f33ea4eSTim Shen using type = std::array<_Tp, __num_element>; 679403c667bSTim Shen}; 680403c667bSTim Shen 681403c667bSTim Shentemplate <class _Tp> 682*6f33ea4eSTim Shenstruct __simd_storage_traits<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> { 683*6f33ea4eSTim Shen using type = _Tp; 684403c667bSTim Shen}; 685403c667bSTim Shen 686403c667bSTim Shentemplate <class _To, class _From> 687403c667bSTim Shenconstexpr decltype(_To{std::declval<_From>()}, true) 688403c667bSTim Shen__is_non_narrowing_convertible_impl(_From) { 689403c667bSTim Shen return true; 690403c667bSTim Shen} 691403c667bSTim Shen 692403c667bSTim Shentemplate <class _To> 693403c667bSTim Shenconstexpr bool __is_non_narrowing_convertible_impl(...) { 694403c667bSTim Shen return false; 695403c667bSTim Shen} 696403c667bSTim Shen 697403c667bSTim Shentemplate <class _From, class _To> 698403c667bSTim Shenconstexpr typename std::enable_if<std::is_arithmetic<_To>::value && 699403c667bSTim Shen std::is_arithmetic<_From>::value, 700403c667bSTim Shen bool>::type 701403c667bSTim Shen__is_non_narrowing_arithmetic_convertible() { 702403c667bSTim Shen return __is_non_narrowing_convertible_impl<_To>(_From{}); 703403c667bSTim Shen} 704403c667bSTim Shen 705403c667bSTim Shentemplate <class _From, class _To> 706403c667bSTim Shenconstexpr typename std::enable_if<!(std::is_arithmetic<_To>::value && 707403c667bSTim Shen std::is_arithmetic<_From>::value), 708403c667bSTim Shen bool>::type 709403c667bSTim Shen__is_non_narrowing_arithmetic_convertible() { 710403c667bSTim Shen return false; 711403c667bSTim Shen} 712403c667bSTim Shen 713403c667bSTim Shentemplate <class _Tp> 714403c667bSTim Shenconstexpr _Tp __variadic_sum() { 715403c667bSTim Shen return _Tp{}; 716403c667bSTim Shen} 717403c667bSTim Shen 718403c667bSTim Shentemplate <class _Tp, class _Up, class... _Args> 719403c667bSTim Shenconstexpr _Tp __variadic_sum(_Up __first, _Args... __rest) { 720403c667bSTim Shen return static_cast<_Tp>(__first) + __variadic_sum<_Tp>(__rest...); 721403c667bSTim Shen} 722403c667bSTim Shen 723403c667bSTim Shen_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD 724403c667bSTim Shen_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD_ABI 725403c667bSTim Shen 726403c667bSTim Shenusing scalar = __simd_abi<_StorageKind::_Scalar, 1>; 727403c667bSTim Shen 728403c667bSTim Shentemplate <int _Np> 729403c667bSTim Shenusing fixed_size = __simd_abi<_StorageKind::_Array, _Np>; 730403c667bSTim Shen 731*6f33ea4eSTim Shen#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) 732403c667bSTim Shentemplate <class _Tp> 733*6f33ea4eSTim Shen_LIBCPP_INLINE_VAR constexpr int max_fixed_size = 32; 734*6f33ea4eSTim Shen#endif 735403c667bSTim Shentemplate <class _Tp> 736403c667bSTim Shenusing compatible = fixed_size<16 / sizeof(_Tp)>; 737403c667bSTim Shentemplate <class _Tp> 738*6f33ea4eSTim Shenusing native = compatible<_Tp>; 739403c667bSTim Shen 740403c667bSTim Shen_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI 741403c667bSTim Shen_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD 742403c667bSTim Shen 743403c667bSTim Shentemplate <class _Tp, class _Abi = simd_abi::compatible<_Tp>> 744403c667bSTim Shenclass simd; 745403c667bSTim Shentemplate <class _Tp, class _Abi = simd_abi::compatible<_Tp>> 746403c667bSTim Shenclass simd_mask; 747403c667bSTim Shen 748403c667bSTim Shenstruct element_aligned_tag {}; 749403c667bSTim Shenstruct vector_aligned_tag {}; 750403c667bSTim Shentemplate <size_t> 751403c667bSTim Shenstruct overaligned_tag {}; 752*6f33ea4eSTim Shen#if _LIBCPP_STD_VER > 14 753403c667bSTim Shen_LIBCPP_INLINE_VAR constexpr element_aligned_tag element_aligned{}; 754403c667bSTim Shen_LIBCPP_INLINE_VAR constexpr vector_aligned_tag vector_aligned{}; 755*6f33ea4eSTim Shen#if !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) 756403c667bSTim Shentemplate <size_t _Np> 757403c667bSTim Shen_LIBCPP_INLINE_VAR constexpr overaligned_tag<_Np> overaligned{}; 758*6f33ea4eSTim Shen#endif 759*6f33ea4eSTim Shen#endif 760403c667bSTim Shen 761403c667bSTim Shen// traits [simd.traits] 762403c667bSTim Shentemplate <class _Tp> 763403c667bSTim Shenstruct is_abi_tag : std::integral_constant<bool, false> {}; 764403c667bSTim Shen 765403c667bSTim Shentemplate <_StorageKind __kind, int _Np> 766403c667bSTim Shenstruct is_abi_tag<__simd_abi<__kind, _Np>> 767403c667bSTim Shen : std::integral_constant<bool, true> {}; 768403c667bSTim Shen 769403c667bSTim Shentemplate <class _Tp> 770403c667bSTim Shenstruct is_simd : std::integral_constant<bool, false> {}; 771403c667bSTim Shen 772403c667bSTim Shentemplate <class _Tp, class _Abi> 773403c667bSTim Shenstruct is_simd<simd<_Tp, _Abi>> : std::integral_constant<bool, true> {}; 774403c667bSTim Shen 775403c667bSTim Shentemplate <class _Tp> 776403c667bSTim Shenstruct is_simd_mask : std::integral_constant<bool, false> {}; 777403c667bSTim Shen 778403c667bSTim Shentemplate <class _Tp, class _Abi> 779403c667bSTim Shenstruct is_simd_mask<simd_mask<_Tp, _Abi>> : std::integral_constant<bool, true> { 780403c667bSTim Shen}; 781403c667bSTim Shen 782403c667bSTim Shentemplate <class _Tp> 783403c667bSTim Shenstruct is_simd_flag_type : std::integral_constant<bool, false> {}; 784403c667bSTim Shen 785403c667bSTim Shentemplate <> 786403c667bSTim Shenstruct is_simd_flag_type<element_aligned_tag> 787403c667bSTim Shen : std::integral_constant<bool, true> {}; 788403c667bSTim Shen 789403c667bSTim Shentemplate <> 790403c667bSTim Shenstruct is_simd_flag_type<vector_aligned_tag> 791403c667bSTim Shen : std::integral_constant<bool, true> {}; 792403c667bSTim Shen 793403c667bSTim Shentemplate <size_t _Align> 794403c667bSTim Shenstruct is_simd_flag_type<overaligned_tag<_Align>> 795403c667bSTim Shen : std::integral_constant<bool, true> {}; 796403c667bSTim Shen 797*6f33ea4eSTim Shen#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) 798403c667bSTim Shentemplate <class _Tp> 799403c667bSTim Shen_LIBCPP_INLINE_VAR constexpr bool is_abi_tag_v = is_abi_tag<_Tp>::value; 800403c667bSTim Shentemplate <class _Tp> 801403c667bSTim Shen_LIBCPP_INLINE_VAR constexpr bool is_simd_v = is_simd<_Tp>::value; 802403c667bSTim Shentemplate <class _Tp> 803403c667bSTim Shen_LIBCPP_INLINE_VAR constexpr bool is_simd_mask_v = is_simd_mask<_Tp>::value; 804403c667bSTim Shentemplate <class _Tp> 805403c667bSTim Shen_LIBCPP_INLINE_VAR constexpr bool is_simd_flag_type_v = 806403c667bSTim Shen is_simd_flag_type<_Tp>::value; 807*6f33ea4eSTim Shen#endif 808403c667bSTim Shentemplate <class _Tp, size_t _Np> 809403c667bSTim Shenstruct abi_for_size { 810403c667bSTim Shen using type = simd_abi::fixed_size<_Np>; 811403c667bSTim Shen}; 812403c667bSTim Shentemplate <class _Tp, size_t _Np> 813403c667bSTim Shenusing abi_for_size_t = typename abi_for_size<_Tp, _Np>::type; 814403c667bSTim Shen 815403c667bSTim Shentemplate <class _Tp, class _Abi = simd_abi::compatible<_Tp>> 816403c667bSTim Shenstruct simd_size; 817403c667bSTim Shen 818403c667bSTim Shentemplate <class _Tp, _StorageKind __kind, int _Np> 819403c667bSTim Shenstruct simd_size<_Tp, __simd_abi<__kind, _Np>> 820403c667bSTim Shen : std::integral_constant<size_t, _Np> { 821403c667bSTim Shen static_assert( 822403c667bSTim Shen std::is_arithmetic<_Tp>::value && 823403c667bSTim Shen !std::is_same<typename std::remove_const<_Tp>::type, bool>::value, 824403c667bSTim Shen "Element type should be vectorizable"); 825403c667bSTim Shen}; 826403c667bSTim Shen 827403c667bSTim Shentemplate <class _Tp, class _Up = typename _Tp::value_type> 828403c667bSTim Shenstruct memory_alignment; 829403c667bSTim Shen 830*6f33ea4eSTim Shen#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) 831403c667bSTim Shentemplate <class _Tp, class _Abi = simd_abi::compatible<_Tp>> 832403c667bSTim Shen_LIBCPP_INLINE_VAR constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value; 833403c667bSTim Shen 834403c667bSTim Shentemplate <class _Tp, class _Up = typename _Tp::value_type> 835403c667bSTim Shen_LIBCPP_INLINE_VAR constexpr size_t memory_alignment_v = 836403c667bSTim Shen memory_alignment<_Tp, _Up>::value; 837*6f33ea4eSTim Shen#endif 838403c667bSTim Shen 839403c667bSTim Shen// class template simd [simd.class] 840403c667bSTim Shentemplate <class _Tp> 841403c667bSTim Shenusing native_simd = simd<_Tp, simd_abi::native<_Tp>>; 842403c667bSTim Shentemplate <class _Tp, int _Np> 843403c667bSTim Shenusing fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>; 844403c667bSTim Shen 845403c667bSTim Shen// class template simd_mask [simd.mask.class] 846403c667bSTim Shentemplate <class _Tp> 847403c667bSTim Shenusing native_simd_mask = simd_mask<_Tp, simd_abi::native<_Tp>>; 848403c667bSTim Shen 849403c667bSTim Shentemplate <class _Tp, int _Np> 850403c667bSTim Shenusing fixed_size_simd_mask = simd_mask<_Tp, simd_abi::fixed_size<_Np>>; 851403c667bSTim Shen 852403c667bSTim Shen// casts [simd.casts] 853403c667bSTim Shentemplate <class _Tp> 854403c667bSTim Shenstruct __static_simd_cast_traits { 855403c667bSTim Shen template <class _Up, class _Abi> 856403c667bSTim Shen static simd<_Tp, _Abi> __apply(const simd<_Up, _Abi>& __v); 857403c667bSTim Shen}; 858403c667bSTim Shen 859403c667bSTim Shentemplate <class _Tp, class _NewAbi> 860403c667bSTim Shenstruct __static_simd_cast_traits<simd<_Tp, _NewAbi>> { 861403c667bSTim Shen template <class _Up, class _Abi> 862403c667bSTim Shen static typename std::enable_if<simd<_Up, _Abi>::size() == 863403c667bSTim Shen simd<_Tp, _NewAbi>::size(), 864403c667bSTim Shen simd<_Tp, _NewAbi>>::type 865403c667bSTim Shen __apply(const simd<_Up, _Abi>& __v); 866403c667bSTim Shen}; 867403c667bSTim Shen 868403c667bSTim Shentemplate <class _Tp> 869403c667bSTim Shenstruct __simd_cast_traits { 870403c667bSTim Shen template <class _Up, class _Abi> 871403c667bSTim Shen static typename std::enable_if< 872403c667bSTim Shen __is_non_narrowing_arithmetic_convertible<_Up, _Tp>(), 873403c667bSTim Shen simd<_Tp, _Abi>>::type 874403c667bSTim Shen __apply(const simd<_Up, _Abi>& __v); 875403c667bSTim Shen}; 876403c667bSTim Shen 877403c667bSTim Shentemplate <class _Tp, class _NewAbi> 878403c667bSTim Shenstruct __simd_cast_traits<simd<_Tp, _NewAbi>> { 879403c667bSTim Shen template <class _Up, class _Abi> 880403c667bSTim Shen static typename std::enable_if< 881403c667bSTim Shen __is_non_narrowing_arithmetic_convertible<_Up, _Tp>() && 882403c667bSTim Shen simd<_Up, _Abi>::size() == simd<_Tp, _NewAbi>::size(), 883403c667bSTim Shen simd<_Tp, _NewAbi>>::type 884403c667bSTim Shen __apply(const simd<_Up, _Abi>& __v); 885403c667bSTim Shen}; 886403c667bSTim Shen 887403c667bSTim Shentemplate <class _Tp, class _Up, class _Abi> 888403c667bSTim Shenauto simd_cast(const simd<_Up, _Abi>& __v) 889403c667bSTim Shen -> decltype(__simd_cast_traits<_Tp>::__apply(__v)) { 890403c667bSTim Shen return __simd_cast_traits<_Tp>::__apply(__v); 891403c667bSTim Shen} 892403c667bSTim Shen 893403c667bSTim Shentemplate <class _Tp, class _Up, class _Abi> 894403c667bSTim Shenauto static_simd_cast(const simd<_Up, _Abi>& __v) 895403c667bSTim Shen -> decltype(__static_simd_cast_traits<_Tp>::__apply(__v)) { 896403c667bSTim Shen return __static_simd_cast_traits<_Tp>::__apply(__v); 897403c667bSTim Shen} 898403c667bSTim Shen 899403c667bSTim Shentemplate <class _Tp, class _Abi> 900403c667bSTim Shenfixed_size_simd<_Tp, simd_size<_Tp, _Abi>::value> 901403c667bSTim Shento_fixed_size(const simd<_Tp, _Abi>&) noexcept; 902403c667bSTim Shen 903403c667bSTim Shentemplate <class _Tp, class _Abi> 904403c667bSTim Shenfixed_size_simd_mask<_Tp, simd_size<_Tp, _Abi>::value> 905403c667bSTim Shento_fixed_size(const simd_mask<_Tp, _Abi>&) noexcept; 906403c667bSTim Shen 907403c667bSTim Shentemplate <class _Tp, size_t _Np> 908403c667bSTim Shennative_simd<_Tp> to_native(const fixed_size_simd<_Tp, _Np>&) noexcept; 909403c667bSTim Shen 910403c667bSTim Shentemplate <class _Tp, size_t _Np> 911403c667bSTim Shennative_simd_mask<_Tp> to_native(const fixed_size_simd_mask<_Tp, _Np>&) noexcept; 912403c667bSTim Shen 913403c667bSTim Shentemplate <class _Tp, size_t _Np> 914403c667bSTim Shensimd<_Tp> to_compatible(const fixed_size_simd<_Tp, _Np>&) noexcept; 915403c667bSTim Shen 916403c667bSTim Shentemplate <class _Tp, size_t _Np> 917403c667bSTim Shensimd_mask<_Tp> to_compatible(const fixed_size_simd_mask<_Tp, _Np>&) noexcept; 918403c667bSTim Shen 919403c667bSTim Shentemplate <size_t... __sizes, class _Tp, class _Abi> 920403c667bSTim Shentuple<simd<_Tp, abi_for_size_t<_Tp, __sizes>>...> split(const simd<_Tp, _Abi>&); 921403c667bSTim Shen 922403c667bSTim Shentemplate <size_t... __sizes, class _Tp, class _Abi> 923403c667bSTim Shentuple<simd_mask<_Tp, abi_for_size_t<_Tp, __sizes>>...> 924403c667bSTim Shensplit(const simd_mask<_Tp, _Abi>&); 925403c667bSTim Shen 926403c667bSTim Shentemplate <class _SimdType, class _Abi> 927403c667bSTim Shenarray<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value / 928403c667bSTim Shen _SimdType::size()> 929403c667bSTim Shensplit(const simd<typename _SimdType::value_type, _Abi>&); 930403c667bSTim Shen 931403c667bSTim Shentemplate <class _SimdType, class _Abi> 932403c667bSTim Shenarray<_SimdType, simd_size<typename _SimdType::value_type, _Abi>::value / 933403c667bSTim Shen _SimdType::size()> 934403c667bSTim Shensplit(const simd_mask<typename _SimdType::value_type, _Abi>&); 935403c667bSTim Shen 936403c667bSTim Shentemplate <class _Tp, class... _Abis> 937403c667bSTim Shensimd<_Tp, abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>> 938403c667bSTim Shenconcat(const simd<_Tp, _Abis>&...); 939403c667bSTim Shen 940403c667bSTim Shentemplate <class _Tp, class... _Abis> 941403c667bSTim Shensimd_mask<_Tp, 942403c667bSTim Shen abi_for_size_t<_Tp, __variadic_sum(simd_size<_Tp, _Abis>::value...)>> 943403c667bSTim Shenconcat(const simd_mask<_Tp, _Abis>&...); 944403c667bSTim Shen 945403c667bSTim Shen// reductions [simd.mask.reductions] 946403c667bSTim Shentemplate <class _Tp, class _Abi> 947403c667bSTim Shenbool all_of(const simd_mask<_Tp, _Abi>&) noexcept; 948403c667bSTim Shentemplate <class _Tp, class _Abi> 949403c667bSTim Shenbool any_of(const simd_mask<_Tp, _Abi>&) noexcept; 950403c667bSTim Shentemplate <class _Tp, class _Abi> 951403c667bSTim Shenbool none_of(const simd_mask<_Tp, _Abi>&) noexcept; 952403c667bSTim Shentemplate <class _Tp, class _Abi> 953403c667bSTim Shenbool some_of(const simd_mask<_Tp, _Abi>&) noexcept; 954403c667bSTim Shentemplate <class _Tp, class _Abi> 955403c667bSTim Shenint popcount(const simd_mask<_Tp, _Abi>&) noexcept; 956403c667bSTim Shentemplate <class _Tp, class _Abi> 957403c667bSTim Shenint find_first_set(const simd_mask<_Tp, _Abi>&); 958403c667bSTim Shentemplate <class _Tp, class _Abi> 959403c667bSTim Shenint find_last_set(const simd_mask<_Tp, _Abi>&); 960403c667bSTim Shenbool all_of(bool) noexcept; 961403c667bSTim Shenbool any_of(bool) noexcept; 962403c667bSTim Shenbool none_of(bool) noexcept; 963403c667bSTim Shenbool some_of(bool) noexcept; 964403c667bSTim Shenint popcount(bool) noexcept; 965403c667bSTim Shenint find_first_set(bool) noexcept; 966403c667bSTim Shenint find_last_set(bool) noexcept; 967403c667bSTim Shen 968403c667bSTim Shen// masked assignment [simd.whereexpr] 969403c667bSTim Shentemplate <class _MaskType, class _Tp> 970403c667bSTim Shenclass const_where_expression; 971403c667bSTim Shentemplate <class _MaskType, class _Tp> 972403c667bSTim Shenclass where_expression; 973403c667bSTim Shen 974403c667bSTim Shen// masked assignment [simd.mask.where] 975*6f33ea4eSTim Shentemplate <class _Tp> 976*6f33ea4eSTim Shenstruct __nodeduce { 977*6f33ea4eSTim Shen using type = _Tp; 978*6f33ea4eSTim Shen}; 979*6f33ea4eSTim Shen 980403c667bSTim Shentemplate <class _Tp, class _Abi> 981403c667bSTim Shenwhere_expression<simd_mask<_Tp, _Abi>, simd<_Tp, _Abi>> 982403c667bSTim Shenwhere(const typename simd<_Tp, _Abi>::mask_type&, simd<_Tp, _Abi>&) noexcept; 983403c667bSTim Shen 984403c667bSTim Shentemplate <class _Tp, class _Abi> 985403c667bSTim Shenconst_where_expression<simd_mask<_Tp, _Abi>, const simd<_Tp, _Abi>> 986403c667bSTim Shenwhere(const typename simd<_Tp, _Abi>::mask_type&, 987403c667bSTim Shen const simd<_Tp, _Abi>&) noexcept; 988403c667bSTim Shen 989403c667bSTim Shentemplate <class _Tp, class _Abi> 990403c667bSTim Shenwhere_expression<simd_mask<_Tp, _Abi>, simd_mask<_Tp, _Abi>> 991403c667bSTim Shenwhere(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&, 992403c667bSTim Shen simd_mask<_Tp, _Abi>&) noexcept; 993403c667bSTim Shen 994403c667bSTim Shentemplate <class _Tp, class _Abi> 995403c667bSTim Shenconst_where_expression<simd_mask<_Tp, _Abi>, const simd_mask<_Tp, _Abi>> 996403c667bSTim Shenwhere(const typename __nodeduce<simd_mask<_Tp, _Abi>>::type&, 997403c667bSTim Shen const simd_mask<_Tp, _Abi>&) noexcept; 998403c667bSTim Shen 999403c667bSTim Shentemplate <class _Tp> 1000403c667bSTim Shenwhere_expression<bool, _Tp> where(bool, _Tp&) noexcept; 1001403c667bSTim Shen 1002403c667bSTim Shentemplate <class _Tp> 1003403c667bSTim Shenconst_where_expression<bool, const _Tp> where(bool, const _Tp&) noexcept; 1004403c667bSTim Shen 1005403c667bSTim Shen// reductions [simd.reductions] 1006403c667bSTim Shentemplate <class _Tp, class _Abi, class _BinaryOp = std::plus<_Tp>> 1007403c667bSTim Shen_Tp reduce(const simd<_Tp, _Abi>&, _BinaryOp = _BinaryOp()); 1008403c667bSTim Shen 1009403c667bSTim Shentemplate <class _MaskType, class _SimdType, class _BinaryOp> 1010403c667bSTim Shentypename _SimdType::value_type 1011403c667bSTim Shenreduce(const const_where_expression<_MaskType, _SimdType>&, 1012403c667bSTim Shen typename _SimdType::value_type neutral_element, _BinaryOp binary_op); 1013403c667bSTim Shen 1014403c667bSTim Shentemplate <class _MaskType, class _SimdType> 1015403c667bSTim Shentypename _SimdType::value_type 1016403c667bSTim Shenreduce(const const_where_expression<_MaskType, _SimdType>&, 1017403c667bSTim Shen plus<typename _SimdType::value_type> binary_op = {}); 1018403c667bSTim Shen 1019403c667bSTim Shentemplate <class _MaskType, class _SimdType> 1020403c667bSTim Shentypename _SimdType::value_type 1021403c667bSTim Shenreduce(const const_where_expression<_MaskType, _SimdType>&, 1022403c667bSTim Shen multiplies<typename _SimdType::value_type> binary_op); 1023403c667bSTim Shen 1024403c667bSTim Shentemplate <class _MaskType, class _SimdType> 1025403c667bSTim Shentypename _SimdType::value_type 1026403c667bSTim Shenreduce(const const_where_expression<_MaskType, _SimdType>&, 1027403c667bSTim Shen bit_and<typename _SimdType::value_type> binary_op); 1028403c667bSTim Shen 1029403c667bSTim Shentemplate <class _MaskType, class _SimdType> 1030403c667bSTim Shentypename _SimdType::value_type 1031403c667bSTim Shenreduce(const const_where_expression<_MaskType, _SimdType>&, 1032403c667bSTim Shen bit_or<typename _SimdType::value_type> binary_op); 1033403c667bSTim Shen 1034403c667bSTim Shentemplate <class _MaskType, class _SimdType> 1035403c667bSTim Shentypename _SimdType::value_type 1036403c667bSTim Shenreduce(const const_where_expression<_MaskType, _SimdType>&, 1037403c667bSTim Shen bit_xor<typename _SimdType::value_type> binary_op); 1038403c667bSTim Shen 1039403c667bSTim Shentemplate <class _Tp, class _Abi> 1040403c667bSTim Shen_Tp hmin(const simd<_Tp, _Abi>&); 1041403c667bSTim Shentemplate <class _MaskType, class _SimdType> 1042403c667bSTim Shentypename _SimdType::value_type 1043403c667bSTim Shenhmin(const const_where_expression<_MaskType, _SimdType>&); 1044403c667bSTim Shentemplate <class _Tp, class _Abi> 1045403c667bSTim Shen_Tp hmax(const simd<_Tp, _Abi>&); 1046403c667bSTim Shentemplate <class _MaskType, class _SimdType> 1047403c667bSTim Shentypename _SimdType::value_type 1048403c667bSTim Shenhmax(const const_where_expression<_MaskType, _SimdType>&); 1049403c667bSTim Shen 1050403c667bSTim Shen// algorithms [simd.alg] 1051403c667bSTim Shentemplate <class _Tp, class _Abi> 1052403c667bSTim Shensimd<_Tp, _Abi> min(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept; 1053403c667bSTim Shen 1054403c667bSTim Shentemplate <class _Tp, class _Abi> 1055403c667bSTim Shensimd<_Tp, _Abi> max(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept; 1056403c667bSTim Shen 1057403c667bSTim Shentemplate <class _Tp, class _Abi> 1058403c667bSTim Shenstd::pair<simd<_Tp, _Abi>, simd<_Tp, _Abi>> 1059403c667bSTim Shenminmax(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&) noexcept; 1060403c667bSTim Shen 1061403c667bSTim Shentemplate <class _Tp, class _Abi> 1062403c667bSTim Shensimd<_Tp, _Abi> clamp(const simd<_Tp, _Abi>&, const simd<_Tp, _Abi>&, 1063403c667bSTim Shen const simd<_Tp, _Abi>&); 1064403c667bSTim Shen 1065403c667bSTim Shen// [simd.whereexpr] 1066403c667bSTim Shen// TODO implement where expressions. 1067403c667bSTim Shentemplate <class _MaskType, class _Tp> 1068403c667bSTim Shenclass const_where_expression { 1069403c667bSTim Shenpublic: 1070403c667bSTim Shen const_where_expression(const const_where_expression&) = delete; 1071403c667bSTim Shen const_where_expression& operator=(const const_where_expression&) = delete; 1072403c667bSTim Shen typename remove_const<_Tp>::type operator-() const&&; 1073403c667bSTim Shen template <class _Up, class _Flags> 1074403c667bSTim Shen void copy_to(_Up*, _Flags) const&&; 1075403c667bSTim Shen}; 1076403c667bSTim Shen 1077403c667bSTim Shentemplate <class _MaskType, class _Tp> 1078403c667bSTim Shenclass where_expression : public const_where_expression<_MaskType, _Tp> { 1079403c667bSTim Shenpublic: 1080403c667bSTim Shen where_expression(const where_expression&) = delete; 1081403c667bSTim Shen where_expression& operator=(const where_expression&) = delete; 1082403c667bSTim Shen template <class _Up> 1083403c667bSTim Shen void operator=(_Up&&); 1084403c667bSTim Shen template <class _Up> 1085403c667bSTim Shen void operator+=(_Up&&); 1086403c667bSTim Shen template <class _Up> 1087403c667bSTim Shen void operator-=(_Up&&); 1088403c667bSTim Shen template <class _Up> 1089403c667bSTim Shen void operator*=(_Up&&); 1090403c667bSTim Shen template <class _Up> 1091403c667bSTim Shen void operator/=(_Up&&); 1092403c667bSTim Shen template <class _Up> 1093403c667bSTim Shen void operator%=(_Up&&); 1094403c667bSTim Shen template <class _Up> 1095403c667bSTim Shen void operator&=(_Up&&); 1096403c667bSTim Shen template <class _Up> 1097403c667bSTim Shen void operator|=(_Up&&); 1098403c667bSTim Shen template <class _Up> 1099403c667bSTim Shen void operator^=(_Up&&); 1100403c667bSTim Shen template <class _Up> 1101403c667bSTim Shen void operator<<=(_Up&&); 1102403c667bSTim Shen template <class _Up> 1103403c667bSTim Shen void operator>>=(_Up&&); 1104403c667bSTim Shen void operator++(); 1105403c667bSTim Shen void operator++(int); 1106403c667bSTim Shen void operator--(); 1107403c667bSTim Shen void operator--(int); 1108403c667bSTim Shen template <class _Up, class _Flags> 1109403c667bSTim Shen void copy_from(const _Up*, _Flags); 1110403c667bSTim Shen}; 1111403c667bSTim Shen 1112403c667bSTim Shen// [simd.class] 1113403c667bSTim Shen// TODO: implement simd 1114403c667bSTim Shentemplate <class _Tp, class _Abi> 1115403c667bSTim Shenclass simd { 1116403c667bSTim Shenprivate: 1117403c667bSTim Shen template <class _Up> 1118403c667bSTim Shen static constexpr bool __can_broadcast() { 1119403c667bSTim Shen return (std::is_arithmetic<_Up>::value && 1120403c667bSTim Shen __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()) || 1121403c667bSTim Shen (!std::is_arithmetic<_Up>::value && 1122403c667bSTim Shen std::is_convertible<_Up, _Tp>::value) || 1123403c667bSTim Shen std::is_same<typename std::remove_const<_Up>::type, int>::value || 1124403c667bSTim Shen (std::is_same<typename std::remove_const<_Up>::type, 1125403c667bSTim Shen unsigned int>::value && 1126403c667bSTim Shen std::is_unsigned<_Tp>::value); 1127403c667bSTim Shen } 1128403c667bSTim Shen 112947ad09b3STim Shenpublic: 1130*6f33ea4eSTim Shen using value_type = _Tp; 1131*6f33ea4eSTim Shen // TODO: this is strawman implementation. Turn it into a proxy type. 1132*6f33ea4eSTim Shen using reference = _Tp&; 1133*6f33ea4eSTim Shen using mask_type = simd_mask<_Tp, _Abi>; 1134*6f33ea4eSTim Shen 1135*6f33ea4eSTim Shen using abi_type = _Abi; 1136*6f33ea4eSTim Shen 1137*6f33ea4eSTim Shen static constexpr size_t size() noexcept { 1138*6f33ea4eSTim Shen return simd_size<_Tp, _Abi>::value; 1139*6f33ea4eSTim Shen } 1140*6f33ea4eSTim Shen 1141*6f33ea4eSTim Shen simd() = default; 1142*6f33ea4eSTim Shen 1143403c667bSTim Shen // implicit type conversion constructor 1144403c667bSTim Shen template <class _Up, 1145403c667bSTim Shen class = typename std::enable_if< 1146403c667bSTim Shen std::is_same<_Abi, simd_abi::fixed_size<size()>>::value && 1147403c667bSTim Shen __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()>::type> 1148*6f33ea4eSTim Shen simd(const simd<_Up, simd_abi::fixed_size<size()>>&) {} 1149403c667bSTim Shen 1150403c667bSTim Shen // implicit broadcast constructor 1151403c667bSTim Shen template <class _Up, 1152403c667bSTim Shen class = typename std::enable_if<__can_broadcast<_Up>()>::type> 1153*6f33ea4eSTim Shen simd(_Up&&); 1154403c667bSTim Shen 1155403c667bSTim Shen // generator constructor 1156*6f33ea4eSTim Shen // TODO: for now only check for the index 0. This is because C++11 doesn't 1157*6f33ea4eSTim Shen // have index_sequence, and it's hard to check for all indicies without using 1158*6f33ea4eSTim Shen // index_sequence. 1159403c667bSTim Shen template <class _Generator, 1160*6f33ea4eSTim Shen int = decltype(simd(std::declval<_Generator>()( 1161*6f33ea4eSTim Shen std::integral_constant<size_t, 0>())), 1162*6f33ea4eSTim Shen int())()> 1163*6f33ea4eSTim Shen explicit simd(_Generator&&); 1164403c667bSTim Shen 1165403c667bSTim Shen // load constructor 1166*6f33ea4eSTim Shen template <class _Up, class _Flags> 1167*6f33ea4eSTim Shen simd(const _Up*, _Flags); 1168403c667bSTim Shen 1169403c667bSTim Shen // loads [simd.load] 1170403c667bSTim Shen template <class _Up, class _Flags> 1171*6f33ea4eSTim Shen void copy_from(const _Up*, _Flags); 1172403c667bSTim Shen 1173403c667bSTim Shen // stores [simd.store] 1174403c667bSTim Shen template <class _Up, class _Flags> 1175*6f33ea4eSTim Shen void copy_to(_Up*, _Flags) const; 1176403c667bSTim Shen 1177403c667bSTim Shen // scalar access [simd.subscr] 1178*6f33ea4eSTim Shen reference operator[](size_t); 1179*6f33ea4eSTim Shen value_type operator[](size_t) const; 1180403c667bSTim Shen 1181403c667bSTim Shen // unary operators [simd.unary] 1182403c667bSTim Shen simd& operator++(); 1183403c667bSTim Shen simd operator++(int); 1184403c667bSTim Shen simd& operator--(); 1185403c667bSTim Shen simd operator--(int); 1186403c667bSTim Shen mask_type operator!() const; 1187403c667bSTim Shen simd operator~() const; 1188403c667bSTim Shen simd operator+() const; 1189403c667bSTim Shen simd operator-() const; 1190403c667bSTim Shen 1191403c667bSTim Shen // binary operators [simd.binary] 1192403c667bSTim Shen friend simd operator+(const simd&, const simd&); 1193403c667bSTim Shen friend simd operator-(const simd&, const simd&); 1194403c667bSTim Shen friend simd operator*(const simd&, const simd&); 1195403c667bSTim Shen friend simd operator/(const simd&, const simd&); 1196403c667bSTim Shen friend simd operator%(const simd&, const simd&); 1197403c667bSTim Shen friend simd operator&(const simd&, const simd&); 1198403c667bSTim Shen friend simd operator|(const simd&, const simd&); 1199403c667bSTim Shen friend simd operator^(const simd&, const simd&); 1200403c667bSTim Shen friend simd operator<<(const simd&, const simd&); 1201403c667bSTim Shen friend simd operator>>(const simd&, const simd&); 1202403c667bSTim Shen friend simd operator<<(const simd&, int); 1203403c667bSTim Shen friend simd operator>>(const simd&, int); 1204403c667bSTim Shen 1205403c667bSTim Shen // compound assignment [simd.cassign] 1206403c667bSTim Shen friend simd& operator+=(simd&, const simd&); 1207403c667bSTim Shen friend simd& operator-=(simd&, const simd&); 1208403c667bSTim Shen friend simd& operator*=(simd&, const simd&); 1209403c667bSTim Shen friend simd& operator/=(simd&, const simd&); 1210403c667bSTim Shen friend simd& operator%=(simd&, const simd&); 1211403c667bSTim Shen 1212403c667bSTim Shen friend simd& operator&=(simd&, const simd&); 1213403c667bSTim Shen friend simd& operator|=(simd&, const simd&); 1214403c667bSTim Shen friend simd& operator^=(simd&, const simd&); 1215403c667bSTim Shen friend simd& operator<<=(simd&, const simd&); 1216403c667bSTim Shen friend simd& operator>>=(simd&, const simd&); 1217403c667bSTim Shen friend simd& operator<<=(simd&, int); 1218403c667bSTim Shen friend simd& operator>>=(simd&, int); 1219403c667bSTim Shen 1220403c667bSTim Shen // compares [simd.comparison] 1221403c667bSTim Shen friend mask_type operator==(const simd&, const simd&); 1222403c667bSTim Shen friend mask_type operator!=(const simd&, const simd&); 1223403c667bSTim Shen friend mask_type operator>=(const simd&, const simd&); 1224403c667bSTim Shen friend mask_type operator<=(const simd&, const simd&); 1225403c667bSTim Shen friend mask_type operator>(const simd&, const simd&); 1226403c667bSTim Shen friend mask_type operator<(const simd&, const simd&); 1227403c667bSTim Shen}; 1228403c667bSTim Shen 1229403c667bSTim Shen// [simd.mask.class] 1230403c667bSTim Shentemplate <class _Tp, class _Abi> 1231403c667bSTim Shen// TODO: implement simd_mask 1232403c667bSTim Shenclass simd_mask { 1233403c667bSTim Shenpublic: 1234403c667bSTim Shen using value_type = bool; 1235403c667bSTim Shen // TODO: this is strawman implementation. Turn it into a proxy type. 1236403c667bSTim Shen using reference = bool&; 1237403c667bSTim Shen using simd_type = simd<_Tp, _Abi>; 1238403c667bSTim Shen using abi_type = _Abi; 1239403c667bSTim Shen static constexpr size_t size() noexcept; 1240403c667bSTim Shen simd_mask() = default; 1241403c667bSTim Shen 1242403c667bSTim Shen // broadcast constructor 1243403c667bSTim Shen explicit simd_mask(value_type) noexcept; 1244403c667bSTim Shen 1245403c667bSTim Shen // implicit type conversion constructor 1246403c667bSTim Shen template <class _Up> 1247403c667bSTim Shen simd_mask(const simd_mask<_Up, simd_abi::fixed_size<size()>>&) noexcept; 1248403c667bSTim Shen 1249403c667bSTim Shen // load constructor 1250403c667bSTim Shen template <class _Flags> 1251403c667bSTim Shen simd_mask(const value_type*, _Flags); 1252403c667bSTim Shen 1253403c667bSTim Shen // loads [simd.mask.copy] 1254403c667bSTim Shen template <class _Flags> 1255403c667bSTim Shen void copy_from(const value_type*, _Flags); 1256403c667bSTim Shen template <class _Flags> 1257403c667bSTim Shen void copy_to(value_type*, _Flags) const; 1258403c667bSTim Shen 1259403c667bSTim Shen // scalar access [simd.mask.subscr] 1260403c667bSTim Shen reference operator[](size_t); 1261403c667bSTim Shen value_type operator[](size_t) const; 1262403c667bSTim Shen 1263403c667bSTim Shen // unary operators [simd.mask.unary] 1264403c667bSTim Shen simd_mask operator!() const noexcept; 1265403c667bSTim Shen 1266403c667bSTim Shen // simd_mask binary operators [simd.mask.binary] 1267403c667bSTim Shen friend simd_mask operator&&(const simd_mask&, const simd_mask&) noexcept; 1268403c667bSTim Shen friend simd_mask operator||(const simd_mask&, const simd_mask&) noexcept; 1269403c667bSTim Shen friend simd_mask operator&(const simd_mask&, const simd_mask&)noexcept; 1270403c667bSTim Shen friend simd_mask operator|(const simd_mask&, const simd_mask&) noexcept; 1271403c667bSTim Shen friend simd_mask operator^(const simd_mask&, const simd_mask&) noexcept; 1272403c667bSTim Shen 1273403c667bSTim Shen // simd_mask compound assignment [simd.mask.cassign] 1274403c667bSTim Shen friend simd_mask& operator&=(simd_mask&, const simd_mask&) noexcept; 1275403c667bSTim Shen friend simd_mask& operator|=(simd_mask&, const simd_mask&) noexcept; 1276403c667bSTim Shen friend simd_mask& operator^=(simd_mask&, const simd_mask&) noexcept; 1277403c667bSTim Shen 1278403c667bSTim Shen // simd_mask compares [simd.mask.comparison] 1279403c667bSTim Shen friend simd_mask operator==(const simd_mask&, const simd_mask&) noexcept; 1280403c667bSTim Shen friend simd_mask operator!=(const simd_mask&, const simd_mask&) noexcept; 1281403c667bSTim Shen}; 1282403c667bSTim Shen 1283403c667bSTim Shen_LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD 1284403c667bSTim Shen 1285403c667bSTim Shen#endif /* _LIBCPP_EXPERIMENTAL_SIMD */ 1286