expr.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /* Copyright (C) 2014 Povilas Kanapickas <[email protected]>
  2. Distributed under the Boost Software License, Version 1.0.
  3. (See accompanying file LICENSE_1_0.txt or copy at
  4. http://www.boost.org/LICENSE_1_0.txt)
  5. */
  6. #ifndef LIBSIMDPP_SIMD_EXPR_H
  7. #define LIBSIMDPP_SIMD_EXPR_H
  8. #include <simdpp/setup_arch.h>
  9. namespace simdpp {
  10. namespace SIMDPP_ARCH_NAMESPACE {
  11. namespace detail {
  12. /* The definition of expr_eval_wrapper is placed at the end of all expression
  13. includes so that all specializations of expr_eval are visible at that point
  14. */
  15. template<class R, class E> struct expr_eval_wrapper;
  16. template<class R, class E> struct expr_eval;
  17. } // namespace detail
  18. // -----------------------------------------------------------------------------
  19. struct expr_empty {};
  20. template<class E1, class E2>
  21. struct expr_bit_and {
  22. const E1& a;
  23. const E2& b;
  24. };
  25. template<class E1, class E2>
  26. struct expr_bit_andnot {
  27. const E1& a;
  28. const E2& b;
  29. };
  30. template<class E>
  31. struct expr_bit_not {
  32. const E& a;
  33. };
  34. template<class E1, class E2>
  35. struct expr_bit_or {
  36. const E1& a;
  37. const E2& b;
  38. };
  39. template<class E1, class E2>
  40. struct expr_bit_xor {
  41. const E1& a;
  42. const E2& b;
  43. };
  44. template<class E1, class E2, class E3>
  45. struct expr_blend {
  46. const E1& on;
  47. const E2& off;
  48. const E3& mask;
  49. };
  50. template<unsigned S, class E>
  51. struct expr_splat2 {
  52. const E& a;
  53. };
  54. template<unsigned S, class E>
  55. struct expr_splat4 {
  56. const E& a;
  57. };
  58. template<unsigned S, class E>
  59. struct expr_splat8 {
  60. const E& a;
  61. };
  62. template<unsigned S, class E>
  63. struct expr_splat16 {
  64. const E& a;
  65. };
  66. template<class E1, class E2>
  67. struct expr_iadd {
  68. const E1& a;
  69. const E2& b;
  70. };
  71. template<class E1, class E2>
  72. struct expr_fadd {
  73. const E1& a;
  74. const E2& b;
  75. };
  76. template<class E1, class E2>
  77. struct expr_iadd_sat {
  78. const E1& a;
  79. const E2& b;
  80. };
  81. template<class E1, class E2>
  82. struct expr_fsub {
  83. const E1& a;
  84. const E2& b;
  85. };
  86. template<class E1, class E2>
  87. struct expr_isub {
  88. const E1& a;
  89. const E2& b;
  90. };
  91. template<class E1, class E2>
  92. struct expr_isub_sat {
  93. const E1& a;
  94. const E2& b;
  95. };
  96. template<class E>
  97. struct expr_fabs {
  98. const E& a;
  99. };
  100. template<class E>
  101. struct expr_iabs {
  102. const E& a;
  103. };
  104. template<class E>
  105. struct expr_fneg {
  106. const E& a;
  107. };
  108. template<class E>
  109. struct expr_ineg {
  110. const E& a;
  111. };
  112. template<class E1, class E2>
  113. struct expr_fmul {
  114. const E1& a;
  115. const E2& b;
  116. };
  117. template<class E1, class E2>
  118. struct expr_mul_lo {
  119. const E1& a;
  120. const E2& b;
  121. };
  122. template<class E1, class E2>
  123. struct expr_mul_hi {
  124. const E1& a;
  125. const E2& b;
  126. };
  127. template<class E1, class E2>
  128. struct expr_mull {
  129. const E1& a;
  130. const E2& b;
  131. };
  132. template<class E1, class E2, class E3>
  133. struct expr_fmadd { // a * b + c
  134. const E1& a;
  135. const E2& b;
  136. const E3& c;
  137. };
  138. template<class E1, class E2, class E3>
  139. struct expr_fmsub { // a * b - c
  140. const E1& a;
  141. const E2& b;
  142. const E3& c;
  143. };
  144. template<unsigned S, class E>
  145. struct expr_imm_shift_l {
  146. const E& a;
  147. static const unsigned shift = S;
  148. };
  149. template<unsigned S, class E>
  150. struct expr_imm_shift_r {
  151. const E& a;
  152. static const unsigned shift = S;
  153. };
  154. template<class E>
  155. struct expr_vec_construct {
  156. SIMDPP_INL E& expr() { return static_cast<E&>(*this); }
  157. SIMDPP_INL const E& expr() const { return static_cast<const E&>(*this); }
  158. };
  159. struct expr_vec_load_splat : expr_vec_construct<expr_vec_load_splat> {
  160. const char* a;
  161. expr_vec_load_splat(const char* x) : a(x) {}
  162. };
  163. template<class VE>
  164. struct expr_vec_set_splat : expr_vec_construct<expr_vec_set_splat<VE>> {
  165. VE a;
  166. expr_vec_set_splat(const VE& x) : a(x) {}
  167. };
  168. template<class VE, unsigned N>
  169. struct expr_vec_make_const : expr_vec_construct<expr_vec_make_const<VE,N>> {
  170. VE a[N];
  171. SIMDPP_INL const VE& val(unsigned n) const { return a[n%N]; }
  172. };
  173. // This expression is needed because it's not possible to use
  174. // expr_vec_make_const to initialize floating-point vectors to ones
  175. struct expr_vec_make_ones : expr_vec_construct<expr_vec_make_ones> {};
  176. struct expr_vec_load : expr_vec_construct<expr_vec_load> {
  177. const char* a;
  178. };
  179. struct expr_vec_load_u : expr_vec_construct<expr_vec_load_u> {
  180. const char* a;
  181. expr_vec_load_u(const char* x) : a(x) {}
  182. };
  183. } // namespace SIMDPP_ARCH_NAMESPACE
  184. } // namespace simdpp
  185. #endif