summaryrefslogtreecommitdiff
path: root/volk
diff options
context:
space:
mode:
authorNathan West <nathan.west@okstate.edu>2014-10-21 17:32:30 -0500
committerNathan West <nathan.west@okstate.edu>2014-10-21 17:32:30 -0500
commit398f96a94e2b0b0df8870ad4ccc956bce4c9633b (patch)
tree12f960e64c009ec56a2f6c96c855fdeec6715a82 /volk
parent150bb12cffd1e2a07028aabd2cc395ea3502c17a (diff)
volk: add neon version of complex<float> dot product
Diffstat (limited to 'volk')
-rw-r--r--volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h49
-rw-r--r--volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h2
2 files changed, 49 insertions, 2 deletions
diff --git a/volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h b/volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h
index 750f508b7e..8964434bef 100644
--- a/volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h
+++ b/volk/kernels/volk/volk_32fc_x2_conjugate_dot_prod_32fc.h
@@ -164,10 +164,57 @@ static inline void volk_32fc_x2_conjugate_dot_prod_32fc_u_sse3(lv_32fc_t* result
#endif /*LV_HAVE_SSE3*/
+#ifdef LV_HAVE_NEON
+#include <arm_neon.h>
+static inline void volk_32fc_x2_conjugate_dot_prod_32fc_neon(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
+
+ unsigned int quarter_points = num_points / 4;
+ unsigned int number;
+
+ lv_32fc_t* a_ptr = (lv_32fc_t*) taps;
+ lv_32fc_t* b_ptr = (lv_32fc_t*) input;
+ // for 2-lane vectors, 1st lane holds the real part,
+ // 2nd lane holds the imaginary part
+ float32x4x2_t a_val, b_val, accumulator;
+ float32x4x2_t tmp_imag;
+ accumulator.val[0] = vdupq_n_f32(0);
+ accumulator.val[1] = vdupq_n_f32(0);
+
+ for(number = 0; number < quarter_points; ++number) {
+ a_val = vld2q_f32((float*)a_ptr); // a0r|a1r|a2r|a3r || a0i|a1i|a2i|a3i
+ b_val = vld2q_f32((float*)b_ptr); // b0r|b1r|b2r|b3r || b0i|b1i|b2i|b3i
+ __builtin_prefetch(a_ptr+8);
+ __builtin_prefetch(b_ptr+8);
+
+ // do the first multiply
+ tmp_imag.val[1] = vmulq_f32(a_val.val[1], b_val.val[0]);
+ tmp_imag.val[0] = vmulq_f32(a_val.val[0], b_val.val[0]);
+
+ // use multiply accumulate/subtract to get result
+ tmp_imag.val[1] = vmlsq_f32(tmp_imag.val[1], a_val.val[0], b_val.val[1]);
+ tmp_imag.val[0] = vmlaq_f32(tmp_imag.val[0], a_val.val[1], b_val.val[1]);
+
+ accumulator.val[0] = vaddq_f32(accumulator.val[0], tmp_imag.val[0]);
+ accumulator.val[1] = vaddq_f32(accumulator.val[1], tmp_imag.val[1]);
+
+ // increment pointers
+ a_ptr += 4;
+ b_ptr += 4;
+ }
+ lv_32fc_t accum_result[4];
+ vst2q_f32((float*)accum_result, accumulator);
+ *result = accum_result[0] + accum_result[1] + accum_result[2] + accum_result[3];
-#endif /*INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_u_H*/
+ // tail case
+ for(number = quarter_points*4; number < num_points; ++number) {
+ *result += (*a_ptr++) * lv_conj(*b_ptr++);
+ }
+ *result = lv_conj(*result);
+}
+#endif /*LV_HAVE_NEON*/
+#endif /*INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_u_H*/
#ifndef INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_a_H
#define INCLUDED_volk_32fc_x2_conjugate_dot_prod_32fc_a_H
diff --git a/volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h b/volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h
index d0a09f989f..c65d0984c5 100644
--- a/volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h
+++ b/volk/kernels/volk/volk_32fc_x2_dot_prod_32fc.h
@@ -896,7 +896,7 @@ static inline void volk_32fc_x2_dot_prod_32fc_neon(lv_32fc_t* result, const lv_3
#endif /*LV_HAVE_NEON*/
#ifdef LV_HAVE_NEON
-
+#include <arm_neon.h>
static inline void volk_32fc_x2_dot_prod_32fc_neon_opttests(lv_32fc_t* result, const lv_32fc_t* input, const lv_32fc_t* taps, unsigned int num_points) {
unsigned int quarter_points = num_points / 4;