bowen liu
/
mbed-os-example-blinky
ex
Fork of mbed-os-example-mbed5-blinky by
Embed:
(wiki syntax)
Show/hide line numbers
fixed_debug.h
Go to the documentation of this file.
00001 /* Copyright (C) 2003 Jean-Marc Valin */ 00002 /** 00003 @file fixed_debug.h 00004 @brief Fixed-point operations with debugging 00005 */ 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 QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) 00044 #define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) 00045 00046 00047 #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768) 00048 #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL) 00049 00050 static inline short NEG16(int x) 00051 { 00052 int res; 00053 if (!VERIFY_SHORT(x)) 00054 { 00055 fprintf (stderr, "NEG16: input is not short: %d\n", (int)x); 00056 } 00057 res = -x; 00058 if (!VERIFY_SHORT(res)) 00059 fprintf (stderr, "NEG16: output is not short: %d\n", (int)res); 00060 spx_mips++; 00061 return res; 00062 } 00063 static inline int NEG32(long long x) 00064 { 00065 long long res; 00066 if (!VERIFY_INT(x)) 00067 { 00068 fprintf (stderr, "NEG16: input is not int: %d\n", (int)x); 00069 } 00070 res = -x; 00071 if (!VERIFY_INT(res)) 00072 fprintf (stderr, "NEG16: output is not int: %d\n", (int)res); 00073 spx_mips++; 00074 return res; 00075 } 00076 00077 #define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__) 00078 static inline short _EXTRACT16(int x, char *file, int line) 00079 { 00080 int res; 00081 if (!VERIFY_SHORT(x)) 00082 { 00083 fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); 00084 } 00085 res = x; 00086 spx_mips++; 00087 return res; 00088 } 00089 00090 #define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__) 00091 static inline int _EXTEND32(int x, char *file, int line) 00092 { 00093 int res; 00094 if (!VERIFY_SHORT(x)) 00095 { 00096 fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); 00097 } 00098 res = x; 00099 spx_mips++; 00100 return res; 00101 } 00102 00103 #define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__) 00104 static inline short _SHR16(int a, int shift, char *file, int line) 00105 { 00106 int res; 00107 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) 00108 { 00109 fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); 00110 } 00111 res = a>>shift; 00112 if (!VERIFY_SHORT(res)) 00113 fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); 00114 spx_mips++; 00115 return res; 00116 } 00117 #define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__) 00118 static inline short _SHL16(int a, int shift, char *file, int line) 00119 { 00120 int res; 00121 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) 00122 { 00123 fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); 00124 } 00125 res = a<<shift; 00126 if (!VERIFY_SHORT(res)) 00127 fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line); 00128 spx_mips++; 00129 return res; 00130 } 00131 00132 static inline int SHR32(long long a, int shift) 00133 { 00134 long long res; 00135 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) 00136 { 00137 fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift); 00138 } 00139 res = a>>shift; 00140 if (!VERIFY_INT(res)) 00141 { 00142 fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); 00143 } 00144 spx_mips++; 00145 return res; 00146 } 00147 static inline int SHL32(long long a, int shift) 00148 { 00149 long long res; 00150 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) 00151 { 00152 fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift); 00153 } 00154 res = a<<shift; 00155 if (!VERIFY_INT(res)) 00156 { 00157 fprintf (stderr, "SHL32: output is not int: %d\n", (int)res); 00158 } 00159 spx_mips++; 00160 return res; 00161 } 00162 00163 #define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift)) 00164 #define PSHR32(a,shift) (SHR32(ADD32((a),((1<<((shift))>>1))),shift)) 00165 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) 00166 00167 #define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) 00168 #define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) 00169 00170 //#define SHR(a,shift) ((a) >> (shift)) 00171 //#define SHL(a,shift) ((a) << (shift)) 00172 00173 #define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__) 00174 static inline short _ADD16(int a, int b, char *file, int line) 00175 { 00176 int res; 00177 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00178 { 00179 fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 00180 } 00181 res = a+b; 00182 if (!VERIFY_SHORT(res)) 00183 { 00184 fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line); 00185 } 00186 spx_mips++; 00187 return res; 00188 } 00189 00190 #define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__) 00191 static inline short _SUB16(int a, int b, char *file, int line) 00192 { 00193 int res; 00194 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00195 { 00196 fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 00197 } 00198 res = a-b; 00199 if (!VERIFY_SHORT(res)) 00200 fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line); 00201 spx_mips++; 00202 return res; 00203 } 00204 00205 #define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__) 00206 static inline int _ADD32(long long a, long long b, char *file, int line) 00207 { 00208 long long res; 00209 if (!VERIFY_INT(a) || !VERIFY_INT(b)) 00210 { 00211 fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 00212 } 00213 res = a+b; 00214 if (!VERIFY_INT(res)) 00215 { 00216 fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line); 00217 } 00218 spx_mips++; 00219 return res; 00220 } 00221 00222 static inline int SUB32(long long a, long long b) 00223 { 00224 long long res; 00225 if (!VERIFY_INT(a) || !VERIFY_INT(b)) 00226 { 00227 fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b); 00228 } 00229 res = a-b; 00230 if (!VERIFY_INT(res)) 00231 fprintf (stderr, "SUB32: output is not int: %d\n", (int)res); 00232 spx_mips++; 00233 return res; 00234 } 00235 00236 #define ADD64(a,b) (MIPS_INC(a)+(b)) 00237 00238 /* result fits in 16 bits */ 00239 static inline short MULT16_16_16(int a, int b) 00240 { 00241 int res; 00242 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00243 { 00244 fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b); 00245 } 00246 res = a*b; 00247 if (!VERIFY_SHORT(res)) 00248 fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res); 00249 spx_mips++; 00250 return res; 00251 } 00252 00253 #define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__) 00254 static inline int _MULT16_16(int a, int b, char *file, int line) 00255 { 00256 long long res; 00257 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00258 { 00259 fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 00260 } 00261 res = ((long long)a)*b; 00262 if (!VERIFY_INT(res)) 00263 fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line); 00264 spx_mips++; 00265 return res; 00266 } 00267 00268 #define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b)))) 00269 #define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11))))) 00270 #define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13))))) 00271 #define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13)))) 00272 00273 00274 #define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__) 00275 static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line) 00276 { 00277 long long res; 00278 if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) 00279 { 00280 fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); 00281 } 00282 if (ABS32(b)>=(1<<(15+Q))) 00283 fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); 00284 res = (((long long)a)*(long long)b) >> Q; 00285 if (!VERIFY_INT(res)) 00286 fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line); 00287 spx_mips+=5; 00288 return res; 00289 } 00290 00291 static inline int MULT16_32_PX(int a, long long b, int Q) 00292 { 00293 long long res; 00294 if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) 00295 { 00296 fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b); 00297 } 00298 if (ABS32(b)>=(1<<(15+Q))) 00299 fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b); 00300 res = ((((long long)a)*(long long)b) + ((1<<Q)>>1))>> Q; 00301 if (!VERIFY_INT(res)) 00302 fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res); 00303 spx_mips+=5; 00304 return res; 00305 } 00306 00307 00308 #define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11) 00309 #define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b))) 00310 #define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12) 00311 #define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13) 00312 #define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14) 00313 #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) 00314 #define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15) 00315 #define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b))) 00316 00317 static inline int SATURATE(int a, int b) 00318 { 00319 if (a>b) 00320 a=b; 00321 if (a<-b) 00322 a = -b; 00323 return a; 00324 } 00325 00326 static inline int MULT16_16_Q11_32(int a, int b) 00327 { 00328 long long res; 00329 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00330 { 00331 fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b); 00332 } 00333 res = ((long long)a)*b; 00334 res >>= 11; 00335 if (!VERIFY_INT(res)) 00336 fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res); 00337 spx_mips+=3; 00338 return res; 00339 } 00340 static inline short MULT16_16_Q13(int a, int b) 00341 { 00342 long long res; 00343 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00344 { 00345 fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b); 00346 } 00347 res = ((long long)a)*b; 00348 res >>= 13; 00349 if (!VERIFY_SHORT(res)) 00350 fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res); 00351 spx_mips+=3; 00352 return res; 00353 } 00354 static inline short MULT16_16_Q14(int a, int b) 00355 { 00356 long long res; 00357 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00358 { 00359 fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b); 00360 } 00361 res = ((long long)a)*b; 00362 res >>= 14; 00363 if (!VERIFY_SHORT(res)) 00364 fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res); 00365 spx_mips+=3; 00366 return res; 00367 } 00368 static inline short MULT16_16_Q15(int a, int b) 00369 { 00370 long long res; 00371 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00372 { 00373 fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b); 00374 } 00375 res = ((long long)a)*b; 00376 res >>= 15; 00377 if (!VERIFY_SHORT(res)) 00378 { 00379 fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res); 00380 } 00381 spx_mips+=3; 00382 return res; 00383 } 00384 00385 static inline short MULT16_16_P13(int a, int b) 00386 { 00387 long long res; 00388 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00389 { 00390 fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b); 00391 } 00392 res = ((long long)a)*b; 00393 res += 4096; 00394 if (!VERIFY_INT(res)) 00395 fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res); 00396 res >>= 13; 00397 if (!VERIFY_SHORT(res)) 00398 fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res); 00399 spx_mips+=4; 00400 return res; 00401 } 00402 static inline short MULT16_16_P14(int a, int b) 00403 { 00404 long long res; 00405 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00406 { 00407 fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b); 00408 } 00409 res = ((long long)a)*b; 00410 res += 8192; 00411 if (!VERIFY_INT(res)) 00412 fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res); 00413 res >>= 14; 00414 if (!VERIFY_SHORT(res)) 00415 fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res); 00416 spx_mips+=4; 00417 return res; 00418 } 00419 static inline short MULT16_16_P15(int a, int b) 00420 { 00421 long long res; 00422 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 00423 { 00424 fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b); 00425 } 00426 res = ((long long)a)*b; 00427 res += 16384; 00428 if (!VERIFY_INT(res)) 00429 fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res); 00430 res >>= 15; 00431 if (!VERIFY_SHORT(res)) 00432 fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res); 00433 spx_mips+=4; 00434 return res; 00435 } 00436 00437 #define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__) 00438 00439 static inline int _DIV32_16(long long a, long long b, char *file, int line) 00440 { 00441 long long res; 00442 if (b==0) 00443 { 00444 fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); 00445 return 0; 00446 } 00447 if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) 00448 { 00449 fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 00450 } 00451 res = a/b; 00452 if (!VERIFY_SHORT(res)) 00453 { 00454 fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line); 00455 if (res>32767) 00456 res = 32767; 00457 if (res<-32768) 00458 res = -32768; 00459 } 00460 spx_mips+=20; 00461 return res; 00462 } 00463 00464 #define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__) 00465 static inline int _DIV32(long long a, long long b, char *file, int line) 00466 { 00467 long long res; 00468 if (b==0) 00469 { 00470 fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); 00471 return 0; 00472 } 00473 00474 if (!VERIFY_INT(a) || !VERIFY_INT(b)) 00475 { 00476 fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 00477 } 00478 res = a/b; 00479 if (!VERIFY_INT(res)) 00480 fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); 00481 spx_mips+=36; 00482 return res; 00483 } 00484 #define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b) 00485 #define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b) 00486 00487 #endif
Generated on Tue Jul 12 2022 16:28:53 by 1.7.2