Browse Source

add more assemble implementation in wma codec.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@27 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 16 years ago
parent
commit
556b091940

+ 17 - 206
bsp/stm32_radio/libwma/asm_arm.h

@@ -18,211 +18,22 @@
 #ifndef __ASM_ARM_H__
 #define __ASM_ARM_H__
 
-#if !defined(_V_WIDE_MATH) && !defined(_LOW_ACCURACY_)
-#define _V_WIDE_MATH
-
-static inline int32_t MULT32(int32_t x, int32_t y) {
-  int lo,hi;
-  asm volatile("smull\t%0, %1, %2, %3"
-               : "=&r"(lo),"=&r"(hi)
-               : "%r"(x),"r"(y)
-	       : "cc");
-  return(hi);
-}
-
-static inline int32_t MULT31(int32_t x, int32_t y) {
-  return MULT32(x,y)<<1;
-}
-
-static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
-  int lo,hi;
-  asm volatile("smull	%0, %1, %2, %3\n\t"
-	       "movs	%0, %0, lsr #15\n\t"
-	       "adc	%1, %0, %1, lsl #17\n\t"
-               : "=&r"(lo),"=&r"(hi)
-               : "%r"(x),"r"(y)
-	       : "cc");
-  return(hi);
-}
-
-#define MB() asm volatile ("" : : : "memory")
-
-#define XPROD32(a, b, t, v, x, y) \
-{ \
-  long l; \
-  asm(	"smull	%0, %1, %4, %6\n\t" \
-	"smlal	%0, %1, %5, %7\n\t" \
-	"rsb	%3, %4, #0\n\t" \
-	"smull	%0, %2, %5, %6\n\t" \
-	"smlal	%0, %2, %3, %7" \
-	: "=&r" (l), "=&r" (x), "=&r" (y), "=r" ((a)) \
-	: "3" ((a)), "r" ((b)), "r" ((t)), "r" ((v)) \
-	: "cc" ); \
-}
-
-static inline void XPROD31(int32_t  a, int32_t  b,
-			   int32_t  t, int32_t  v,
-			   int32_t *x, int32_t *y)
-{
-  int x1, y1, l;
-  asm(	"smull	%0, %1, %4, %6\n\t"
-	"smlal	%0, %1, %5, %7\n\t"
-	"rsb	%3, %4, #0\n\t"
-	"smull	%0, %2, %5, %6\n\t"
-	"smlal	%0, %2, %3, %7"
-	: "=&r" (l), "=&r" (x1), "=&r" (y1), "=r" (a)
-	: "3" (a), "r" (b), "r" (t), "r" (v)
-	: "cc" );
-  *x = x1 << 1;
-  MB();
-  *y = y1 << 1;
-}
-
-static inline void XNPROD31(int32_t  a, int32_t  b,
-			    int32_t  t, int32_t  v,
-			    int32_t *x, int32_t *y)
-{
-  int x1, y1, l;
-  asm(	"rsb	%2, %4, #0\n\t"
-	"smull	%0, %1, %3, %5\n\t"
-	"smlal	%0, %1, %2, %6\n\t"
-	"smull	%0, %2, %4, %5\n\t"
-	"smlal	%0, %2, %3, %6"
-	: "=&r" (l), "=&r" (x1), "=&r" (y1)
-	: "r" (a), "r" (b), "r" (t), "r" (v)
-	: "cc" );
-  *x = x1 << 1;
-  MB();
-  *y = y1 << 1;
-}
-
-#ifndef _V_VECT_OPS
-#define _V_VECT_OPS
-
-/* asm versions of vector operations for block.c, window.c */
-static inline
-void vect_add(int32_t *x, int32_t *y, int n)
-{
-  while (n>=4) {
-    asm volatile ("ldmia %[x], {r0, r1, r2, r3};"
-                  "ldmia %[y]!, {r4, r5, r6, r7};"
-                  "add r0, r0, r4;"
-                  "add r1, r1, r5;"
-                  "add r2, r2, r6;"
-                  "add r3, r3, r7;"
-                  "stmia %[x]!, {r0, r1, r2, r3};"
-                  : [x] "+r" (x), [y] "+r" (y)
-                  : : "r0", "r1", "r2", "r3",
-                  "r4", "r5", "r6", "r7",
-                  "memory");
-    n -= 4;
-  }
-  /* add final elements */
-  while (n>0) {
-    *x++ += *y++;
-    n--;
-  }
-}
-
-static inline
-void vect_copy(int32_t *x, int32_t *y, int n)
-{
-  while (n>=4) {
-    asm volatile ("ldmia %[y]!, {r0, r1, r2, r3};"
-                  "stmia %[x]!, {r0, r1, r2, r3};"
-                  : [x] "+r" (x), [y] "+r" (y)
-                  : : "r0", "r1", "r2", "r3",
-                  "memory");
-    n -= 4;
-  }
-  /* copy final elements */
-  while (n>0) {
-    *x++ = *y++;
-    n--;
-  }
-}
-
-static inline
-void vect_mult_fw(int32_t *data, int32_t *window, int n)
-{
-  while (n>=4) {
-    asm volatile ("ldmia %[d], {r0, r1, r2, r3};"
-                  "ldmia %[w]!, {r4, r5, r6, r7};"
-                  "smull r8, r9, r0, r4;"
-                  "mov   r0, r9, lsl #1;"
-                  "smull r8, r9, r1, r5;"
-                  "mov   r1, r9, lsl #1;"
-                  "smull r8, r9, r2, r6;"
-                  "mov   r2, r9, lsl #1;"
-                  "smull r8, r9, r3, r7;"
-                  "mov   r3, r9, lsl #1;"
-                  "stmia %[d]!, {r0, r1, r2, r3};"
-                  : [d] "+r" (data), [w] "+r" (window)
-                  : : "r0", "r1", "r2", "r3",
-                  "r4", "r5", "r6", "r7", "r8", "r9",
-                  "memory", "cc");
-    n -= 4;
-  }
-  while(n>0) {
-    *data = MULT31(*data, *window);
-    data++;
-    window++;
-    n--;
-  }
-}
-
-static inline
-void vect_mult_bw(int32_t *data, int32_t *window, int n)
-{
-  while (n>=4) {
-    asm volatile ("ldmia %[d], {r0, r1, r2, r3};"
-                  "ldmda %[w]!, {r4, r5, r6, r7};"
-                  "smull r8, r9, r0, r7;"
-                  "mov   r0, r9, lsl #1;"
-                  "smull r8, r9, r1, r6;"
-                  "mov   r1, r9, lsl #1;"
-                  "smull r8, r9, r2, r5;"
-                  "mov   r2, r9, lsl #1;"
-                  "smull r8, r9, r3, r4;"
-                  "mov   r3, r9, lsl #1;"
-                  "stmia %[d]!, {r0, r1, r2, r3};"
-                  : [d] "+r" (data), [w] "+r" (window)
-                  : : "r0", "r1", "r2", "r3",
-                  "r4", "r5", "r6", "r7", "r8", "r9",
-                  "memory", "cc");
-    n -= 4;
-  }
-  while(n>0) {
-    *data = MULT31(*data, *window);
-    data++;
-    window--;
-    n--;
-  }
-}
-#endif
-
-#endif
-
-#ifndef _V_CLIP_MATH
-#define _V_CLIP_MATH
-
-static inline int32_t CLIP_TO_15(int32_t x) {
-  int tmp;
-  asm volatile("subs	%1, %0, #32768\n\t"
-	       "movpl	%0, #0x7f00\n\t"
-	       "orrpl	%0, %0, #0xff\n"
-	       "adds	%1, %0, #32768\n\t"
-	       "movmi	%0, #0x8000"
-	       : "+r"(x),"=r"(tmp)
-	       :
-	       : "cc");
-  return(x);
-}
-
-#endif
+int32_t MULT32(int32_t x, int32_t y);
+int32_t MULT31(int32_t x, int32_t y);
+int32_t MULT31_SHIFT15(int32_t x, int32_t y);
+
+#define MB() 
+
+void XPROD32(int32_t a, int32_t b,
+	int32_t t, int32_t v,
+	int32_t *x, int32_t *y);
+void XPROD31(int32_t a, int32_t b,
+	int32_t t, int32_t v,
+	int32_t *x, int32_t *y);
+void XNPROD31(int32_t a, int32_t b, 
+	int32_t t, int32_t v,
+	int32_t *x, int32_t *y);
+
+int32_t CLIP_TO_15(int32_t x);
 
