xref: /aosp_15_r20/external/pffft/pffft_common.c (revision 3f1979aa0d7ad34fcf3763de7b7b8f8cd67e5bdd)
1*3f1979aaSAndroid Build Coastguard Worker 
2*3f1979aaSAndroid Build Coastguard Worker #include "pffft.h"
3*3f1979aaSAndroid Build Coastguard Worker 
4*3f1979aaSAndroid Build Coastguard Worker #include <stdlib.h>
5*3f1979aaSAndroid Build Coastguard Worker 
6*3f1979aaSAndroid Build Coastguard Worker /* SSE and co like 16-bytes aligned pointers
7*3f1979aaSAndroid Build Coastguard Worker  * with a 64-byte alignment, we are even aligned on L2 cache lines... */
8*3f1979aaSAndroid Build Coastguard Worker #define MALLOC_V4SF_ALIGNMENT 64
9*3f1979aaSAndroid Build Coastguard Worker 
Valigned_malloc(size_t nb_bytes)10*3f1979aaSAndroid Build Coastguard Worker static void * Valigned_malloc(size_t nb_bytes) {
11*3f1979aaSAndroid Build Coastguard Worker   void *p, *p0 = malloc(nb_bytes + MALLOC_V4SF_ALIGNMENT);
12*3f1979aaSAndroid Build Coastguard Worker   if (!p0) return (void *) 0;
13*3f1979aaSAndroid Build Coastguard Worker   p = (void *) (((size_t) p0 + MALLOC_V4SF_ALIGNMENT) & (~((size_t) (MALLOC_V4SF_ALIGNMENT-1))));
14*3f1979aaSAndroid Build Coastguard Worker   *((void **) p - 1) = p0;
15*3f1979aaSAndroid Build Coastguard Worker   return p;
16*3f1979aaSAndroid Build Coastguard Worker }
17*3f1979aaSAndroid Build Coastguard Worker 
Valigned_free(void * p)18*3f1979aaSAndroid Build Coastguard Worker static void Valigned_free(void *p) {
19*3f1979aaSAndroid Build Coastguard Worker   if (p) free(*((void **) p - 1));
20*3f1979aaSAndroid Build Coastguard Worker }
21*3f1979aaSAndroid Build Coastguard Worker 
22*3f1979aaSAndroid Build Coastguard Worker 
next_power_of_two(int N)23*3f1979aaSAndroid Build Coastguard Worker static int next_power_of_two(int N) {
24*3f1979aaSAndroid Build Coastguard Worker   /* https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 */
25*3f1979aaSAndroid Build Coastguard Worker   /* compute the next highest power of 2 of 32-bit v */
26*3f1979aaSAndroid Build Coastguard Worker   unsigned v = N;
27*3f1979aaSAndroid Build Coastguard Worker   v--;
28*3f1979aaSAndroid Build Coastguard Worker   v |= v >> 1;
29*3f1979aaSAndroid Build Coastguard Worker   v |= v >> 2;
30*3f1979aaSAndroid Build Coastguard Worker   v |= v >> 4;
31*3f1979aaSAndroid Build Coastguard Worker   v |= v >> 8;
32*3f1979aaSAndroid Build Coastguard Worker   v |= v >> 16;
33*3f1979aaSAndroid Build Coastguard Worker   v++;
34*3f1979aaSAndroid Build Coastguard Worker   return v;
35*3f1979aaSAndroid Build Coastguard Worker }
36*3f1979aaSAndroid Build Coastguard Worker 
is_power_of_two(int N)37*3f1979aaSAndroid Build Coastguard Worker static int is_power_of_two(int N) {
38*3f1979aaSAndroid Build Coastguard Worker   /* https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 */
39*3f1979aaSAndroid Build Coastguard Worker   int f = N && !(N & (N - 1));
40*3f1979aaSAndroid Build Coastguard Worker   return f;
41*3f1979aaSAndroid Build Coastguard Worker }
42*3f1979aaSAndroid Build Coastguard Worker 
min_fft_size(pffft_transform_t transform)43*3f1979aaSAndroid Build Coastguard Worker static int min_fft_size(pffft_transform_t transform) {
44*3f1979aaSAndroid Build Coastguard Worker   /* unfortunately, the fft size must be a multiple of 16 for complex FFTs
45*3f1979aaSAndroid Build Coastguard Worker      and 32 for real FFTs -- a lot of stuff would need to be rewritten to
46*3f1979aaSAndroid Build Coastguard Worker      handle other cases (or maybe just switch to a scalar fft, I don't know..) */
47*3f1979aaSAndroid Build Coastguard Worker   int simdSz = pffft_simd_size();
48*3f1979aaSAndroid Build Coastguard Worker   if (transform == PFFFT_REAL)
49*3f1979aaSAndroid Build Coastguard Worker     return ( 2 * simdSz * simdSz );
50*3f1979aaSAndroid Build Coastguard Worker   else if (transform == PFFFT_COMPLEX)
51*3f1979aaSAndroid Build Coastguard Worker     return ( simdSz * simdSz );
52*3f1979aaSAndroid Build Coastguard Worker   else
53*3f1979aaSAndroid Build Coastguard Worker     return 1;
54*3f1979aaSAndroid Build Coastguard Worker }
55*3f1979aaSAndroid Build Coastguard Worker 
56*3f1979aaSAndroid Build Coastguard Worker 
pffft_aligned_malloc(size_t nb_bytes)57*3f1979aaSAndroid Build Coastguard Worker void *pffft_aligned_malloc(size_t nb_bytes) { return Valigned_malloc(nb_bytes); }
pffft_aligned_free(void * p)58*3f1979aaSAndroid Build Coastguard Worker void pffft_aligned_free(void *p) { Valigned_free(p); }
pffft_next_power_of_two(int N)59*3f1979aaSAndroid Build Coastguard Worker int pffft_next_power_of_two(int N) { return next_power_of_two(N); }
pffft_is_power_of_two(int N)60*3f1979aaSAndroid Build Coastguard Worker int pffft_is_power_of_two(int N) { return is_power_of_two(N); }
pffft_min_fft_size(pffft_transform_t transform)61*3f1979aaSAndroid Build Coastguard Worker int pffft_min_fft_size(pffft_transform_t transform) { return min_fft_size(transform); }
62*3f1979aaSAndroid Build Coastguard Worker 
pffftd_aligned_malloc(size_t nb_bytes)63*3f1979aaSAndroid Build Coastguard Worker void *pffftd_aligned_malloc(size_t nb_bytes) { return Valigned_malloc(nb_bytes); }
pffftd_aligned_free(void * p)64*3f1979aaSAndroid Build Coastguard Worker void pffftd_aligned_free(void *p) { Valigned_free(p); }
pffftd_next_power_of_two(int N)65*3f1979aaSAndroid Build Coastguard Worker int pffftd_next_power_of_two(int N) { return next_power_of_two(N); }
pffftd_is_power_of_two(int N)66*3f1979aaSAndroid Build Coastguard Worker int pffftd_is_power_of_two(int N) { return is_power_of_two(N); }
pffftd_min_fft_size(pffft_transform_t transform)67*3f1979aaSAndroid Build Coastguard Worker int pffftd_min_fft_size(pffft_transform_t transform) { return min_fft_size(transform); }
68*3f1979aaSAndroid Build Coastguard Worker 
69