quant_lsp_bfin.h revision 98913fed6520d8849fb2e246be943e04474aefa4
19b6ec9471cebdbd68639492825956b96f807e382Ben Gruver/* Copyright (C) 2006 David Rowe */
29b6ec9471cebdbd68639492825956b96f807e382Ben Gruver/**
39b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   @file quant_lsp_bfin.h
49b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   @author David Rowe
59b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   @brief Various compatibility routines for Speex (Blackfin version)
69b6ec9471cebdbd68639492825956b96f807e382Ben Gruver*/
79b6ec9471cebdbd68639492825956b96f807e382Ben Gruver/*
89b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   Redistribution and use in source and binary forms, with or without
99b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   modification, are permitted provided that the following conditions
109b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   are met:
119b6ec9471cebdbd68639492825956b96f807e382Ben Gruver
129b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   - Redistributions of source code must retain the above copyright
139b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   notice, this list of conditions and the following disclaimer.
149b6ec9471cebdbd68639492825956b96f807e382Ben Gruver
159b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   - Redistributions in binary form must reproduce the above copyright
169b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   notice, this list of conditions and the following disclaimer in the
179b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   documentation and/or other materials provided with the distribution.
189b6ec9471cebdbd68639492825956b96f807e382Ben Gruver
199b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   - Neither the name of the Xiph.org Foundation nor the names of its
209b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   contributors may be used to endorse or promote products derived from
219b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   this software without specific prior written permission.
22f3d921d1f8eb52f20440a0e43f604a7aae972e94Ben Gruver
239b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
249b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
259b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
269b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
279b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
289b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
299b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
309b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
319b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
329b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
339b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
349b6ec9471cebdbd68639492825956b96f807e382Ben Gruver*/
359b6ec9471cebdbd68639492825956b96f807e382Ben Gruver
369b6ec9471cebdbd68639492825956b96f807e382Ben Gruver#define OVERRIDE_LSP_QUANT
379b6ec9471cebdbd68639492825956b96f807e382Ben Gruver#ifdef OVERRIDE_LSP_QUANT
389b6ec9471cebdbd68639492825956b96f807e382Ben Gruver
395fd395796e215a80c722815bf180728948868f18Ben Gruver/*
409b6ec9471cebdbd68639492825956b96f807e382Ben Gruver  Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
41f3d921d1f8eb52f20440a0e43f604a7aae972e94Ben Gruver  well tell you all the magic resgister constraints used below
421d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruver  for gcc in-line asm.
431d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruver*/
441d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruver
451d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruverstatic int lsp_quant(
469b6ec9471cebdbd68639492825956b96f807e382Ben Gruver  spx_word16_t      *x,
479b6ec9471cebdbd68639492825956b96f807e382Ben Gruver  const signed char *cdbk,
489b6ec9471cebdbd68639492825956b96f807e382Ben Gruver  int                nbVec,
499b6ec9471cebdbd68639492825956b96f807e382Ben Gruver  int                nbDim
509b6ec9471cebdbd68639492825956b96f807e382Ben Gruver)
519b6ec9471cebdbd68639492825956b96f807e382Ben Gruver{
529b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   int          j;
539b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   spx_word32_t best_dist=1<<30;
549b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   int          best_id=0;
559b6ec9471cebdbd68639492825956b96f807e382Ben Gruver
569b6ec9471cebdbd68639492825956b96f807e382Ben Gruver   __asm__ __volatile__
579b6ec9471cebdbd68639492825956b96f807e382Ben Gruver     (
589b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"	%0 = 1 (X);\n\t"                       /* %0: best_dist */
599b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"	%0 <<= 30;\n\t"
609b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"	%1 = 0 (X);\n\t"                       /* %1: best_i         */
619b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"       P2 = %3\n\t"                           /* P2: ptr to cdbk    */
629b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"       R5 = 0;\n\t"                           /* R5: best cb entry  */
639b6ec9471cebdbd68639492825956b96f807e382Ben Gruver
649b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"       R0 = %5;\n\t"                          /* set up circ addr   */
659b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"       R0 <<= 1;\n\t"
669b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"       L0 = R0;\n\t"
679b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"       I0 = %2;\n\t"                          /* %2: &x[0]          */
689b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"       B0 = %2;\n\t"
69f3d921d1f8eb52f20440a0e43f604a7aae972e94Ben Gruver
709b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"       R2.L = W [I0++];\n\t"
719b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"	LSETUP (1f, 2f) LC0 = %4;\n\t"
729b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"1:	  R3 = 0;\n\t"                         /* R3: dist           */
739b6ec9471cebdbd68639492825956b96f807e382Ben Gruver"	  LSETUP (3f, 4f) LC1 = %5;\n\t"
74"3:       R1 = B [P2++] (X);\n\t"
75"	    R1 <<= 5;\n\t"
76"	    R0.L = R2.L - R1.L || R2.L = W [I0++];\n\t"
77"	    R0 = R0.L*R0.L;\n\t"
78"4:	    R3 = R3 + R0;\n\t"
79
80"	  cc =R3<%0;\n\t"
81"	  if cc %0=R3;\n\t"
82"	  if cc %1=R5;\n\t"
83"2:     R5 += 1;\n\t"
84"         L0 = 0;\n\t"
85   : "=&d" (best_dist), "=&d" (best_id)
86   : "a" (x), "b" (cdbk), "a" (nbVec), "a" (nbDim)
87   : "I0", "P2", "R0", "R1", "R2", "R3", "R5", "L0", "B0", "A0"
88   );
89
90   for (j=0;j<nbDim;j++) {
91      x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
92   }
93   return best_id;
94}
95#endif
96
97#define OVERRIDE_LSP_WEIGHT_QUANT
98#ifdef OVERRIDE_LSP_WEIGHT_QUANT
99
100/*
101  Note http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
102  well tell you all the magic resgister constraints used below
103  for gcc in-line asm.
104*/
105
106static int lsp_weight_quant(
107  spx_word16_t      *x,
108  spx_word16_t      *weight,
109  const signed char *cdbk,
110  int                nbVec,
111  int                nbDim
112)
113{
114   int          j;
115   spx_word32_t best_dist=1<<30;
116   int          best_id=0;
117
118   __asm__ __volatile__
119     (
120"	%0 = 1 (X);\n\t"                       /* %0: best_dist */
121"	%0 <<= 30;\n\t"
122"	%1 = 0 (X);\n\t"                       /* %1: best_i         */
123"       P2 = %4\n\t"                           /* P2: ptr to cdbk    */
124"       R5 = 0;\n\t"                           /* R5: best cb entry  */
125
126"       R0 = %6;\n\t"                          /* set up circ addr   */
127"       R0 <<= 1;\n\t"
128"       L0 = R0;\n\t"
129"       L1 = R0;\n\t"
130"       I0 = %2;\n\t"                          /* %2: &x[0]          */
131"	I1 = %3;\n\t"                          /* %3: &weight[0]     */
132"       B0 = %2;\n\t"
133"	B1 = %3;\n\t"
134
135"	LSETUP (1f, 2f) LC0 = %5;\n\t"
136"1:	  R3 = 0 (X);\n\t"                     /* R3: dist           */
137"	  LSETUP (3f, 4f) LC1 = %6;\n\t"
138"3:	    R0.L = W [I0++] || R2.L = W [I1++];\n\t"
139"           R1 = B [P2++] (X);\n\t"
140"	    R1 <<= 5;\n\t"
141"	    R0.L = R0.L - R1.L;\n\t"
142"           R0 = R0.L*R0.L;\n\t"
143"	    A1 = R2.L*R0.L (M,IS);\n\t"
144"	    A1 = A1 >>> 16;\n\t"
145"	    R1 = (A1 += R2.L*R0.H) (IS);\n\t"
146"4:	    R3 = R3 + R1;\n\t"
147
148"	  cc =R3<%0;\n\t"
149"	  if cc %0=R3;\n\t"
150"	  if cc %1=R5;\n\t"
151"2:    R5 += 1;\n\t"
152"         L0 = 0;\n\t"
153"         L1 = 0;\n\t"
154   : "=&d" (best_dist), "=&d" (best_id)
155   : "a" (x), "a" (weight), "b" (cdbk), "a" (nbVec), "a" (nbDim)
156   : "I0", "I1", "P2", "R0", "R1", "R2", "R3", "R5", "A1",
157     "L0", "L1", "B0", "B1"
158   );
159
160   for (j=0;j<nbDim;j++) {
161      x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
162   }
163   return best_id;
164}
165#endif
166