fixed_bfin.h revision 98913fed6520d8849fb2e246be943e04474aefa4
1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Copyright (C) 2005 Analog Devices
2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Author: Jean-Marc Valin */
3663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/**
4663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   @file fixed_bfin.h
5663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   @brief Blackfin fixed-point operations
6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/
7663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*
8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Redistribution and use in source and binary forms, with or without
9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   modification, are permitted provided that the following conditions
10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   are met:
11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   - Redistributions of source code must retain the above copyright
13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   notice, this list of conditions and the following disclaimer.
14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   - Redistributions in binary form must reproduce the above copyright
16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   notice, this list of conditions and the following disclaimer in the
17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   documentation and/or other materials provided with the distribution.
18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   - Neither the name of the Xiph.org Foundation nor the names of its
20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   contributors may be used to endorse or promote products derived from
21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   this software without specific prior written permission.
22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/
35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#ifndef FIXED_BFIN_H
37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define FIXED_BFIN_H
38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef PDIV32_16
40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic inline spx_word16_t PDIV32_16(spx_word32_t a, spx_word16_t b)
41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   spx_word32_t res, bb;
43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   bb = b;
44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   a += b>>1;
45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   __asm__  (
46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "P0 = 15;\n\t"
47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "R0 = %1;\n\t"
48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "R1 = %2;\n\t"
49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         //"R0 = R0 + R1;\n\t"
50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "R0 <<= 1;\n\t"
51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "DIVS (R0, R1);\n\t"
52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "LOOP divide%= LC0 = P0;\n\t"
53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "LOOP_BEGIN divide%=;\n\t"
54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            "DIVQ (R0, R1);\n\t"
55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "LOOP_END divide%=;\n\t"
56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "R0 = R0.L;\n\t"
57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "%0 = R0;\n\t"
58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   : "=m" (res)
59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   : "m" (a), "m" (bb)
60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   : "P0", "R0", "R1", "cc");
61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return res;
62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
64663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef DIV32_16
65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic inline spx_word16_t DIV32_16(spx_word32_t a, spx_word16_t b)
66663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   spx_word32_t res, bb;
68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   bb = b;
69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* Make the roundinf consistent with the C version
70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      (do we need to do that?)*/
71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (a<0)
72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      a += (b-1);
73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   __asm__  (
74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "P0 = 15;\n\t"
75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "R0 = %1;\n\t"
76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "R1 = %2;\n\t"
77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "R0 <<= 1;\n\t"
78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "DIVS (R0, R1);\n\t"
79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "LOOP divide%= LC0 = P0;\n\t"
80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "LOOP_BEGIN divide%=;\n\t"
81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            "DIVQ (R0, R1);\n\t"
82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "LOOP_END divide%=;\n\t"
83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "R0 = R0.L;\n\t"
84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "%0 = R0;\n\t"
85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   : "=m" (res)
86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   : "m" (a), "m" (bb)
87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   : "P0", "R0", "R1", "cc");
88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return res;
89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef MAX16
92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic inline spx_word16_t MAX16(spx_word16_t a, spx_word16_t b)
93663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   spx_word32_t res;
95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   __asm__  (
96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "%1 = %1.L (X);\n\t"
97663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "%2 = %2.L (X);\n\t"
98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         "%0 = MAX(%1,%2);"
99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   : "=d" (res)
100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   : "%d" (a), "d" (b)
101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   );
102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return res;
103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef MULT16_32_Q15
106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic inline spx_word32_t MULT16_32_Q15(spx_word16_t a, spx_word32_t b)
107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   spx_word32_t res;
109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   __asm__
110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   (
111         "A1 = %2.L*%1.L (M);\n\t"
112         "A1 = A1 >>> 15;\n\t"
113         "%0 = (A1 += %2.L*%1.H) ;\n\t"
114   : "=&W" (res), "=&d" (b)
115   : "d" (a), "1" (b)
116   : "A1"
117   );
118   return res;
119}
120
121#undef MAC16_32_Q15
122static inline spx_word32_t MAC16_32_Q15(spx_word32_t c, spx_word16_t a, spx_word32_t b)
123{
124   spx_word32_t res;
125   __asm__
126         (
127         "A1 = %2.L*%1.L (M);\n\t"
128         "A1 = A1 >>> 15;\n\t"
129         "%0 = (A1 += %2.L*%1.H);\n\t"
130         "%0 = %0 + %4;\n\t"
131   : "=&W" (res), "=&d" (b)
132   : "d" (a), "1" (b), "d" (c)
133   : "A1"
134         );
135   return res;
136}
137
138#undef MULT16_32_Q14
139static inline spx_word32_t MULT16_32_Q14(spx_word16_t a, spx_word32_t b)
140{
141   spx_word32_t res;
142   __asm__
143         (
144         "%2 <<= 1;\n\t"
145         "A1 = %1.L*%2.L (M);\n\t"
146         "A1 = A1 >>> 15;\n\t"
147         "%0 = (A1 += %1.L*%2.H);\n\t"
148   : "=W" (res), "=d" (a), "=d" (b)
149   : "1" (a), "2" (b)
150   : "A1"
151         );
152   return res;
153}
154
155#undef MAC16_32_Q14
156static inline spx_word32_t MAC16_32_Q14(spx_word32_t c, spx_word16_t a, spx_word32_t b)
157{
158   spx_word32_t res;
159   __asm__
160         (
161         "%1 <<= 1;\n\t"
162         "A1 = %2.L*%1.L (M);\n\t"
163         "A1 = A1 >>> 15;\n\t"
164         "%0 = (A1 += %2.L*%1.H);\n\t"
165         "%0 = %0 + %4;\n\t"
166   : "=&W" (res), "=&d" (b)
167   : "d" (a), "1" (b), "d" (c)
168   : "A1"
169         );
170   return res;
171}
172
173#endif
174