1/* Copyright (C) 2013-2017 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_SUB_H
9#define LIBSIMDPP_SIMDPP_DETAIL_INSN_F_SUB_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
24static SIMDPP_INL
25float32<4> i_fsub(const float32<4>& a, const float32<4>& b)
26{
27#if SIMDPP_USE_NULL || SIMDPP_USE_NEON_NO_FLT_SP
28 return detail::null::sub(a, b);
29#elif SIMDPP_USE_SSE2
30 return _mm_sub_ps(a.native(), b.native());
31#elif SIMDPP_USE_NEON_FLT_SP
32 return vsubq_f32(a.native(), b.native());
33#elif SIMDPP_USE_ALTIVEC
34 return vec_sub(a.native(), b.native());
35#elif SIMDPP_USE_MSA
36 return __msa_fsub_w(a.native(), b.native());
37#endif
38}
39
40#if SIMDPP_USE_AVX
41static SIMDPP_INL
42float32<8> i_fsub(const float32<8>& a, const float32<8>& b)
43{
44 return _mm256_sub_ps(a.native(), b.native());
45}
46#endif
47
48#if SIMDPP_USE_AVX512F
49static SIMDPP_INL
50float32<16> i_fsub(const float32<16>& a, const float32<16>& b)
51{
52 return _mm512_sub_ps(a.native(), b.native());
53}
54#endif
55
56template<class R, unsigned N, class E1, class E2> SIMDPP_INL
57float32<N> i_fsub(const float32<N>& a, const float32<N>& b)
58{
59 SIMDPP_VEC_ARRAY_IMPL2(float32<N>, sub, a, b);
60}
61
62// -----------------------------------------------------------------------------
63
64static SIMDPP_INL
65float64<2> i_fsub(const float64<2>& a, const float64<2>& b)
66{
67#if SIMDPP_USE_SSE2
68 return _mm_sub_pd(a.native(), b.native());
69#elif SIMDPP_USE_NEON64
70 return vsubq_f64(a.native(), b.native());
71#elif SIMDPP_USE_VSX_206
72 return vec_sub(a.native(), b.native());
73#elif SIMDPP_USE_NULL || SIMDPP_USE_NEON || SIMDPP_USE_ALTIVEC
74 return detail::null::sub(a, b);
75#elif SIMDPP_USE_MSA
76 return __msa_fsub_d(a.native(), b.native());
77#endif
78}
79
80#if SIMDPP_USE_AVX
81static SIMDPP_INL
82float64<4> i_fsub(const float64<4>& a, const float64<4>& b)
83{
84 return _mm256_sub_pd(a.native(), b.native());
85}
86#endif
87
88#if SIMDPP_USE_AVX512F
89static SIMDPP_INL
90float64<8> i_fsub(const float64<8>& a, const float64<8>& b)
91{
92 return _mm512_sub_pd(a.native(), b.native());
93}
94#endif
95
96// -----------------------------------------------------------------------------
97
98template<class V> SIMDPP_INL
99V i_fsub(const V& a, const V& b)
100{
101 SIMDPP_VEC_ARRAY_IMPL2(V, i_fsub, a, b)
102}
103
104} // namespace insn
105} // namespace detail
106} // namespace SIMDPP_ARCH_NAMESPACE
107} // namespace simdpp
108
109#endif
110
111