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_ISNAN_H
9#define LIBSIMDPP_SIMDPP_DETAIL_INSN_ISNAN_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/detail/null/math.h>
17#include <simdpp/detail/vector_array_macros.h>
18
19namespace simdpp {
20namespace SIMDPP_ARCH_NAMESPACE {
21namespace detail {
22namespace insn {
23
24
25static SIMDPP_INL
26mask_float32x4 i_isnan(const float32x4& a)
27{
28#if SIMDPP_USE_NULL || SIMDPP_USE_NEON_NO_FLT_SP
29 return detail::null::isnan(a);
30#elif SIMDPP_USE_AVX512VL
31 return _mm_cmp_ps_mask(a.native(), a.native(), _CMP_UNORD_Q);
32#elif SIMDPP_USE_AVX
33 return _mm_cmp_ps(a.native(), a.native(), _CMP_UNORD_Q);
34#elif SIMDPP_USE_SSE2
35 return (mask_float32x4) _mm_cmpunord_ps(a.native(), a.native());
36#elif SIMDPP_USE_NEON || SIMDPP_USE_ALTIVEC
37 return cmp_neq(a, a);
38#elif SIMDPP_USE_MSA
39 return (v4f32) __msa_fcun_w(a.native(), a.native());
40#endif
41}
42
43#if SIMDPP_USE_AVX
44static SIMDPP_INL
45mask_float32x8 i_isnan(const float32x8& a)
46{
47#if SIMDPP_USE_AVX512VL
48 return _mm256_cmp_ps_mask(a.native(), a.native(), _CMP_UNORD_Q);
49#else
50 return _mm256_cmp_ps(a.native(), a.native(), _CMP_UNORD_Q);
51#endif
52}
53#endif
54
55#if SIMDPP_USE_AVX512F
56static SIMDPP_INL
57mask_float32<16> i_isnan(const float32<16>& a)
58{
59 return _mm512_cmp_ps_mask(a.native(), a.native(), _CMP_UNORD_Q);
60}
61#endif
62
63// -----------------------------------------------------------------------------
64
65static SIMDPP_INL
66mask_float64x2 i_isnan(const float64x2& a)
67{
68#if SIMDPP_USE_AVX512VL
69 return _mm_cmp_pd_mask(a.native(), a.native(), _CMP_UNORD_Q);
70#elif SIMDPP_USE_AVX
71 return _mm_cmp_pd(a.native(), a.native(), _CMP_UNORD_Q);
72#elif SIMDPP_USE_SSE2
73 return _mm_cmpunord_pd(a.native(), a.native());
74#elif SIMDPP_USE_NEON64 || SIMDPP_USE_VSX_206
75 return cmp_neq(a, a);
76#elif SIMDPP_USE_MSA
77 return (v2f64) __msa_fcun_d(a.native(), a.native());
78#elif SIMDPP_USE_NULL || SIMDPP_USE_NEON32 || SIMDPP_USE_ALTIVEC
79 return detail::null::isnan(a);
80#endif
81}
82
83#if SIMDPP_USE_AVX
84static SIMDPP_INL
85mask_float64x4 i_isnan(const float64x4& a)
86{
87#if SIMDPP_USE_AVX512VL
88 return _mm256_cmp_pd_mask(a.native(), a.native(), _CMP_UNORD_Q);
89#else
90 return _mm256_cmp_pd(a.native(), a.native(), _CMP_UNORD_Q);
91#endif
92}
93#endif
94
95#if SIMDPP_USE_AVX512F
96static SIMDPP_INL
97mask_float64<8> i_isnan(const float64<8>& a)
98{
99 return _mm512_cmp_pd_mask(a.native(), a.native(), _CMP_UNORD_Q);
100}
101#endif
102
103// -----------------------------------------------------------------------------
104
105template<class V> SIMDPP_INL
106typename V::mask_vector_type i_isnan(const V& a)
107{
108 SIMDPP_VEC_ARRAY_IMPL1(typename V::mask_vector_type, i_isnan, a);
109}
110
111} // namespace insn
112} // namespace detail
113} // namespace SIMDPP_ARCH_NAMESPACE
114} // namespace simdpp
115
116#endif
117
118