-#ifndef _V_LSP_MATH_ASM
-#define _V_LSP_MATH_ASM
 #endif
-
-#endif 

+ 316 - 459
bsp/stm32_radio/libwma/mdct2.c

@@ -40,479 +40,336 @@
 #include "codeclib.h"
 #include "asm_arm.h"
 
-#if defined(CPU_ARM) && CONFIG_CPU != S3C2440
-/* C code is faster on S3C2440 */
-
 extern void mdct_butterfly_32(int32_t *x);
 extern void mdct_butterfly_generic_loop(int32_t *x1, int32_t *x2,
-                                        const int32_t *T0, int step,
-                                        const int32_t *Ttop);
-
-static inline void mdct_butterfly_generic(int32_t *x,int points, int step){
-    mdct_butterfly_generic_loop(x + points, x + (points>>1),  sincos_lookup0, step, sincos_lookup0+1024);
-}
+	const int32_t *T0, int step,
+	const int32_t *Ttop);
 
-#else
-
-/* 8 point butterfly (in place) */
-static inline void mdct_butterfly_8(int32_t *x){
-  register int32_t r0   = x[4] + x[0];
-  register int32_t r1   = x[4] - x[0];
-  register int32_t r2   = x[5] + x[1];
-  register int32_t r3   = x[5] - x[1];
-  register int32_t r4   = x[6] + x[2];
-  register int32_t r5   = x[6] - x[2];
-  register int32_t r6   = x[7] + x[3];
-  register int32_t r7   = x[7] - x[3];
-
-           x[0] = r5   + r3;
-           x[1] = r7   - r1;
-           x[2] = r5   - r3;
-           x[3] = r7   + r1;
-           x[4] = r4   - r0;
-           x[5] = r6   - r2;
-           x[6] = r4   + r0;
-           x[7] = r6   + r2;
-           MB();
+static inline void mdct_butterfly_generic(int32_t *x,int points, int step)
+{
+	mdct_butterfly_generic_loop(x + points, x + (points>>1),  sincos_lookup0, step, sincos_lookup0+1024);
 }
 
-/* 16 point butterfly (in place, 4 register) */
-static inline void mdct_butterfly_16(int32_t *x){
-
-  register int32_t r0, r1;
-
-           r0 = x[ 0] - x[ 8]; x[ 8] += x[ 0];
-           r1 = x[ 1] - x[ 9]; x[ 9] += x[ 1];
-           x[ 0] = MULT31((r0 + r1) , cPI2_8);
-           x[ 1] = MULT31((r1 - r0) , cPI2_8);
-           MB();
+static inline void mdct_butterflies(int32_t *x,int points,int shift)
+{
+	int stages=8-shift;
+	int i,j;
 
-           r0 = x[10] - x[ 2]; x[10] += x[ 2];
-           r1 = x[ 3] - x[11]; x[11] += x[ 3];
-           x[ 2] = r1; x[ 3] = r0;
-           MB();
+	for(i=0;--stages>0;i++)
+	{
+		for(j=0;j<(1<<i);j++)
+			mdct_butterfly_generic(x+(points>>i)*j,points>>i,4<<(i+shift));
+	}
 
-           r0 = x[12] - x[ 4]; x[12] += x[ 4];
-           r1 = x[13] - x[ 5]; x[13] += x[ 5];
-           x[ 4] = MULT31((r0 - r1) , cPI2_8);
-           x[ 5] = MULT31((r0 + r1) , cPI2_8);
-           MB();
-
-           r0 = x[14] - x[ 6]; x[14] += x[ 6];
-           r1 = x[15] - x[ 7]; x[15] += x[ 7];
-           x[ 6] = r0; x[ 7] = r1;
-           MB();
-
-           mdct_butterfly_8(x);
-           mdct_butterfly_8(x+8);
-}
-
-/* 32 point butterfly (in place, 4 register) */
-static inline  void mdct_butterfly_32(int32_t *x){
-
-  register int32_t r0, r1;
-
-           r0 = x[30] - x[14]; x[30] += x[14];
-           r1 = x[31] - x[15]; x[31] += x[15];
-           x[14] = r0; x[15] = r1;
-           MB();
-
-           r0 = x[28] - x[12]; x[28] += x[12];
-           r1 = x[29] - x[13]; x[29] += x[13];
-           XNPROD31( r0, r1, cPI1_8, cPI3_8, &x[12], &x[13] );
-           MB();
-
-           r0 = x[26] - x[10]; x[26] += x[10];
-           r1 = x[27] - x[11]; x[27] += x[11];
-           x[10] = MULT31((r0 - r1) , cPI2_8);
-           x[11] = MULT31((r0 + r1) , cPI2_8);
-           MB();
-
-           r0 = x[24] - x[ 8]; x[24] += x[ 8];
-           r1 = x[25] - x[ 9]; x[25] += x[ 9];
-           XNPROD31( r0, r1, cPI3_8, cPI1_8, &x[ 8], &x[ 9] );
-           MB();
-
-           r0 = x[22] - x[ 6]; x[22] += x[ 6];
-           r1 = x[ 7] - x[23]; x[23] += x[ 7];
-           x[ 6] = r1; x[ 7] = r0;
-           MB();
-
-           r0 = x[ 4] - x[20]; x[20] += x[ 4];
-           r1 = x[ 5] - x[21]; x[21] += x[ 5];
-           XPROD31 ( r0, r1, cPI3_8, cPI1_8, &x[ 4], &x[ 5] );
-           MB();
-
-           r0 = x[ 2] - x[18]; x[18] += x[ 2];
-           r1 = x[ 3] - x[19]; x[19] += x[ 3];
-           x[ 2] = MULT31((r1 + r0) , cPI2_8);
-           x[ 3] = MULT31((r1 - r0) , cPI2_8);
-           MB();
-
-           r0 = x[ 0] - x[16]; x[16] += x[ 0];
-           r1 = x[ 1] - x[17]; x[17] += x[ 1];
-           XPROD31 ( r0, r1, cPI1_8, cPI3_8, &x[ 0], &x[ 1] );
-           MB();
-
-           mdct_butterfly_16(x);
-           mdct_butterfly_16(x+16);
-}
-
-/* N/stage point generic N stage butterfly (in place, 4 register) */
-void mdct_butterfly_generic(int32_t *x,int points, int step){
-  const int32_t *T   = sincos_lookup0;
-  int32_t *x1        = x + points      - 8;
-  int32_t *x2        = x + (points>>1) - 8;
-  register int32_t   r0;
-  register int32_t   r1;
-  register int32_t   r2;
-  register int32_t   r3;
-
-  do{
-    r0 = x1[6] - x2[6]; x1[6] += x2[6];
-    r1 = x2[7] - x1[7]; x1[7] += x2[7];
-    r2 = x1[4] - x2[4]; x1[4] += x2[4];
-    r3 = x2[5] - x1[5]; x1[5] += x2[5];
-    XPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T+=step;
-    XPROD31( r3, r2, T[0], T[1], &x2[4], &x2[5] ); T+=step;
-
-    r0 = x1[2] - x2[2]; x1[2] += x2[2];
-    r1 = x2[3] - x1[3]; x1[3] += x2[3];
-    r2 = x1[0] - x2[0]; x1[0] += x2[0];
-    r3 = x2[1] - x1[1]; x1[1] += x2[1];
-    XPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T+=step;
-    XPROD31( r3, r2, T[0], T[1], &x2[0], &x2[1] ); T+=step;
-
-    x1-=8; x2-=8;
-  }while(T<sincos_lookup0+1024);
-  do{
-    r0 = x1[6] - x2[6]; x1[6] += x2[6];
-    r1 = x1[7] - x2[7]; x1[7] += x2[7];
-    r2 = x1[4] - x2[4]; x1[4] += x2[4];
-    r3 = x1[5] - x2[5]; x1[5] += x2[5];
-    XNPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T-=step;
-    XNPROD31( r2, r3, T[0], T[1], &x2[4], &x2[5] ); T-=step;
-
-    r0 = x1[2] - x2[2]; x1[2] += x2[2];
-    r1 = x1[3] - x2[3]; x1[3] += x2[3];
-    r2 = x1[0] - x2[0]; x1[0] += x2[0];
-    r3 = x1[1] - x2[1]; x1[1] += x2[1];
-    XNPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T-=step;
-    XNPROD31( r2, r3, T[0], T[1], &x2[0], &x2[1] ); T-=step;
-
-    x1-=8; x2-=8;
-  }while(T>sincos_lookup0);
-  do{
-    r0 = x2[6] - x1[6]; x1[6] += x2[6];
-    r1 = x2[7] - x1[7]; x1[7] += x2[7];
-    r2 = x2[4] - x1[4]; x1[4] += x2[4];
-    r3 = x2[5] - x1[5]; x1[5] += x2[5];
-    XPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T+=step;
-    XPROD31( r2, r3, T[0], T[1], &x2[4], &x2[5] ); T+=step;
-
-    r0 = x2[2] - x1[2]; x1[2] += x2[2];
-    r1 = x2[3] - x1[3]; x1[3] += x2[3];
-    r2 = x2[0] - x1[0]; x1[0] += x2[0];
-    r3 = x2[1] - x1[1]; x1[1] += x2[1];
-    XPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T+=step;
-    XPROD31( r2, r3, T[0], T[1], &x2[0], &x2[1] ); T+=step;
-
-    x1-=8; x2-=8;
-  }while(T<sincos_lookup0+1024);
-  do{
-    r0 = x1[6] - x2[6]; x1[6] += x2[6];
-    r1 = x2[7] - x1[7]; x1[7] += x2[7];
-    r2 = x1[4] - x2[4]; x1[4] += x2[4];
-    r3 = x2[5] - x1[5]; x1[5] += x2[5];
-    XNPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T-=step;
-    XNPROD31( r3, r2, T[0], T[1], &x2[4], &x2[5] ); T-=step;
-
-    r0 = x1[2] - x2[2]; x1[2] += x2[2];
-    r1 = x2[3] - x1[3]; x1[3] += x2[3];
-    r2 = x1[0] - x2[0]; x1[0] += x2[0];
-    r3 = x2[1] - x1[1]; x1[1] += x2[1];
-    XNPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T-=step;
-    XNPROD31( r3, r2, T[0], T[1], &x2[0], &x2[1] ); T-=step;
-
-    x1-=8; x2-=8;
-  }while(T>sincos_lookup0);
-}
-
-#endif /* CPU_ARM */
-
-static inline void mdct_butterflies(int32_t *x,int points,int shift) {
-
-  int stages=8-shift;
-  int i,j;
-
-  for(i=0;--stages>0;i++){
-    for(j=0;j<(1<<i);j++)
-      mdct_butterfly_generic(x+(points>>i)*j,points>>i,4<<(i+shift));
-  }
-
-  for(j=0;j<points;j+=32)
-    mdct_butterfly_32(x+j);
+	for(j=0;j<points;j+=32)
+		mdct_butterfly_32(x+j);
 }
 
 
 static const unsigned char bitrev[16]=
-  {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
+	{
+		0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15
+	};
 
-static inline int bitrev12(int x){
-  return bitrev[x>>8]|(bitrev[(x&0x0f0)>>4]<<4)|(((int)bitrev[x&0x00f])<<8);
+static inline int bitrev12(int x)
+{
+	return bitrev[x>>8]|(bitrev[(x&0x0f0)>>4]<<4)|(((int)bitrev[x&0x00f])<<8);
 }
 
-static inline void mdct_bitreverse(int32_t *x,int n,int step,int shift) {
-
-  int          bit   = 0;
-  int32_t   *w0    = x;
-  int32_t   *w1    = x = w0+(n>>1);
-  const int32_t    *T = (step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
-  const int32_t    *Ttop  = T+1024;
-  register int32_t    r2;
-
-  do{
-    register int32_t r3      = bitrev12(bit++);
-    int32_t *x0    = x + ((r3 ^ 0xfff)>>shift) -1;
-    int32_t *x1    = x + (r3>>shift);
-
-    register int32_t  r0     = x0[0]  + x1[0];
-    register int32_t  r1     = x1[1]  - x0[1];
-
-              XPROD32( r0, r1, T[1], T[0], r2, r3 ); T+=step;
-
-              w1    -= 4;
-
-              r0     = (x0[1] + x1[1])>>1;
-              r1     = (x0[0] - x1[0])>>1;
-              w0[0]  = r0     + r2;
-              w0[1]  = r1     + r3;
-              w1[2]  = r0     - r2;
-              w1[3]  = r3     - r1;
-
-              r3     = bitrev12(bit++);
-              x0     = x + ((r3 ^ 0xfff)>>shift) -1;
-              x1     = x + (r3>>shift);
-
-              r0     = x0[0]  + x1[0];
-              r1     = x1[1]  - x0[1];
-
-              XPROD32( r0, r1, T[1], T[0], r2, r3 ); T+=step;
-
-              r0     = (x0[1] + x1[1])>>1;
-              r1     = (x0[0] - x1[0])>>1;
-              w0[2]  = r0     + r2;
-              w0[3]  = r1     + r3;
-              w1[0]  = r0     - r2;
-              w1[1]  = r3     - r1;
-
-              w0    += 4;
-  }while(T<Ttop);
-
-  do{
-    register int32_t r3     = bitrev12(bit++);
-    int32_t *x0    = x + ((r3 ^ 0xfff)>>shift) -1;
-    int32_t *x1    = x + (r3>>shift);
-
-    register int32_t  r0     = x0[0]  + x1[0];
-    register int32_t  r1     = x1[1]  - x0[1];
-
-              T-=step; XPROD32( r0, r1, T[0], T[1], r2, r3 );
-
-              w1    -= 4;
-
-              r0     = (x0[1] + x1[1])>>1;
-              r1     = (x0[0] - x1[0])>>1;
-              w0[0]  = r0     + r2;
-              w0[1]  = r1     + r3;
-              w1[2]  = r0     - r2;
-              w1[3]  = r3     - r1;
-
-              r3     = bitrev12(bit++);
-              x0     = x + ((r3 ^ 0xfff)>>shift) -1;
-              x1     = x + (r3>>shift);
-
-              r0     = x0[0]  + x1[0];
-              r1     = x1[1]  - x0[1];
-
-              T-=step; XPROD32( r0, r1, T[0], T[1], r2, r3 );
-
-              r0     = (x0[1] + x1[1])>>1;
-              r1     = (x0[0] - x1[0])>>1;
-              w0[2]  = r0     + r2;
-              w0[3]  = r1     + r3;
-              w1[0]  = r0     - r2;
-              w1[1]  = r3     - r1;
-
-              w0    += 4;
-  }while(w0<w1);
+static inline void mdct_bitreverse(int32_t *x,int n,int step,int shift)
+{
+	int          bit   = 0;
+	int32_t   *w0    = x;
+	int32_t   *w1    = x = w0+(n>>1);
+	const int32_t    *T = (step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
+	const int32_t    *Ttop  = T+1024;
+	int32_t    r2;
+
+	do
+	{
+		int32_t r3      = bitrev12(bit++);
+		int32_t *x0    = x + ((r3 ^ 0xfff)>>shift) -1;
+		int32_t *x1    = x + (r3>>shift);
+
+		register int32_t  r0     = x0[0]  + x1[0];
+		register int32_t  r1     = x1[1]  - x0[1];
+
+		XPROD32( r0, r1, T[1], T[0], &r2, &r3 );
+		T+=step;
+
+		w1    -= 4;
+
+		r0     = (x0[1] + x1[1])>>1;
+		r1     = (x0[0] - x1[0])>>1;
+		w0[0]  = r0     + r2;
+		w0[1]  = r1     + r3;
+		w1[2]  = r0     - r2;
+		w1[3]  = r3     - r1;
+
+		r3     = bitrev12(bit++);
+		x0     = x + ((r3 ^ 0xfff)>>shift) -1;
+		x1     = x + (r3>>shift);
+
+		r0     = x0[0]  + x1[0];
+		r1     = x1[1]  - x0[1];
+
+		XPROD32( r0, r1, T[1], T[0], &r2, &r3 );
+		T+=step;
+
+		r0     = (x0[1] + x1[1])>>1;
+		r1     = (x0[0] - x1[0])>>1;
+		w0[2]  = r0     + r2;
+		w0[3]  = r1     + r3;
+		w1[0]  = r0     - r2;
+		w1[1]  = r3     - r1;
+
+		w0    += 4;
+	}
+	while(T<Ttop);
+
+	do
+	{
+		int32_t r3     = bitrev12(bit++);
+		int32_t *x0    = x + ((r3 ^ 0xfff)>>shift) -1;
+		int32_t *x1    = x + (r3>>shift);
+
+		register int32_t  r0     = x0[0]  + x1[0];
+		register int32_t  r1     = x1[1]  - x0[1];
+
+		T-=step;
+		XPROD32( r0, r1, T[0], T[1], &r2, &r3 );
+
+		w1    -= 4;
+
+		r0     = (x0[1] + x1[1])>>1;
+		r1     = (x0[0] - x1[0])>>1;
+		w0[0]  = r0     + r2;
+		w0[1]  = r1     + r3;
+		w1[2]  = r0     - r2;
+		w1[3]  = r3     - r1;
+
+		r3     = bitrev12(bit++);
+		x0     = x + ((r3 ^ 0xfff)>>shift) -1;
+		x1     = x + (r3>>shift);
+
+		r0     = x0[0]  + x1[0];
+		r1     = x1[1]  - x0[1];
+
+		T-=step;
+		XPROD32( r0, r1, T[0], T[1], &r2, &r3 );
+
+		r0     = (x0[1] + x1[1])>>1;
+		r1     = (x0[0] - x1[0])>>1;
+		w0[2]  = r0     + r2;
+		w0[3]  = r1     + r3;
+		w1[0]  = r0     - r2;
+		w1[1]  = r3     - r1;
+
+		w0    += 4;
+	}
+	while(w0<w1);
 }
 
-void mdct_backward(int n, int32_t *in, int32_t *out) {
-  int n2=n>>1;
-  int n4=n>>2;
-  int32_t *iX;
-  int32_t *oX;
-  const int32_t *T;
-  const int32_t *V;
-  int shift;
-  int step;
-  for (shift=6;!(n&(1<<shift));shift++);
-  shift=13-shift;
-  step=2<<shift;
-
-  /* rotate */
-
-  iX            = in+n2-7;
-  oX            = out+n2+n4;
-  T             = sincos_lookup0;
-
-  do{
-    oX-=4;
-    XPROD31( iX[4], iX[6], T[0], T[1], &oX[2], &oX[3] ); T+=step;
-    XPROD31( iX[0], iX[2], T[0], T[1], &oX[0], &oX[1] ); T+=step;
-    iX-=8;
-  }while(iX>=in+n4);
-  do{
-    oX-=4;
-    XPROD31( iX[4], iX[6], T[1], T[0], &oX[2], &oX[3] ); T-=step;
-    XPROD31( iX[0], iX[2], T[1], T[0], &oX[0], &oX[1] ); T-=step;
-    iX-=8;
-  }while(iX>=in);
-
-  iX            = in+n2-8;
-  oX            = out+n2+n4;
-  T             = sincos_lookup0;
-
-  do{
-    T+=step; XNPROD31( iX[6], iX[4], T[0], T[1], &oX[0], &oX[1] );
-    T+=step; XNPROD31( iX[2], iX[0], T[0], T[1], &oX[2], &oX[3] );
-    iX-=8;
-    oX+=4;
-  }while(iX>=in+n4);
-  do{
-    T-=step; XNPROD31( iX[6], iX[4], T[1], T[0], &oX[0], &oX[1] );
-    T-=step; XNPROD31( iX[2], iX[0], T[1], T[0], &oX[2], &oX[3] );
-    iX-=8;
-    oX+=4;
-  }while(iX>=in);
-
-  mdct_butterflies(out+n2,n2,shift);
-  mdct_bitreverse(out,n,step,shift);
-  /* rotate + window */
-
-  step>>=2;
-  {
-    int32_t *oX1=out+n2+n4;
-    int32_t *oX2=out+n2+n4;
-    int32_t *iX =out;
-
-    switch(step) {
-      default: {
-        T=(step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
-        do{
-          oX1-=4;
-          XPROD31( iX[0], -iX[1], T[0], T[1], &oX1[3], &oX2[0] ); T+=step;
-          XPROD31( iX[2], -iX[3], T[0], T[1], &oX1[2], &oX2[1] ); T+=step;
-          XPROD31( iX[4], -iX[5], T[0], T[1], &oX1[1], &oX2[2] ); T+=step;
-          XPROD31( iX[6], -iX[7], T[0], T[1], &oX1[0], &oX2[3] ); T+=step;
-          oX2+=4;
-          iX+=8;
-        }while(iX<oX1);
-        break;
-      }
-
-      case 1: {
-        /* linear interpolation between table values: offset=0.5, step=1 */
-        register int32_t  t0,t1,v0,v1;
-        T         = sincos_lookup0;
-        V         = sincos_lookup1;
-        t0        = (*T++)>>1;
-        t1        = (*T++)>>1;
-        do{
-          oX1-=4;
-
-          t0 += (v0 = (*V++)>>1);
-          t1 += (v1 = (*V++)>>1);
-          XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] );
-          v0 += (t0 = (*T++)>>1);
-          v1 += (t1 = (*T++)>>1);
-          XPROD31( iX[2], -iX[3], v0, v1, &oX1[2], &oX2[1] );
-          t0 += (v0 = (*V++)>>1);
-          t1 += (v1 = (*V++)>>1);
-          XPROD31( iX[4], -iX[5], t0, t1, &oX1[1], &oX2[2] );
-          v0 += (t0 = (*T++)>>1);
-          v1 += (t1 = (*T++)>>1);
-          XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] );
-
-          oX2+=4;
-          iX+=8;
-        }while(iX<oX1);
-        break;
-      }
-
-      case 0: {
-        /* linear interpolation between table values: offset=0.25, step=0.5 */
-        register int32_t  t0,t1,v0,v1,q0,q1;
-        T         = sincos_lookup0;
-        V         = sincos_lookup1;
-        t0        = *T++;
-        t1        = *T++;
-        do{
-          oX1-=4;
-
-          v0  = *V++;
-          v1  = *V++;
-          t0 +=  (q0 = (v0-t0)>>2);
-          t1 +=  (q1 = (v1-t1)>>2);
-          XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] );
-          t0  = v0-q0;
-          t1  = v1-q1;
-          XPROD31( iX[2], -iX[3], t0, t1, &oX1[2], &oX2[1] );
-
-          t0  = *T++;
-          t1  = *T++;
-          v0 += (q0 = (t0-v0)>>2);
-          v1 += (q1 = (t1-v1)>>2);
-          XPROD31( iX[4], -iX[5], v0, v1, &oX1[1], &oX2[2] );
-          v0  = t0-q0;
-          v1  = t1-q1;
-          XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] );
-
-          oX2+=4;
-          iX+=8;
-        }while(iX<oX1);
-        break;
-      }
-    }
-
-    iX=out+n2+n4;
-    oX1=out+n4;
-    oX2=oX1;
-
-    do{
-      oX1-=4;
-      iX-=4;
-
-      oX2[0] = -(oX1[3] = iX[3]);
-      oX2[1] = -(oX1[2] = iX[2]);
-      oX2[2] = -(oX1[1] = iX[1]);
-      oX2[3] = -(oX1[0] = iX[0]);
-
-      oX2+=4;
-    }while(oX2<iX);
-
-    iX=out+n2+n4;
-    oX1=out+n2+n4;
-    oX2=out+n2;
-
-    do{
-      oX1-=4;
-      oX1[0]= iX[3];
-      oX1[1]= iX[2];
-      oX1[2]= iX[1];
-      oX1[3]= iX[0];
-      iX+=4;
-    }while(oX1>oX2);
-  }
+void mdct_backward(int n, int32_t *in, int32_t *out)
+{
+	int n2=n>>1;
+	int n4=n>>2;
+	int32_t *iX;
+	int32_t *oX;
+	const int32_t *T;
+	const int32_t *V;
+	int shift;
+	int step;
+	for (shift=6;!(n&(1<<shift));shift++);
+	shift=13-shift;
+	step=2<<shift;
+
+	/* rotate */
+
+	iX            = in+n2-7;
+	oX            = out+n2+n4;
+	T             = sincos_lookup0;
+
+	do
+	{
+		oX-=4;
+		XPROD31( iX[4], iX[6], T[0], T[1], &oX[2], &oX[3] );
+		T+=step;
+		XPROD31( iX[0], iX[2], T[0], T[1], &oX[0], &oX[1] );
+		T+=step;
+		iX-=8;
+	}
+	while(iX>=in+n4);
+	do
+	{
+		oX-=4;
+		XPROD31( iX[4], iX[6], T[1], T[0], &oX[2], &oX[3] );
+		T-=step;
+		XPROD31( iX[0], iX[2], T[1], T[0], &oX[0], &oX[1] );
+		T-=step;
+		iX-=8;
+	}
+	while(iX>=in);
+
+	iX            = in+n2-8;
+	oX            = out+n2+n4;
+	T             = sincos_lookup0;
+
+	do
+	{
+		T+=step;
+		XNPROD31( iX[6], iX[4], T[0], T[1], &oX[0], &oX[1] );
+		T+=step;
+		XNPROD31( iX[2], iX[0], T[0], T[1], &oX[2], &oX[3] );
+		iX-=8;
+		oX+=4;
+	}
+	while(iX>=in+n4);
+	do
+	{
+		T-=step;
+		XNPROD31( iX[6], iX[4], T[1], T[0], &oX[0], &oX[1] );
+		T-=step;
+		XNPROD31( iX[2], iX[0], T[1], T[0], &oX[2], &oX[3] );
+		iX-=8;
+		oX+=4;
+	}
+	while(iX>=in);
+
+	mdct_butterflies(out+n2,n2,shift);
+	mdct_bitreverse(out,n,step,shift);
+	/* rotate + window */
+
+	step>>=2;
+	{
+		int32_t *oX1=out+n2+n4;
+		int32_t *oX2=out+n2+n4;
+		int32_t *iX =out;
+
+		switch(step)
+		{
+		default:
+		{
+			T=(step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
+			do
+			{
+				oX1-=4;
+				XPROD31( iX[0], -iX[1], T[0], T[1], &oX1[3], &oX2[0] );
+				T+=step;
+				XPROD31( iX[2], -iX[3], T[0], T[1], &oX1[2], &oX2[1] );
+				T+=step;
+				XPROD31( iX[4], -iX[5], T[0], T[1], &oX1[1], &oX2[2] );
+				T+=step;
+				XPROD31( iX[6], -iX[7], T[0], T[1], &oX1[0], &oX2[3] );
+				T+=step;
+				oX2+=4;
+				iX+=8;
+			}
+			while(iX<oX1);
+			break;
+		}
+
+		case 1:
+		{
+			/* linear interpolation between table values: offset=0.5, step=1 */
+			register int32_t  t0,t1,v0,v1;
+			T         = sincos_lookup0;
+			V         = sincos_lookup1;
+			t0        = (*T++)>>1;
+			t1        = (*T++)>>1;
+			do
+			{
+				oX1-=4;
+
+				t0 += (v0 = (*V++)>>1);
+				t1 += (v1 = (*V++)>>1);
+				XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] );
+				v0 += (t0 = (*T++)>>1);
+				v1 += (t1 = (*T++)>>1);
+				XPROD31( iX[2], -iX[3], v0, v1, &oX1[2], &oX2[1] );
+				t0 += (v0 = (*V++)>>1);
+				t1 += (v1 = (*V++)>>1);
+				XPROD31( iX[4], -iX[5], t0, t1, &oX1[1], &oX2[2] );
+				v0 += (t0 = (*T++)>>1);
+				v1 += (t1 = (*T++)>>1);
+				XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] );
+
+				oX2+=4;
+				iX+=8;
+			}
+			while(iX<oX1);
+			break;
+		}
+
+		case 0:
+		{
+			/* linear interpolation between table values: offset=0.25, step=0.5 */
+			register int32_t  t0,t1,v0,v1,q0,q1;
+			T         = sincos_lookup0;
+			V         = sincos_lookup1;
+			t0        = *T++;
+			t1        = *T++;
+			do
+			{
+				oX1-=4;
+
+				v0  = *V++;
+				v1  = *V++;
+				t0 +=  (q0 = (v0-t0)>>2);
+				t1 +=  (q1 = (v1-t1)>>2);
+				XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] );
+				t0  = v0-q0;
+				t1  = v1-q1;
+				XPROD31( iX[2], -iX[3], t0, t1, &oX1[2], &oX2[1] );
+
+				t0  = *T++;
+				t1  = *T++;
+				v0 += (q0 = (t0-v0)>>2);
+				v1 += (q1 = (t1-v1)>>2);
+				XPROD31( iX[4], -iX[5], v0, v1, &oX1[1], &oX2[2] );
+				v0  = t0-q0;
+				v1  = t1-q1;
+				XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] );
+
+				oX2+=4;
+				iX+=8;
+			}
+			while(iX<oX1);
+			break;
+		}
+		}
+
+		iX=out+n2+n4;
+		oX1=out+n4;
+		oX2=oX1;
+
+		do
+		{
+			oX1-=4;
+			iX-=4;
+
+			oX2[0] = -(oX1[3] = iX[3]);
+			oX2[1] = -(oX1[2] = iX[2]);
+			oX2[2] = -(oX1[1] = iX[1]);
+			oX2[3] = -(oX1[0] = iX[0]);
+
+			oX2+=4;
+		}
+		while(oX2<iX);
+
+		iX=out+n2+n4;
+		oX1=out+n2+n4;
+		oX2=out+n2;
+
+		do
+		{
+			oX1-=4;
+			oX1[0]= iX[3];
+			oX1[1]= iX[2];
+			oX1[2]= iX[1];
+			oX1[3]= iX[0];
+			iX+=4;
+		}
+		while(oX1>oX2);
+	}
 }

