/*
 * NEON Convolution
 * Copyright (C) 2012, 2013 Thomas Tsou <tom@tsou.cc>
 *
 * SPDX-License-Identifier: LGPL-2.1+
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

#include <malloc.h>
#include <string.h>
#include <stdio.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* Forward declarations from base implementation */
int _base_convolve_real(float *x, int x_len,
			float *h, int h_len,
			float *y, int y_len,
			int start, int len);

int _base_convolve_complex(float *x, int x_len,
			   float *h, int h_len,
			   float *y, int y_len,
			   int start, int len);

int bounds_check(int x_len, int h_len, int y_len,
		 int start, int len);

#ifdef HAVE_NEON
/* Calls into NEON assembler */
void neon_conv_real4(float *x, float *h, float *y, int len);
void neon_conv_real8(float *x, float *h, float *y, int len);
void neon_conv_real12(float *x, float *h, float *y, int len);
void neon_conv_real16(float *x, float *h, float *y, int len);
void neon_conv_real20(float *x, float *h, float *y, int len);
void mac_cx_neon4(float *x, float *h, float *y, int len);

/* Complex-complex convolution */
static void neon_conv_cmplx_4n(float *x, float *h, float *y, int h_len, int len)
{
	for (int i = 0; i < len; i++)
		mac_cx_neon4(&x[2 * i], h, &y[2 * i], h_len >> 2);
}
#endif

/* API: Initialize convolve module */
void convolve_init(void)
{
	/* Stub */
	return;
}

/* API: Aligned complex-real */
int convolve_real(float *x, int x_len,
		  float *h, int h_len,
		  float *y, int y_len,
		  int start, int len)
{
	void (*conv_func)(float *, float *, float *, int) = NULL;

	if (bounds_check(x_len, h_len, y_len, start, len) < 0)
		return -1;

	memset(y, 0, len * 2 * sizeof(float));

#ifdef HAVE_NEON
	switch (h_len) {
	case 4:
		conv_func = neon_conv_real4;
		break;
	case 8:
		conv_func = neon_conv_real8;
		break;
	case 12:
		conv_func = neon_conv_real12;
		break;
	case 16:
		conv_func = neon_conv_real16;
		break;
	case 20:
		conv_func = neon_conv_real20;
		break;
	}
#endif
	if (conv_func) {
		conv_func(&x[2 * (-(h_len - 1) + start)],
			  h, y, len);
	} else {
		_base_convolve_real(x, x_len,
				    h, h_len,
				    y, y_len,
				    start, len);
	}

	return len;
}


/* API: Aligned complex-complex */
int convolve_complex(float *x, int x_len,
		     float *h, int h_len,
		     float *y, int y_len,
		     int start, int len)
{
	void (*conv_func)(float *, float *, float *, int, int) = NULL;

	if (bounds_check(x_len, h_len, y_len, start, len) < 0)
		return -1;

	memset(y, 0, len * 2 * sizeof(float));

#ifdef HAVE_NEON
	if (!(h_len % 4))
		conv_func = neon_conv_cmplx_4n;
#endif
	if (conv_func) {
		conv_func(&x[2 * (-(h_len - 1) + start)],
			  h, y, h_len, len);
	} else {
		_base_convolve_complex(x, x_len,
				       h, h_len,
				       y, y_len,
				       start, len);
	}

	return len;
}
