Merged r11397:11413 from balister/arm-configure into trunk. Trunk passes distcheck.
[debian/gnuradio] / gnuradio-core / src / lib / filter / dotprod_fff_armv7_a.c
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2008,2009 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <dotprod_fff_armv7_a.h>
27
28 /*!
29  * \param x any value
30  * \param pow2 must be a power of 2
31  * \returns \p x rounded down to a multiple of \p pow2.
32  */
33 static inline size_t
34 gr_p2_round_down(size_t x, size_t pow2)
35 {
36   return x & -pow2;
37 }
38
39
40 #if 0
41
42 float
43 dotprod_fff_armv7_a(const float *a, const float *b, size_t n)
44 {
45   float sum = 0;
46   size_t i;
47   for (i = 0; i < n; i++){
48     sum += a[i] * b[i];
49   }
50   return sum;
51 }
52
53 #else
54
55 /*
56  *  preconditions:
57  *
58  *    n > 0 and a multiple of 4
59  *    a   4-byte aligned
60  *    b  16-byte aligned
61  */
62 float
63 dotprod_fff_armv7_a(const float *a, const float *b, size_t n)
64 {
65      float s = 0;
66
67     asm ("vmov.f32  q8, #0.0                  \n\t"
68          "vmov.f32  q9, #0.0                  \n\t"
69          "1:                                  \n\t"
70          "subs      %3, %3, #8                \n\t"
71          "vld1.32   {d0,d1,d2,d3}, [%1]!      \n\t"
72          "vld1.32   {d4,d5,d6,d7}, [%2]!      \n\t"
73          "vmla.f32  q8, q0, q2                \n\t"
74          "vmla.f32  q9, q1, q3                \n\t"
75          "bgt       1b                        \n\t"
76          "vadd.f32  q8, q8, q9                \n\t"
77          "vpadd.f32 d0, d16, d17              \n\t"
78          "vadd.f32  %0, s0, s1                \n\t"
79          : "=w"(s), "+r"(a), "+r"(b), "+r"(n)
80          :: "q0", "q1", "q2", "q3", "q8", "q9");
81
82     return s;
83
84 }
85
86 #endif