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_MUL_H
9#define LIBSIMDPP_SIMDPP_DETAIL_INSN_F_MUL_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#if SIMDPP_USE_NULL || SIMDPP_USE_NEON
17 #include <simdpp/detail/null/math.h>
18#endif
19#include <simdpp/detail/vector_array_macros.h>
20
21namespace simdpp {
22namespace SIMDPP_ARCH_NAMESPACE {
23namespace detail {
24namespace insn {
25
26static SIMDPP_INL
27float32<4> i_fmul(const float32<4>& a, const float32<4>& b)
28{
29#if SIMDPP_USE_NULL || SIMDPP_USE_NEON_NO_FLT_SP
30 return detail::null::mul(a, b);
31#elif SIMDPP_USE_SSE2
32 return _mm_mul_ps(a.native(), b.native());
33#elif SIMDPP_USE_NEON_FLT_SP
34 return vmulq_f32(a.native(), b.native());
35#elif SIMDPP_USE_VSX_206
36 return vec_mul(a.native(), b.native());
37#elif SIMDPP_USE_ALTIVEC
38 float32<4> zero = make_zero();
39 return vec_madd(a.native(), b.native(), zero.native());
40#elif SIMDPP_USE_MSA
41 return __msa_fmul_w(a.native(), b.native());
42#endif
43}
44
45#if SIMDPP_USE_AVX
46static SIMDPP_INL
47float32<8> i_fmul(const float32<8>& a, const float32<8>& b)
48{
49 return _mm256_mul_ps(a.native(), b.native());
50}
51#endif
52
53#if SIMDPP_USE_AVX512F
54static SIMDPP_INL
55float32<16> i_fmul(const float32<16>& a, const float32<16>& b)
56{
57 return _mm512_mul_ps(a.native(), b.native());
58}
59#endif
60
61// -----------------------------------------------------------------------------
62
63static SIMDPP_INL
64float64<2> i_fmul(const float64<2>& a, const float64<2>& b)
65{
66#if SIMDPP_USE_SSE2
67 return _mm_mul_pd(a.native(), b.native());
68#elif SIMDPP_USE_NEON64
69 return vmulq_f64(a.native(), b.native());
70#elif SIMDPP_USE_VSX_206
71 return vec_mul(a.native(), b.native());
72#elif SIMDPP_USE_MSA
73 return __msa_fmul_d(a.native(), b.native());
74#elif SIMDPP_USE_NULL || SIMDPP_USE_NEON32 || SIMDPP_USE_ALTIVEC
75 return detail::null::mul(a, b);
76#endif
77}
78
79#if SIMDPP_USE_AVX
80static SIMDPP_INL
81float64<4> i_fmul(const float64<4>& a, const float64<4>& b)
82{
83 return _mm256_mul_pd(a.native(), b.native());
84}
85#endif
86
87#if SIMDPP_USE_AVX512F
88static SIMDPP_INL
89float64<8> i_fmul(const float64<8>& a, const float64<8>& b)
90{
91 return _mm512_mul_pd(a.native(), b.native());
92}
93#endif
94
95// -----------------------------------------------------------------------------
96
97template<class V> SIMDPP_INL
98V i_fmul(const V& a, const V& b)
99{
100 SIMDPP_VEC_ARRAY_IMPL2(V, i_fmul, a, b)
101}
102
103} // namespace insn
104} // namespace detail
105} // namespace SIMDPP_ARCH_NAMESPACE
106} // namespace simdpp
107
108#endif
109
110