1 | /* Copyright (C) 2011-2014 Povilas Kanapickas <povilas@radix.lt> |
2 | |
3 | Distributed under the Boost Software License, Version 1.0. |
4 | (See accompanying file LICENSE_1_0.txt or copy at |
5 | http://www.boost.org/LICENSE_1_0.txt) |
6 | */ |
7 | |
8 | #ifndef LIBSIMDPP_SIMDPP_DETAIL_INSN_F_ISNAN2_H |
9 | #define LIBSIMDPP_SIMDPP_DETAIL_INSN_F_ISNAN2_H |
10 | |
11 | #ifndef LIBSIMDPP_SIMD_H |
12 | #error "This file must be included through simd.h" |
13 | #endif |
14 | |
15 | #include <simdpp/types.h> |
16 | #include <simdpp/core/bit_or.h> |
17 | #include <simdpp/core/f_isnan.h> |
18 | #include <simdpp/detail/null/math.h> |
19 | #include <simdpp/detail/vector_array_macros.h> |
20 | |
21 | namespace simdpp { |
22 | namespace SIMDPP_ARCH_NAMESPACE { |
23 | namespace detail { |
24 | namespace insn { |
25 | |
26 | |
27 | static SIMDPP_INL |
28 | mask_float32x4 i_isnan2(const float32x4& a, const float32x4& b) |
29 | { |
30 | #if SIMDPP_USE_NULL |
31 | return detail::null::isnan2(a, b); |
32 | #elif SIMDPP_USE_AVX512VL |
33 | return _mm_cmp_ps_mask(a.native(), b.native(), _CMP_UNORD_Q); |
34 | #elif SIMDPP_USE_AVX |
35 | return _mm_cmp_ps(a.native(), b.native(), _CMP_UNORD_Q); |
36 | #elif SIMDPP_USE_SSE2 |
37 | return (mask_float32x4) _mm_cmpunord_ps(a.native(), b.native()); |
38 | #elif SIMDPP_USE_NEON || SIMDPP_USE_ALTIVEC |
39 | return bit_or(isnan(a), isnan(b)); |
40 | #elif SIMDPP_USE_MSA |
41 | return (v4f32) __msa_fcun_w(a.native(), b.native()); |
42 | #endif |
43 | } |
44 | |
45 | #if SIMDPP_USE_AVX |
46 | static SIMDPP_INL |
47 | mask_float32x8 i_isnan2(const float32x8& a, const float32x8& b) |
48 | { |
49 | #if SIMDPP_USE_AVX512VL |
50 | return _mm256_cmp_ps_mask(a.native(), b.native(), _CMP_UNORD_Q); |
51 | #else |
52 | return _mm256_cmp_ps(a.native(), b.native(), _CMP_UNORD_Q); |
53 | #endif |
54 | } |
55 | #endif |
56 | |
57 | #if SIMDPP_USE_AVX512F |
58 | static SIMDPP_INL |
59 | mask_float32<16> i_isnan2(const float32<16>& a, const float32<16>& b) |
60 | { |
61 | return _mm512_cmp_ps_mask(a.native(), b.native(), _CMP_UNORD_Q); |
62 | } |
63 | #endif |
64 | |
65 | // ----------------------------------------------------------------------------- |
66 | |
67 | static SIMDPP_INL |
68 | mask_float64x2 i_isnan2(const float64x2& a, const float64x2& b) |
69 | { |
70 | #if SIMDPP_USE_AVX512VL |
71 | return _mm_cmp_pd_mask(a.native(), b.native(), _CMP_UNORD_Q); |
72 | #elif SIMDPP_USE_AVX |
73 | return _mm_cmp_pd(a.native(), b.native(), _CMP_UNORD_Q); |
74 | #elif SIMDPP_USE_SSE2 |
75 | return _mm_cmpunord_pd(a.native(), b.native()); |
76 | #elif SIMDPP_USE_NEON64 || SIMDPP_USE_VSX_206 |
77 | return bit_or(isnan(a), isnan(b)); |
78 | #elif SIMDPP_USE_MSA |
79 | return (v2f64) __msa_fcun_d(a.native(), b.native()); |
80 | #elif SIMDPP_USE_NULL || SIMDPP_USE_NEON32 || SIMDPP_USE_ALTIVEC |
81 | return detail::null::isnan2(a, b); |
82 | #endif |
83 | } |
84 | |
85 | #if SIMDPP_USE_AVX |
86 | static SIMDPP_INL |
87 | mask_float64x4 i_isnan2(const float64x4& a, const float64x4& b) |
88 | { |
89 | #if SIMDPP_USE_AVX512VL |
90 | return _mm256_cmp_pd_mask(a.native(), b.native(), _CMP_UNORD_Q); |
91 | #else |
92 | return _mm256_cmp_pd(a.native(), b.native(), _CMP_UNORD_Q); |
93 | #endif |
94 | } |
95 | #endif |
96 | |
97 | #if SIMDPP_USE_AVX512F |
98 | static SIMDPP_INL |
99 | mask_float64<8> i_isnan2(const float64<8>& a, const float64<8>& b) |
100 | { |
101 | return _mm512_cmp_pd_mask(a.native(), b.native(), _CMP_UNORD_Q); |
102 | } |
103 | #endif |
104 | |
105 | // ----------------------------------------------------------------------------- |
106 | |
107 | template<class V> SIMDPP_INL |
108 | typename V::mask_vector_type i_isnan2(const V& a, const V& b) |
109 | { |
110 | SIMDPP_VEC_ARRAY_IMPL2(typename V::mask_vector_type, i_isnan2, a, b); |
111 | } |
112 | |
113 | } // namespace insn |
114 | } // namespace detail |
115 | } // namespace SIMDPP_ARCH_NAMESPACE |
116 | } // namespace simdpp |
117 | |
118 | #endif |
119 | |
120 | |