+ 415 - 0
bsp/stm32_radio/libwma/mdct_arm.S

@@ -0,0 +1,415 @@
+cPI3_8 EQU 0x30fbc54d
+cPI2_8 EQU 0x5a82799a
+cPI1_8 EQU 0x7641af3d
+
+	AREA |.text|, CODE, READONLY, ALIGN=2
+	THUMB
+	REQUIRE8
+	PRESERVE8
+
+mdct_butterfly_8	PROC
+    add     r9,  r5,  r1                ; x4 + x0
+    sub     r5,  r5,  r1                ; x4 - x0
+    add     r7,  r6,  r2                ; x5 + x1
+    sub     r6,  r6,  r2                ; x5 - x1
+    add     r8,  r10, r3                ; x6 + x2
+    sub     r10, r10, r3                ; x6 - x2
+    add     r12, r11, r4                ; x7 + x3
+    sub     r11, r11, r4                ; x7 - x3
+
+    add     r1,  r10, r6                ; y0 = (x6 - x2) + (x5 - x1)
+    sub     r2,  r11, r5                ; y1 = (x7 - x3) - (x4 - x0)
+    sub     r3,  r10, r6                ; y2 = (x6 - x2) - (x5 - x1)
+    add     r4,  r11, r5                ; y3 = (x7 - x3) + (x4 - x0)
+    sub     r5,  r8,  r9                ; y4 = (x6 + x2) - (x4 + x0)
+    sub     r6,  r12, r7                ; y5 = (x7 + x3) - (x5 + x1)
+    add     r10, r8,  r9                ; y6 = (x6 + x2) + (x4 + x0)
+    add     r11, r12, r7                ; y7 = (x7 + x3) + (x5 + x1)
+    stmia   r0, {r1, r2, r3, r4, r5, r6, r10, r11}
+
+	bx		lr
+	
+	ENDP
+
+mdct_butterfly_16	PROC
+    str     lr, [sp, #-4]!
+    add     r1, r0, #8*4
+
+    ldmia   r0, {r2, r3, r4, r5}
+    ldmia   r1, {r6, r7, r8, r9}
+    add     r6, r6, r2                  ; y8 = x8 + x0
+    rsb     r2, r6, r2, lsl #1          ; x0 - x8
+    add     r7, r7, r3                  ; y9 = x9 + x1
+    rsb     r3, r7, r3, lsl #1          ; x1 - x9
+    add     r8, r8, r4                  ; y10 = x10 + x2
+    sub     r11, r8, r4, lsl #1         ; x10 - x2
+    add     r9, r9, r5                  ; y11 = x11 + x3
+    rsb     r10, r9, r5, lsl #1         ; x3 - x11
+
+    stmia   r1!, {r6, r7, r8, r9}
+
+    add     r2, r2, r3                  ; (x0 - x8) + (x1 - x9)
+    rsb     r3, r2, r3, lsl #1          ; (x1 - x9) - (x0 - x8)
+
+    ldr     r12, =cPI2_8
+    smull   r8, r5, r12, r2
+    smull   r8, r6, r12, r3
+    mov     r5, r5, lsl #1
+    mov     r6, r6, lsl #1
+
+    stmia   r0!, {r5, r6, r10, r11}
+
+    ldmia   r0, {r2, r3, r4, r5}
+    ldmia   r1, {r6, r7, r8, r9}
+    add     r6, r6, r2                  ; y12 = x12 + x4
+    sub     r2, r6, r2, lsl #1          ; x12 - x4
+    add     r7, r7, r3                  ; y13 = x13 + x5
+    sub     r3, r7, r3, lsl #1          ; x13 - x5
+    add     r8, r8, r4                  ; y10 = x14 + x6
+    sub     r10, r8, r4, lsl #1         ; x14 - x6
+    add     r9, r9, r5                  ; y11 = x15 + x7
+    sub     r11, r9, r5, lsl #1         ; x15 - x7
+
+    stmia   r1, {r6, r7, r8, r9}
+
+    sub     r2, r2, r3                  ; (x12 - x4) - (x13 - x5)
+    add     r3, r2, r3, lsl #1          ; (x12 - x4) + (x13 - x5)
+
+    smull   r8, r5, r12, r2
+    smull   r8, r6, r12, r3
+    mov     r5, r5, lsl #1
+    mov     r6, r6, lsl #1
+    ; no stmia here, r5, r6, r10, r11 are passed to mdct_butterfly_8
+
+    sub     r0, r0, #4*4
+    ldmia   r0, {r1, r2, r3, r4}
+    bl      mdct_butterfly_8
+    add     r0, r0, #8*4
+    ldmia   r0, {r1, r2, r3, r4, r5, r6, r10, r11}
+    bl      mdct_butterfly_8
+
+    ldr     pc, [sp], #4
+
+	ENDP
+
+mdct_butterfly_32	PROC
+	EXPORT mdct_butterfly_32
+
+    stmdb   sp!, {r4-r11, lr}
+
+    add     r1, r0, #16*4
+
+    ldmia   r0, {r2, r3, r4, r5}
+    ldmia   r1, {r6, r7, r8, r9}
+    add     r6, r6, r2                  ; y16 = x16 + x0
+    rsb     r2, r6, r2, lsl #1          ; x0 - x16
+    add     r7, r7, r3                  ; y17 = x17 + x1
+    rsb     r3, r7, r3, lsl #1          ; x1 - x17
+    add     r8, r8, r4                  ; y18 = x18 + x2
+    rsb     r4, r8, r4, lsl #1          ; x2 - x18
+    add     r9, r9, r5                  ; y19 = x19 + x3
+    rsb     r5, r9, r5, lsl #1          ; x3 - x19
+
+    stmia   r1!, {r6, r7, r8, r9}
+
+    ldr     r12, =cPI1_8
+    ldr     lr, =cPI3_8
+    smull   r10, r6, r12, r2
+    rsb     r2, r2, #0
+    smlal   r10, r6, lr, r3
+    smull   r10, r7, r12, r3
+    smlal   r10, r7, lr, r2
+    mov     r6, r6, lsl #1
+    mov     r7, r7, lsl #1
+
+    add     r4, r4, r5                  ; (x3 - x19) + (x2 - x18)
+    rsb     r5, r4, r5, lsl #1          ; (x3 - x19) - (x2 - x18)
+
+    ldr     r11, =cPI2_8
+    smull   r10, r8, r4, r11
+    smull   r10, r9, r5, r11
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+
+    stmia   r0!, {r6, r7, r8, r9}
+
+    ldmia   r0, {r2, r3, r4, r5}
+    ldmia   r1, {r6, r7, r8, r9}
+    add     r6, r6, r2                  ; y20 = x20 + x4
+    rsb     r2, r6, r2, lsl #1          ; x4 - x20
+    add     r7, r7, r3                  ; y21 = x21 + x5
+    rsb     r3, r7, r3, lsl #1          ; x5 - x21
+    add     r8, r8, r4                  ; y22 = x22 + x6
+    sub     r4, r8, r4, lsl #1          ; x22 - x6
+    add     r9, r9, r5                  ; y23 = x23 + x7
+    rsb     r5, r9, r5, lsl #1          ; x7 - x23
+
+    stmia   r1!, {r6, r7, r8, r9}
+
+    smull   r10, r6, lr, r2
+    rsb     r2, r2, #0
+    smlal   r10, r6, r12, r3
+    smull   r10, r7, lr, r3
+    smlal   r10, r7, r12, r2
+    mov     r6, r6, lsl #1
+    mov     r7, r7, lsl #1
+
+    mov     r8, r5
+    mov     r9, r4
+    stmia   r0!, {r6, r7, r8, r9}
+
+    ldmia   r0, {r2, r3, r4, r5}
+    ldmia   r1, {r6, r7, r8, r9}
+    add     r6, r6, r2                  ; y24 = x24 + x8
+    sub     r2, r6, r2, lsl #1          ; x24 - x8
+    add     r7, r7, r3                  ; y25 = x25 + x9
+    sub     r3, r7, r3, lsl #1          ; x25 - x9
+    add     r8, r8, r4                  ; y26 = x26 + x10
+    sub     r4, r8, r4, lsl #1          ; x26 - x10
+    add     r9, r9, r5                  ; y27 = x27 + x11
+    sub     r5, r9, r5, lsl #1          ; x27 - x11
+
+    stmia   r1!, {r6, r7, r8, r9}
+
+    smull   r10, r7, lr, r3
+    rsb     r3, r3, #0
+    smlal   r10, r7, r12, r2
+    smull   r10, r6, r12, r3
+    smlal   r10, r6, lr, r2
+    mov     r6, r6, lsl #1
+    mov     r7, r7, lsl #1
+
+    sub     r4, r4, r5                  ; (x26 - x10) - (x27 - x11)
+    add     r5, r4, r5, lsl #1          ; (x26 - x10) + (x27 - x11)
+
+    ldr     r11, =cPI2_8
+    smull   r10, r8, r11, r4
+    smull   r10, r9, r11, r5
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+
+    stmia   r0!, {r6, r7, r8, r9}
+
+    ldmia   r0, {r2, r3, r4, r5}
+    ldmia   r1, {r6, r7, r8, r9}
+    add     r6, r6, r2                  ; y28 = x28 + x12
+    sub     r2, r6, r2, lsl #1          ; x28 - x12
+    add     r7, r7, r3                  ; y29 = x29 + x13
+    sub     r3, r7, r3, lsl #1          ; x29 - x13
+    add     r8, r8, r4                  ; y30 = x30 + x14
+    sub     r4, r8, r4, lsl #1          ; x30 - x14
+    add     r9, r9, r5                  ; y31 = x31 + x15
+    sub     r5, r9, r5, lsl #1          ; x31 - x15
+
+    stmia   r1, {r6, r7, r8, r9}
+
+    smull   r10, r7, r12, r3
+    rsb     r3, r3, #0
+    smlal   r10, r7, lr, r2
+    smull   r10, r6, lr, r3
+    smlal   r10, r6, r12, r2
+    mov     r6, r6, lsl #1
+    mov     r7, r7, lsl #1
+
+    mov     r8, r4
+    mov     r9, r5
+    stmia   r0, {r6, r7, r8, r9}
+
+    sub     r0, r0, #12*4
+    str     r0, [sp, #-4]!
+    bl      mdct_butterfly_16
+
+    ldr     r0, [sp], #4
+    add     r0, r0, #16*4
+    bl      mdct_butterfly_16
+
+    ldmia   sp!, {r4-r11, pc}
+
+    ENDP
+
+    ; mdct_butterfly_generic_loop(x1, x2, T0, step, Ttop)
+mdct_butterfly_generic_loop PROC
+	EXPORT mdct_butterfly_generic_loop
+    stmdb   sp!, {r4-r11, lr}
+    str     r2, [sp, #-4]
+    ldr     r4, [sp, #36]
+
+label_1
+    ldmdb   r0, {r6, r7, r8, r9}
+    ldmdb   r1, {r10, r11, r12, r14}
+
+    add     r6, r6, r10
+    sub     r10, r6, r10, lsl #1
+    add     r7, r7, r11
+    rsb     r11, r7, r11, lsl #1
+    add     r8, r8, r12
+    sub     r12, r8, r12, lsl #1
+    add     r9, r9, r14
+    rsb     r14, r9, r14, lsl #1
+
+    stmdb   r0!, {r6, r7, r8, r9}
+
+    ldmia   r2, {r6, r7}
+    smull   r5, r8, r6, r14
+    rsb     r14, r14, #0
+    smlal   r5, r8, r7, r12
+    smull   r5, r9, r6, r12
+    smlal   r5, r9, r7, r14
+
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+    stmdb   r1!, {r8, r9}
+    add     r2, r2, r3, lsl #2
+
+    ldmia   r2, {r6, r7}
+    smull   r5, r8, r6, r11
+    rsb     r11, r11, #0
+    smlal   r5, r8, r7, r10
+    smull   r5, r9, r6, r10
+    smlal   r5, r9, r7, r11
+
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+    stmdb   r1!, {r8, r9}
+    add     r2, r2, r3, lsl #2
+
+    cmp     r2, r4
+    blo     label_1
+
+    ldr     r4, [sp, #-4]
+
+label_2
+    ldmdb   r0, {r6, r7, r8, r9}
+    ldmdb   r1, {r10, r11, r12, r14}
+
+    add     r6, r6, r10
+    sub     r10, r6, r10, lsl #1
+    add     r7, r7, r11
+    sub     r11, r7, r11, lsl #1
+    add     r8, r8, r12
+    sub     r12, r8, r12, lsl #1
+    add     r9, r9, r14
+    sub     r14, r9, r14, lsl #1
+
+    stmdb   r0!, {r6, r7, r8, r9}
+
+    ldmia   r2, {r6, r7}
+    smull   r5, r9, r6, r14
+    rsb     r14, r14, #0
+    smlal   r5, r9, r7, r12
+    smull   r5, r8, r6, r12
+    smlal   r5, r8, r7, r14
+
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+    stmdb   r1!, {r8, r9}
+    sub     r2, r2, r3, lsl #2
+
+    ldmia   r2, {r6, r7}
+    smull   r5, r9, r6, r11
+    rsb     r11, r11, #0
+    smlal   r5, r9, r7, r10
+    smull   r5, r8, r6, r10
+    smlal   r5, r8, r7, r11
+
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+    stmdb   r1!, {r8, r9}
+    sub     r2, r2, r3, lsl #2
+
+    cmp     r2, r4
+    bhi     label_2
+
+    ldr     r4, [sp, #36]
+
+label_3
+    ldmdb   r0, {r6, r7, r8, r9}
+    ldmdb   r1, {r10, r11, r12, r14}
+
+    add     r6, r6, r10
+    rsb     r10, r6, r10, lsl #1
+    add     r7, r7, r11
+    rsb     r11, r7, r11, lsl #1
+    add     r8, r8, r12
+    rsb     r12, r8, r12, lsl #1
+    add     r9, r9, r14
+    rsb     r14, r9, r14, lsl #1
+
+    stmdb   r0!, {r6, r7, r8, r9}
+
+    ldmia   r2, {r6, r7}
+    smull   r5, r8, r6, r12
+    rsb     r12, r12, #0
+    smlal   r5, r8, r7, r14
+    smull   r5, r9, r6, r14
+    smlal   r5, r9, r7, r12
+
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+    stmdb   r1!, {r8, r9}
+    add     r2, r2, r3, lsl #2
+
+    ldmia   r2, {r6, r7}
+    smull   r5, r8, r6, r10
+    rsb     r10, r10, #0
+    smlal   r5, r8, r7, r11
+    smull   r5, r9, r6, r11
+    smlal   r5, r9, r7, r10
+
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+    stmdb   r1!, {r8, r9}
+    add     r2, r2, r3, lsl #2
+
+    cmp     r2, r4
+    blo     label_3
+
+    ldr     r4, [sp, #-4]
+
+label_4
+    ldmdb   r0, {r6, r7, r8, r9}
+    ldmdb   r1, {r10, r11, r12, r14}
+
+    add     r6, r6, r10
+    sub     r10, r6, r10, lsl #1
+    add     r7, r7, r11
+    rsb     r11, r7, r11, lsl #1
+    add     r8, r8, r12
+    sub     r12, r8, r12, lsl #1
+    add     r9, r9, r14
+    rsb     r14, r9, r14, lsl #1
+
+    stmdb   r0!, {r6, r7, r8, r9}
+
+    ldmia   r2, {r6, r7}
+    smull   r5, r9, r6, r12
+    smlal   r5, r9, r7, r14
+    rsb     r12, r12, #0
+    smull   r5, r8, r6, r14
+    smlal   r5, r8, r7, r12
+
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+    stmdb   r1!, {r8, r9}
+    sub     r2, r2, r3, lsl #2
+
+    ldmia   r2, {r6, r7}
+    smull   r5, r9, r6, r10
+    rsb     r10, r10, #0
+    smlal   r5, r9, r7, r11
+    smull   r5, r8, r6, r11
+    smlal   r5, r8, r7, r10
+
+    mov     r8, r8, lsl #1
+    mov     r9, r9, lsl #1
+    stmdb   r1!, {r8, r9}
+    sub     r2, r2, r3, lsl #2
+
+    cmp     r2, r4
+    bhi     label_4
+
+    ldmia   sp!, {r4-r11, pc}
+
+	ENDP
+
+	END

+ 83 - 7
bsp/stm32_radio/libwma/wma_arm.S

@@ -1,20 +1,96 @@
+	AREA |.text|, CODE, READONLY, ALIGN=2
+	THUMB
+	REQUIRE8
+	PRESERVE8
 
-MULT32
+MULT32	PROC
+	EXPORT MULT32
+	MOV      r2,r0
+	SMULL    r1,r0,r2,r1
+	BX		 lr
 	ENDP
-	
-MULT31_SHIFT15
+
+MULT31	PROC
+	EXPORT MULT31
+	SMULL    r2,r1,r0,r1
+	LSL      r0,r1,#1
+	BX       lr
+	ENDP
+
+MULT31_SHIFT15	PROC
+	EXPORT MULT31_SHIFT15
+
+	SMULL    r2,r1,r0,r1
+	LSRS     r0,r2,#15
+	ADC      r0,r0,r1,LSL #17
+	BX       lr
+
 	ENDP
 
-XPROD32
+XPROD32 PROC
+	EXPORT XPROD32
+
+	PUSH     {r4,r5,lr}
+	SMULL    lr,r12,r0,r2
+	SMLAL    lr,r12,r1,r3
+	RSB      lr,r0,#0
+	SMULL    r2,r0,r1,r2
+	SMLAL    r2,r0,lr,r3
+	LDR      r4,[sp,#0xc]
+	LDR      r5,[sp,#0x10]
+	STR      r12,[r4,#0]
+	STR      r0,[r5,#0]
+	POP      {r4,r5,pc}
+
 	ENDP
 
-XPROD31
+XPROD31 PROC
+	EXPORT XPROD31
+
+	PUSH     {r4,r5,lr}
+	SMULL    lr,r12,r0,r2
+	SMLAL    lr,r12,r1,r3
+	RSB      lr,r0,#0
+	SMULL    r2,r0,r1,r2
+	SMLAL    r2,r0,lr,r3
+	LDR      r4,[sp,#0xc]
+	LDR      r5,[sp,#0x10]
+	LSL      r1,r12,#1
+	LSL      r0,r0,#1
+	STR      r1,[r4,#0]
+	STR      r0,[r5,#0]
+	POP      {r4,r5,pc}
+
 	ENDP
 
-XNPROD31
+XNPROD31	PROC
+	EXPORT XNPROD31
+
+	PUSH     {r4-r6,lr}
+	SMULL    r4,r12,r0,r2
+	RSB      lr,r1,#0
+	SMLAL    r4,r12,lr,r3
+	SMULL    lr,r2,r1,r2
+	SMLAL    lr,r2,r0,r3
+	LDR      r5,[sp,#0x10]
+	LDR      r6,[sp,#0x14]
+	LSL      r0,r12,#1
+	STR      r0,[r5,#0]
+	LSL      r0,r2,#1
+	STR      r0,[r6,#0]
+	POP      {r4-r6,pc}
+
 	ENDP
 
-CLIP_TO_15
+CLIP_TO_15	PROC
+	EXPORT CLIP_TO_15
+
+	SUBS     r1, r0, #0x8000
+	MOVPL    r0, #0x7f00
+	ORRPL    r0, r0, #0xff
+	ADDS     r1, r0, #0x8000
+	MOVMI    r0,#0x8000
+	BX 		 lr
 	ENDP
 
 	END

+ 4 - 31
bsp/stm32_radio/libwma/wmadeci.c

@@ -29,7 +29,6 @@
 #include "wmafixed.h"
 #include "wmabitstream.h"
 
-
 #define VLCBITS 7       /*7 is the lowest without glitching*/
 #define VLCMAX ((22+VLCBITS-1)/VLCBITS)
 
@@ -39,15 +38,13 @@
 #define HGAINVLCBITS 9
 #define HGAINMAX ((13+HGAINVLCBITS-1)/HGAINVLCBITS)
 
-
 typedef struct CoefVLCTable
 {
     int n; /* total number of codes */
     const uint32_t *huffcodes; /* VLC bit values */
     const uint8_t *huffbits;   /* VLC bit size */
     const uint16_t *levels; /* table to build run/level tables */
-}
-CoefVLCTable;
+} CoefVLCTable;
 
 static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len);
 
@@ -74,11 +71,7 @@ VLC_TYPE vlcbuf2[VLCBUF2SIZE][2];
 VLC_TYPE vlcbuf3[VLCBUF3SIZE][2];
 VLC_TYPE vlcbuf4[VLCBUF4SIZE][2];
 
-
-
-#include "wmadata.h" // PJJ
-
-
+#include "wmadata.h"
 
 /*
  * Helper functions for wma_window.
@@ -273,8 +266,6 @@ static inline void vector_fmul_reverse(fixed32 *dst, const fixed32 *src0, const
  }
 
 
-
-
 /* XXX: use same run/length optimization as mpeg decoders */
 static void init_coef_vlc(VLC *vlc,
                           uint16_t **prun_table, uint16_t **plevel_table,
@@ -288,7 +279,6 @@ static void init_coef_vlc(VLC *vlc,
     const uint16_t *p;
     int i, l, j, level;
 
-
     init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0);
 
     run_table = runtabarray[tab];
@@ -413,8 +403,8 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx)
             sample_rate1 = 11025;
         else if (sample_rate1 >= 8000)
             sample_rate1 = 8000;
-    }
-
+    }
+
 	{
 		fixed64 tmp, tmp2;
 		fixed64 tim, tmpi;
@@ -647,7 +637,6 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx)
 
         }
         s->windows[i] = window;
-
     }
 
     s->reset_block_lengths = 1;
@@ -668,19 +657,6 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx)
                 noisetable_exp[i] = noisetable_exp[i]<< 1;
             s->noise_table = noisetable_exp;
         }
-#if 0
-        {
-            unsigned int seed;
-            fixed32 norm;
-            seed = 1;
-            norm = 0;   // PJJ: near as makes any diff to 0!
-            for (i=0;i<NOISE_TAB_SIZE;++i)
-            {
-                seed = seed * 314159 + 1;
-                s->noise_table[i] = itofix32((int)seed) * norm;
-            }
-        }
-#endif
 
          s->hgain_vlc.table = vlcbuf4;
          s->hgain_vlc.table_allocated = VLCBUF4SIZE;
@@ -1454,7 +1430,6 @@ static int wma_decode_frame(WMADecodeContext *s, int32_t *samples)
         ret = wma_decode_block(s, samples);
         if (ret < 0)
         {
-
             DEBUGF("wma_decode_block failed with code %d\n", ret);
             return -1;
         }
@@ -1524,7 +1499,6 @@ int wma_decode_superframe_init(WMADecodeContext* s,
 /* Decode a single frame in the current superframe - return -1 if
    there was a decoding error, or the number of samples decoded.
 */
-
 int wma_decode_superframe_frame(WMADecodeContext* s,
                                 int32_t* samples, /*output*/
                                 const uint8_t *buf,  /*input*/
@@ -1616,4 +1590,3 @@ fail:
     s->last_superframe_len = 0;
     return -1;
 }
-

+ 1 - 13
bsp/stm32_radio/libwma/wmafixed.c

@@ -65,19 +65,14 @@ fixed64 Fixed32To64(fixed32 x)
 
 /*
     Not performance senstitive code here
-
 */
-
-
 fixed64 fixmul64byfixed(fixed64 x, fixed32 y)
 {
-
     //return x * y;
      return (x * y);
  // return (fixed64) fixmul32(Fixed32From64(x),y);
 }
 
-
 fixed32 fixdiv32(fixed32 x, fixed32 y)
 {
     fixed64 temp;
@@ -104,9 +99,8 @@ fixed64 fixdiv64(fixed64 x, fixed64 y)
     return (fixed64)(temp / y);
 }
 
- fixed32 fixsqrt32(fixed32 x)
+fixed32 fixsqrt32(fixed32 x)
 {
-
     unsigned long r = 0, s, v = (unsigned long)x;
 
 #define STEP(k) s = r + (1 << k * 2); r >>= 1; \
@@ -132,8 +126,6 @@ fixed64 fixdiv64(fixed64 x, fixed64 y)
     return (fixed32)(r << (PRECISION / 2));
 }
 
-
-
 /* Inverse gain of circular cordic rotation in s0.31 format. */
 static const long cordic_circular_gain = 0xb2458939; /* 0.607252929 */
 
@@ -175,11 +167,9 @@ static const unsigned long atan_table[] = {
 
 
 /*
-
     Below here functions do not use standard fixed precision!
 */
 
-
 /**
  * Implements sin and cos using CORDIC rotation.
  *
@@ -239,5 +229,3 @@ long fsincos(unsigned long phase, fixed32 *cos)
 
     return y;
 }
-
-