memcpy: hide some memory latencies
[nova-simd.git] / simd_ternary_arithmetic.hpp
blobc316f7031e2e2c0133dc91e62706d03b29552cb6
1 // templated arithmetic simd functions
2 // Copyright (C) 2009 Tim Blechmann <tim@klingt.org>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 // implemented as part of nova
21 #ifndef SIMD_TERNARY_ARITHMETIC_HPP
22 #define SIMD_TERNARY_ARITHMETIC_HPP
24 #include <algorithm>
26 #include "vec.hpp"
28 #include "detail/define_macros.hpp"
30 #if defined(__GNUC__) && defined(NDEBUG)
31 #define always_inline inline __attribute__((always_inline))
32 #else
33 #define always_inline inline
34 #endif
37 namespace nova {
38 namespace detail {
40 struct clip
42 template<typename float_type>
43 float_type operator()(float_type value, float_type low, float_type high) const
45 return max_(min_(value, high),
46 low);
50 struct muladd
52 template<typename float_type>
53 float_type operator()(float_type value, float_type mul, float_type add) const
55 return value * mul + add;
58 template<typename float_type>
59 vec<float_type> operator()(vec<float_type> value, vec<float_type> mul, vec<float_type> add) const
61 return madd(value, mul, add);
65 struct ampmod
67 template<typename float_type>
68 float_type operator()(float_type signal, float_type modulator, float_type amount) const
70 float_type one = 1.f;
71 return signal * (one + modulator * amount);
78 NOVA_SIMD_DEFINE_TERNARY_WRAPPER(clip, detail::clip)
79 NOVA_SIMD_DEFINE_TERNARY_WRAPPER(muladd, detail::muladd)
80 NOVA_SIMD_DEFINE_TERNARY_WRAPPER(ampmod, detail::ampmod)
84 #undef always_inline
86 #endif /* SIMD_TERNARY_ARITHMETIC_HPP */