1 /*  Copyright (C) 2016  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_EXPR_TEST_BITS_H
9 #define LIBSIMDPP_SIMDPP_DETAIL_EXPR_TEST_BITS_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/expr.h>
17 #include <simdpp/detail/insn/test_bits.h>
18 
19 namespace simdpp {
20 namespace SIMDPP_ARCH_NAMESPACE {
21 namespace detail {
22 
23 template<unsigned N, class V> SIMDPP_INL
e_test_bits_any(const any_vec<N,V> & a)24 bool e_test_bits_any(const any_vec<N,V>& a)
25 {
26     typename detail::get_expr_nosign<V>::type ra;
27     ra = a.wrapped().eval();
28     return insn::i_test_bits_any(ra);
29 }
30 
31 #if SIMDPP_USE_SSE4_1
32 template<unsigned N, template<unsigned, typename> class V,
33          class V1, class V2> SIMDPP_INL
e_test_bits_any(const any_vec<16,V<N,expr_bit_and<V1,V2>>> & e)34 bool e_test_bits_any(const any_vec<16, V<N, expr_bit_and<V1,V2>>>& e)
35 {
36     uint8<16> a, b;
37     a = e.wrapped().e.a.eval();
38     b = e.wrapped().e.b.eval();
39     return !_mm_testz_si128(b.native(), a.native());
40 }
41 
42 template<unsigned N, template<unsigned, typename> class V,
43          class V1, class V2> SIMDPP_INL
e_test_bits_any(const any_vec<16,V<N,expr_bit_andnot<V1,V2>>> & e)44 bool e_test_bits_any(const any_vec<16, V<N, expr_bit_andnot<V1,V2>>>& e)
45 {
46     uint8<16> a, b;
47     a = e.wrapped().e.a.eval();
48     b = e.wrapped().e.b.eval();
49     return !_mm_testc_si128(b.native(), a.native());
50 }
51 #endif
52 
53 #if SIMDPP_USE_AVX2
54 template<unsigned N, template<unsigned, typename> class V,
55          class V1, class V2> SIMDPP_INL
e_test_bits_any(const any_vec<32,V<N,expr_bit_and<V1,V2>>> & e)56 bool e_test_bits_any(const any_vec<32, V<N, expr_bit_and<V1,V2>>>& e)
57 {
58     uint8<32> a, b;
59     a = e.wrapped().e.a.eval();
60     b = e.wrapped().e.b.eval();
61     return !_mm256_testz_si256(b.native(), a.native());
62 }
63 
64 template<unsigned N, template<unsigned, typename> class V,
65          class V1, class V2>
e_test_bits_any(const any_vec<32,V<N,expr_bit_andnot<V1,V2>>> & e)66 bool e_test_bits_any(const any_vec<32, V<N, expr_bit_andnot<V1,V2>>>& e)
67 {
68     uint8<32> a, b;
69     a = e.wrapped().e.a.eval();
70     b = e.wrapped().e.b.eval();
71     return !_mm256_testc_si256(b.native(), a.native());
72 }
73 #endif
74 
75 #if SIMDPP_USE_AVX512F
76 template<class V1, class V2> SIMDPP_INL
e_test_bits_any(const uint32<16,expr_bit_and<V1,V2>> & e)77 bool e_test_bits_any(const uint32<16, expr_bit_and<V1,V2>>& e)
78 {
79     uint32<16> a, b;
80     a = e.wrapped().e.a.eval();
81     b = e.wrapped().e.b.eval();
82     return _mm512_test_epi64_mask(a.native(), b.native()) != 0;
83 }
84 
85 template<class V1, class V2> SIMDPP_INL
e_test_bits_any(const uint64<8,expr_bit_and<V1,V2>> & e)86 bool e_test_bits_any(const uint64<8, expr_bit_and<V1,V2>>& e)
87 {
88     uint64<8> a, b;
89     a = e.wrapped().e.a.eval();
90     b = e.wrapped().e.b.eval();
91     return _mm512_test_epi64_mask(a.native(), b.native()) != 0;
92 }
93 #endif
94 
95 
96 } // namespace detail
97 } // namespace SIMDPP_ARCH_NAMESPACE
98 } // namespace simdpp
99 
100 #endif
101