Main Page | Class List | Directories | File List | Class Members | File Members

fixed_debug.h

Go to the documentation of this file.
00001 /* Copyright (C) 2003 Jean-Marc Valin */
00006 /*
00007    Redistribution and use in source and binary forms, with or without
00008    modification, are permitted provided that the following conditions
00009    are met:
00010    
00011    - Redistributions of source code must retain the above copyright
00012    notice, this list of conditions and the following disclaimer.
00013    
00014    - Redistributions in binary form must reproduce the above copyright
00015    notice, this list of conditions and the following disclaimer in the
00016    documentation and/or other materials provided with the distribution.
00017    
00018    - Neither the name of the Xiph.org Foundation nor the names of its
00019    contributors may be used to endorse or promote products derived from
00020    this software without specific prior written permission.
00021    
00022    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00025    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
00026    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00027    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00028    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00029    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00030    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00031    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 */
00034 
00035 #ifndef FIXED_DEBUG_H
00036 #define FIXED_DEBUG_H
00037 
00038 #include <stdio.h>
00039 
00040 extern long long spx_mips;
00041 #define MIPS_INC spx_mips++,
00042 
00043 #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
00044 #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
00045 
00046 #define SHR(a,shift) ((a) >> (shift))
00047 #define SHL(a,shift) ((a) << (shift))
00048 
00049 static inline short ADD16(int a, int b) 
00050 {
00051    int res;
00052    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00053    {
00054       fprintf (stderr, "ADD16: inputs are not short: %d %d\n", a, b);
00055    }
00056    res = a+b;
00057    if (!VERIFY_SHORT(res))
00058       fprintf (stderr, "ADD16: output is not short: %d\n", res);
00059    spx_mips++;
00060    return res;
00061 }
00062 static inline short SUB16(int a, int b) 
00063 {
00064    int res;
00065    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00066    {
00067       fprintf (stderr, "SUB16: inputs are not short: %d %d\n", a, b);
00068    }
00069    res = a-b;
00070    if (!VERIFY_SHORT(res))
00071       fprintf (stderr, "SUB16: output is not short: %d\n", res);
00072    spx_mips++;
00073    return res;
00074 }
00075 
00076 static inline int ADD32(long long a, long long b) 
00077 {
00078    long long res;
00079    if (!VERIFY_INT(a) || !VERIFY_INT(b))
00080    {
00081       fprintf (stderr, "ADD32: inputs are not int: %d %d\n", (int)a, (int)b);
00082    }
00083    res = a+b;
00084    if (!VERIFY_INT(res))
00085       fprintf (stderr, "ADD32: output is not int: %d\n", (int)res);
00086    spx_mips++;
00087    return res;
00088 }
00089 
00090 static inline int SUB32(long long a, long long b) 
00091 {
00092    long long res;
00093    if (!VERIFY_INT(a) || !VERIFY_INT(b))
00094    {
00095       fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b);
00096    }
00097    res = a-b;
00098    if (!VERIFY_INT(res))
00099       fprintf (stderr, "SUB32: output is not int: %d\n", (int)res);
00100    spx_mips++;
00101    return res;
00102 }
00103 
00104 #define ADD64(a,b) (MIPS_INC(a)+(b))
00105 
00106 #define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift))
00107 
00108 /* result fits in 16 bits */
00109 static inline short MULT16_16_16(int a, int b) 
00110 {
00111    int res;
00112    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00113    {
00114       fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
00115    }
00116    res = a*b;
00117    if (!VERIFY_SHORT(res))
00118       fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
00119    spx_mips++;
00120    return res;
00121 }
00122 
00123 static inline int MULT16_16(int a, int b) 
00124 {
00125    long long res;
00126    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00127    {
00128       fprintf (stderr, "MULT16_16: inputs are not short: %d %d\n", a, b);
00129    }
00130    res = ((long long)a)*b;
00131    if (!VERIFY_INT(res))
00132       fprintf (stderr, "MULT16_16: output is not int: %d\n", (int)res);
00133    spx_mips++;
00134    return res;
00135 }
00136 #define MULT16_16B(a,b)     (((short)(a))*((short)(b)))
00137 
00138 #define MAC16_16(c,a,b)     (ADD32((c),MULT16_16((a),(b))))
00139 #define MAC16_16_Q11(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),11)))
00140 
00141 #define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
00142 #define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
00143 #define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
00144 
00145 #define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
00146 #define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
00147 
00148 #define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
00149 #define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
00150 
00151 static inline int SATURATE(int a, int b)
00152 {
00153    if (a>b)
00154       a=b;
00155    if (a<-b)
00156       a = -b;
00157    return a;
00158 }
00159 
00160 static inline short MULT16_16_Q11(int a, int b) 
00161 {
00162    long long res;
00163    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00164    {
00165       fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
00166    }
00167    res = ((long long)a)*b;
00168    res >>= 11;
00169    if (!VERIFY_SHORT(res))
00170       fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
00171    spx_mips++;
00172    return res;
00173 }
00174 static inline short MULT16_16_Q13(int a, int b) 
00175 {
00176    long long res;
00177    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00178    {
00179       fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
00180    }
00181    res = ((long long)a)*b;
00182    res >>= 13;
00183    if (!VERIFY_SHORT(res))
00184       fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
00185    spx_mips++;
00186    return res;
00187 }
00188 static inline short MULT16_16_Q14(int a, int b) 
00189 {
00190    long long res;
00191    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00192    {
00193       fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
00194    }
00195    res = ((long long)a)*b;
00196    res >>= 14;
00197    if (!VERIFY_SHORT(res))
00198       fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
00199    spx_mips++;
00200    return res;
00201 }
00202 static inline short MULT16_16_Q15(int a, int b) 
00203 {
00204    long long res;
00205    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00206    {
00207       fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
00208    }
00209    res = ((long long)a)*b;
00210    res >>= 15;
00211    if (!VERIFY_SHORT(res))
00212       fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
00213    spx_mips++;
00214    return res;
00215 }
00216 
00217 static inline short MULT16_16_P13(int a, int b) 
00218 {
00219    long long res;
00220    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00221    {
00222       fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
00223    }
00224    res = ((long long)a)*b;
00225    res += 4096;
00226    if (!VERIFY_INT(res))
00227       fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
00228    res >>= 13;
00229    if (!VERIFY_SHORT(res))
00230       fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
00231    spx_mips++;
00232    return res;
00233 }
00234 static inline short MULT16_16_P14(int a, int b) 
00235 {
00236    long long res;
00237    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00238    {
00239       fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
00240    }
00241    res = ((long long)a)*b;
00242    res += 8192;
00243    if (!VERIFY_INT(res))
00244       fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
00245    res >>= 14;
00246    if (!VERIFY_SHORT(res))
00247       fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
00248    spx_mips++;
00249    return res;
00250 }
00251 static inline short MULT16_16_P15(int a, int b) 
00252 {
00253    long long res;
00254    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
00255    {
00256       fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
00257    }
00258    res = ((long long)a)*b;
00259    res += 16384;
00260    if (!VERIFY_INT(res))
00261       fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
00262    res >>= 15;
00263    if (!VERIFY_SHORT(res))
00264       fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
00265    spx_mips++;
00266    return res;
00267 }
00268 
00269 #define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
00270 
00271 
00272 static inline int DIV32_16(long long a, long long b) 
00273 {
00274    long long res;
00275    if (b==0)
00276    {
00277       fprintf(stderr, "DIV32_16: divide by zero: %d/%d\n", (int)a, (int)b);
00278       return 0;
00279    }
00280    if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
00281    {
00282       fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d\n", (int)a, (int)b);
00283    }
00284    res = a/b;
00285    if (!VERIFY_SHORT(res))
00286    {
00287       fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d\n", (int)a,(int)b,(int)res);
00288       if (res>32767)
00289          res = 32767;
00290       if (res<-32768)
00291          res = -32768;
00292    }
00293    spx_mips++;
00294    return res;
00295 }
00296 static inline int DIV32(long long a, long long b) 
00297 {
00298    long long res;
00299    if (b==0)
00300    {
00301       fprintf(stderr, "DIV32: divide by zero: %d/%d\n", (int)a, (int)b);
00302       return 0;
00303    }
00304 
00305    if (!VERIFY_INT(a) || !VERIFY_INT(b))
00306    {
00307       fprintf (stderr, "DIV32: inputs are not int/short: %d %d\n", (int)a, (int)b);
00308    }
00309    res = a/b;
00310    if (!VERIFY_INT(res))
00311       fprintf (stderr, "DIV32: output is not int: %d\n", (int)res);
00312    spx_mips++;
00313    return res;
00314 }
00315 
00316 
00317 
00318 #endif

Generated on Sun Feb 27 16:36:11 2005 for speex by  doxygen 1.4.1