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_NEG_H
9#define LIBSIMDPP_SIMDPP_DETAIL_INSN_F_NEG_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_xor.h>
17#include <simdpp/detail/null/math.h>
18#include <simdpp/detail/vector_array_macros.h>
19
20namespace simdpp {
21namespace SIMDPP_ARCH_NAMESPACE {
22namespace detail {
23namespace insn {
24
25static SIMDPP_INL
26float32<4> i_fneg(const float32<4>& a)
27{
28#if SIMDPP_USE_NULL || SIMDPP_USE_NEON_NO_FLT_SP
29 return detail::null::neg(a);
30#elif SIMDPP_USE_SSE2 || SIMDPP_USE_ALTIVEC || SIMDPP_USE_MSA
31 // reversion of the sign bit required even for NaNs and zeros
32 return bit_xor(a, 0x80000000);
33#elif SIMDPP_USE_NEON_FLT_SP
34 return vnegq_f32(a.native());
35#endif
36}
37
38#if SIMDPP_USE_AVX
39static SIMDPP_INL
40float32<8> i_fneg(const float32<8>& a)
41{
42 return bit_xor(a, 0x80000000);
43}
44#endif
45
46#if SIMDPP_USE_AVX512F
47static SIMDPP_INL
48float32<16> i_fneg(const float32<16>& a)
49{
50 // FIXME: check whether we can simply use sub
51 return bit_xor(a, 0x80000000);
52}
53#endif
54
55// -----------------------------------------------------------------------------
56
57static SIMDPP_INL
58float64x2 i_fneg(const float64<2>& a)
59{
60#if SIMDPP_USE_SSE2 || SIMDPP_USE_VSX_206 || SIMDPP_USE_MSA
61 return bit_xor(a, 0x8000000000000000);
62#elif SIMDPP_USE_NEON64
63 return vnegq_f64(a.native());
64#elif SIMDPP_USE_NULL || SIMDPP_USE_NEON32 || SIMDPP_USE_ALTIVEC
65 return detail::null::neg(a);
66#endif
67}
68
69#if SIMDPP_USE_AVX
70static SIMDPP_INL
71float64x4 i_fneg(const float64<4>& a)
72{
73 return bit_xor(a, 0x8000000000000000);
74}
75#endif
76
77#if SIMDPP_USE_AVX512F
78static SIMDPP_INL
79float64<8> i_fneg(const float64<8>& a)
80{
81 // FIXME: check whether we can simply use sub
82 return bit_xor(a, 0x8000000000000000);
83}
84#endif
85
86// -----------------------------------------------------------------------------
87
88template<class V> SIMDPP_INL
89V i_fneg(const V& a)
90{
91 SIMDPP_VEC_ARRAY_IMPL1(V, i_fneg, a)
92}
93
94} // namespace insn
95} // namespace detail
96} // namespace SIMDPP_ARCH_NAMESPACE
97} // namespace simdpp
98
99#endif
100
101