filter_mem2 completely in assembly
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 5 Jun 2005 06:27:48 +0000 (06:27 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 5 Jun 2005 06:27:48 +0000 (06:27 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@9358 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/filters_bfin.h

index b08cdde..b5454d9 100644 (file)
@@ -86,7 +86,6 @@ int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int le
 #define OVERRIDE_FILTER_MEM2
 void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *_y, int N, int ord, spx_mem_t *mem)
 {
-   int i,j;
    spx_word16_t x[N],y[N];
    spx_word16_t *xx, *yy;
    xx = x;
@@ -94,6 +93,7 @@ void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *d
    
    __asm__ __volatile__
    (
+   /* Register setup */
    "R0 = %7;\n\t"      /*ord */
    
    "P0 = %4;\n\t"
@@ -117,6 +117,7 @@ void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *d
    "P0 = %2;\n\t"
    "P1 = %3;\n\t"
    
+   /* First sample */
    "R1 = [P4++];\n\t"
    "R1 <<= 1;\n\t"
    "R2 = [P0++];\n\t"
@@ -126,7 +127,8 @@ void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *d
    "W[P3] = R1.H;\n\t"
    "R2 <<= 2;\n\t"
    "W[P2] = R2.H;\n\t"
-      
+
+   /* Samples 1 to ord-1 (using memory) */
    "R0 += -1;\n\t"
    "R3 = 0;\n\t"
    "LC0 = R0;\n\t"
@@ -150,9 +152,8 @@ void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *d
          "A1 += R4.L*R5.L (IS);\n\t"
          "R4.L = W[I1++];\n\t"
          "R5.L = W[I3--];\n\t"
-         "A1 -= R4.L*R5.L (IS);\n\t"
       "LOOP_END filter_start_inner%=;\n\t"
-      "nop;nop;nop;nop;\n\t"
+         "A1 -= R4.L*R5.L (IS);\n\t"
    
       "R1 = A1;\n\t"
       "R1 <<= 1;\n\t"
@@ -162,12 +163,10 @@ void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *d
       "R1 <<= 2;\n\t"
       "W[P3] = R1.H;\n\t"
       "R2 <<= 2;\n\t"
+   "LOOP_END filter_start%=;\n\t"
       "W[P2] = R2.H;\n\t"
 
-   "LOOP_END filter_start%=;\n\t"
-   "nop;nop;nop;nop;\n\t"
-   
-   
+   /* Samples ord to N*/   
    "R0 = %7;\n\t"
    "R0 <<= 1;\n\t"
    "I0 = B0;\n\t"
@@ -205,26 +204,42 @@ void filter_mem2(const spx_sig_t *_x, const spx_coef_t *num, const spx_coef_t *d
       "R1 <<= 2;\n\t"
       "W[P3] = R1.H;\n\t"
       "R2 <<= 2;\n\t"
+   "LOOP_END filter_mid%=;\n\t"
       "W[P2] = R2.H;\n\t"
      
-   "LOOP_END filter_mid%=;\n\t"
-   "nop;nop;nop;nop;\n\t"
-   
+   /* Update memory */
+   "P4 = %8;\n\t"
+   "R0 = %7;\n\t"
+   "LC0 = R0;\n\t"
+   "P0 = B0;\n\t"
+   "P1 = B1;\n\t"
+   "LOOP mem_update%= LC0;\n\t"
+   "LOOP_BEGIN mem_update%=;\n\t"
+      "A0 = 0;\n\t"
+      "I2 = P2;\n\t"
+      "I3 = P3;\n\t"
+      "I0 = P0;\n\t"
+      "I1 = P1;\n\t"
+      "P0 += 2;\n\t"
+      "P1 += 2;\n\t"
+      "R0 = LC0;LC1=R0;\n\t"
+      "R5.L = W[I2--];\n\t"
+      "R7.L = W[I3--];\n\t"
+      "R4.L = W[I0++];\n\t"
+      "R6.L = W[I1++];\n\t"
+      "LOOP mem_accum%= LC1;\n\t"
+      "LOOP_BEGIN mem_accum%=;\n\t"
+         "A0 += R4.L*R5.L (IS) || R4.L = W[I0++] || R5.L = W[I2--];\n\t"
+      "LOOP_END mem_accum%=;\n\t"
+         "A0 -= R6.L*R7.L (IS) || R6.L = W[I1++] || R7.L = W[I3--];\n\t"
+      "R0 = A0;\n\t"
+   "LOOP_END mem_update%=;\n\t"
+      "[P4++] = R0;\n\t"
+
    : : "m" (xx), "m" (yy), "m" (_x), "m" (_y), "m" (num), "m" (den), "m" (N), "m" (ord), "m" (mem)
    : "R0", "R1", "R2", "R3", "R4", "R5", "R7", "P0", "P1", "P2", "P3", "P4", "B0", "B1", "I0", "I1", "I2", "I3", "L0", "L1", "L2", "L3", "memory"
    );
 
-
-   for (i=0;i<ord;i++)
-   {
-      spx_mem_t m = 0;
-      for (j=0;j<ord-i;j++)
-      {
-         m = MAC16_16(m, x[N-1-j], num[j+i]);
-         m = MAC16_16(m, -y[N-1-j], den[j+i]);
-      }
-      mem[i] = m;
-   }
 }