# @synopsis AX_CHECK_ARM_NEON
#
# Does the machine support the ARM NEON instruction set?
-# @version 1.0 Dec 31 2012
+# @version 1.01 Feb 11 2013
# @author Steve Underwood
#
# Permission to use, copy, modify, distribute, and sell this file for any
static __inline__ int16_t saturated_mul16(int16_t a, int16_t b)
{
- int32_t product;
+ int32_t z;
- product = (int32_t) a*b;
- if (product == 0x40000000)
+#if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
+ __asm__ __volatile__(
+ " smulbb %[z],%[a],%[b];\n"
+ " qadd %[z],%[z],%[z];\n"
+ : [z] "=r" (z)
+ : [a] "r" (a), [b] "r" (b)
+ );
+ return (int16_t) (z >> 16);
+#else
+ z = (int32_t) a*b;
+ if (z == 0x40000000)
return INT16_MAX;
/*endif*/
- return (int16_t) (product >> 15);
+ return (int16_t) (z >> 15);
+#endif
}
/*- End of function --------------------------------------------------------*/
static __inline__ int32_t saturated_mul16_32(int16_t a, int16_t b)
{
- int32_t product;
+ int32_t z;
- product = (int32_t) a*b;
- if (product == 0x40000000)
+#if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
+ __asm__ __volatile__(
+ " smulbb %[z],%[a],%[b];\n"
+ " qadd %[z],%[z],%[z];\n"
+ : [z] "=r" (z)
+ : [a] "r" (a), [b] "r" (b)
+ );
+ return z;
+#else
+ z = (int32_t) a*b;
+ if (z == 0x40000000)
return INT32_MAX;
- return product << 1;
+ return z << 1;
+#endif
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ int32_t saturated_mac16_32(int32_t z, int16_t a, int16_t b)
+{
+#if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
+ int32_t product;
+
+ __asm__ __volatile__(
+ " smulbb %[p],%[a],%[b];\n"
+ " qdadd %[z],%[z],%[p];\n"
+ : [z] "=r" (z)
+ : "[z]" (z), [a] "r" (a), [b] "r" (b), [p] "r"(product)
+ );
+ return z;
+#else
+ return saturated_add32(z, saturated_mul16_32(a, b));
+#endif
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ int32_t saturated_msu16_32(int32_t z, int16_t a, int16_t b)
+{
+#if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
+ int32_t product;
+
+ __asm__ __volatile__(
+ " smulbb %[p],%[a],%[b];\n"
+ " qdsub %[z],%[z],%[p];\n"
+ : [z] "=r" (z)
+ : "[z]" (z), [a] "r" (a), [b] "r" (b), [p] "r" (product)
+ );
+ return z;
+#else
+ return saturated_sub32(z, saturated_mul16_32(a, b));
+#endif
}
/*- End of function --------------------------------------------------------*/
#include "spandsp/private/v22bis.h"
#if defined(SPANDSP_USE_FIXED_POINT)
+#define FP_SCALE(x) FP_Q_6_10(x)
#define FP_SHIFT_FACTOR 10
-#define FP_SCALE FP_Q_6_10
#else
#define FP_SCALE(x) (x)
#endif
{
int out_bit;
- bit &= 1;
-
/* Descramble the bit */
+ bit &= 1;
out_bit = (bit ^ (s->rx.scramble_reg >> 13) ^ (s->rx.scramble_reg >> 16)) & 1;
s->rx.scramble_reg = (s->rx.scramble_reg << 1) | bit;
{
/* Only AGC during the initial symbol acquisition, and then lock the gain. */
#if defined(SPANDSP_USE_FIXED_POINT)
- s->rx.agc_scaling = saturate16(((int32_t) (1024.0f*1024.0f*0.18f*3.60f))/fixed_sqrt32(power));
+ s->rx.agc_scaling = saturate16(((int32_t) (FP_SCALE(0.18f)*FP_SCALE(3.60f)))/fixed_sqrt32(power));
#else
- s->rx.agc_scaling = 0.18f*3.60f/sqrtf(power);
+ s->rx.agc_scaling = FP_SCALE(0.18f)*FP_SCALE(3.60f)/fixed_sqrt32(power);
#endif
}
/* Pulse shape while still at the carrier frequency, using a quadrature
step = -s->rx.eq_put_step;
if (step > PULSESHAPER_COEFF_SETS - 1)
step = PULSESHAPER_COEFF_SETS - 1;
- s->rx.eq_put_step += PULSESHAPER_COEFF_SETS*40/(3*2);
if (s->calling_party)
{
#if defined(SPANDSP_USE_FIXED_POINT)
zz.re = sample.re*z.re - sample.im*z.im;
zz.im = -sample.re*z.im - sample.im*z.re;
#endif
+ s->rx.eq_put_step += PULSESHAPER_COEFF_SETS*40/(3*2);
process_half_baud(s, &zz);
}
#if defined(SPANDSP_USE_FIXED_POINT)
#include "spandsp/private/v22bis.h"
#if defined(SPANDSP_USE_FIXED_POINT)
-#define FP_SCALE FP_Q_6_10
+#define FP_SCALE(x) FP_Q_6_10(x)
#else
#define FP_SCALE(x) (x)
#endif
#define FP_CONSTELLATION_SCALE(x) FP_SCALE(x)
-#include "v29tx_constellation_maps.h"
-
#include "v29tx_rrc.h"
+#include "v29tx_constellation_maps.h"
/*! The nominal frequency of the carrier, in Hertz */
#define CARRIER_NOMINAL_FREQ 1700.0f
exit(2);
}
printf("Testing 16 bit add\n");
- if (saturated_add16(10000, 10000) != 20000
- ||
- saturated_add16(10000, -10000) != 0
- ||
- saturated_add16(-10000, 10000) != 0
- ||
- saturated_add16(-10000, -10000) != -20000
- ||
- saturated_add16(-30000, -30000) != INT16_MIN
- ||
- saturated_add16(30000, 30000) != INT16_MAX)
+ if (saturated_add16(10000, 10000) != 20000)
+ printf("aaa1 %d\n", saturated_add16(10000, 10000));
+ if (saturated_add16(10000, -10000) != 0)
+ printf("aaa2 %d\n", saturated_add16(10000, -10000));
+ if (saturated_add16(-10000, 10000) != 0)
+ printf("aaa3 %d\n", saturated_add16(-10000, 10000));
+ if (saturated_add16(-10000, -10000) != -20000)
+ printf("aaa4 %d\n", saturated_add16(-10000, -10000));
+ if (saturated_add16(-30000, -30000) != INT16_MIN)
+ printf("aaa5 %d\n", saturated_add16(-30000, -30000));
+ if (saturated_add16(30000, 30000) != INT16_MAX)
{
printf("Test failed.\n");
exit(2);
printf("Test failed.\n");
exit(2);
}
+ printf("Testing 32 + 16 x 16 => 32 bit MAC\n");
+ if (saturated_mac16_32(123, 100, 100) != 123 + 20000
+ ||
+ saturated_mac16_32(123, -100, 100) != 123 - 20000
+ ||
+ saturated_mac16_32(123, 32767, -32768) != 123 - 2147418112
+ ||
+ saturated_mac16_32(123, -32768, 32767) != 123 - 2147418112
+ ||
+ saturated_mac16_32(123, 32767, 32767) != 123 + 2147352578
+ ||
+ saturated_mac16_32(123, -32768, -32768) != INT32_MAX)
+ {
+ printf("Test failed.\n");
+ exit(2);
+ }
+ printf("Testing 32 - 16 x 16 => 32 bit MSU\n");
+ if (saturated_msu16_32(123, 100, 100) != 123 - 20000
+ ||
+ saturated_msu16_32(123, -100, 100) != 123 + 20000
+ ||
+ saturated_msu16_32(123, 32767, -32768) != 123 + 2147418112
+ ||
+ saturated_msu16_32(123, -32768, 32767) != 123 + 2147418112
+ ||
+ saturated_msu16_32(123, 32767, 32767) != 123 - 2147352578
+ ||
+ saturated_msu16_32(123, -32768, -32768) != 123 - INT32_MAX)
+ {
+ printf("Test failed.\n");
+ exit(2);
+ }
printf("Testing 16 bit absolute\n");
if (saturated_abs16(10000) != 10000
||