153a5a1b3Sopenharmony_ci/* Copyright (C) 2003 Jean-Marc Valin */ 253a5a1b3Sopenharmony_ci/** 353a5a1b3Sopenharmony_ci @file fixed_debug.h 453a5a1b3Sopenharmony_ci @brief Fixed-point operations with debugging 553a5a1b3Sopenharmony_ci*/ 653a5a1b3Sopenharmony_ci/* 753a5a1b3Sopenharmony_ci Redistribution and use in source and binary forms, with or without 853a5a1b3Sopenharmony_ci modification, are permitted provided that the following conditions 953a5a1b3Sopenharmony_ci are met: 1053a5a1b3Sopenharmony_ci 1153a5a1b3Sopenharmony_ci - Redistributions of source code must retain the above copyright 1253a5a1b3Sopenharmony_ci notice, this list of conditions and the following disclaimer. 1353a5a1b3Sopenharmony_ci 1453a5a1b3Sopenharmony_ci - Redistributions in binary form must reproduce the above copyright 1553a5a1b3Sopenharmony_ci notice, this list of conditions and the following disclaimer in the 1653a5a1b3Sopenharmony_ci documentation and/or other materials provided with the distribution. 1753a5a1b3Sopenharmony_ci 1853a5a1b3Sopenharmony_ci - Neither the name of the Xiph.org Foundation nor the names of its 1953a5a1b3Sopenharmony_ci contributors may be used to endorse or promote products derived from 2053a5a1b3Sopenharmony_ci this software without specific prior written permission. 2153a5a1b3Sopenharmony_ci 2253a5a1b3Sopenharmony_ci THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2353a5a1b3Sopenharmony_ci ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2453a5a1b3Sopenharmony_ci LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2553a5a1b3Sopenharmony_ci A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 2653a5a1b3Sopenharmony_ci CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2753a5a1b3Sopenharmony_ci EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2853a5a1b3Sopenharmony_ci PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2953a5a1b3Sopenharmony_ci PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3053a5a1b3Sopenharmony_ci LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3153a5a1b3Sopenharmony_ci NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3253a5a1b3Sopenharmony_ci SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3353a5a1b3Sopenharmony_ci*/ 3453a5a1b3Sopenharmony_ci 3553a5a1b3Sopenharmony_ci#ifndef FIXED_DEBUG_H 3653a5a1b3Sopenharmony_ci#define FIXED_DEBUG_H 3753a5a1b3Sopenharmony_ci 3853a5a1b3Sopenharmony_ci#include <stdio.h> 3953a5a1b3Sopenharmony_ci 4053a5a1b3Sopenharmony_ciextern long long spx_mips; 4153a5a1b3Sopenharmony_ci#define MIPS_INC spx_mips++, 4253a5a1b3Sopenharmony_ci 4353a5a1b3Sopenharmony_ci#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) 4453a5a1b3Sopenharmony_ci#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) 4553a5a1b3Sopenharmony_ci 4653a5a1b3Sopenharmony_ci 4753a5a1b3Sopenharmony_ci#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768) 4853a5a1b3Sopenharmony_ci#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL) 4953a5a1b3Sopenharmony_ci 5053a5a1b3Sopenharmony_cistatic inline short NEG16(int x) 5153a5a1b3Sopenharmony_ci{ 5253a5a1b3Sopenharmony_ci int res; 5353a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(x)) 5453a5a1b3Sopenharmony_ci { 5553a5a1b3Sopenharmony_ci fprintf (stderr, "NEG16: input is not short: %d\n", (int)x); 5653a5a1b3Sopenharmony_ci } 5753a5a1b3Sopenharmony_ci res = -x; 5853a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 5953a5a1b3Sopenharmony_ci fprintf (stderr, "NEG16: output is not short: %d\n", (int)res); 6053a5a1b3Sopenharmony_ci spx_mips++; 6153a5a1b3Sopenharmony_ci return res; 6253a5a1b3Sopenharmony_ci} 6353a5a1b3Sopenharmony_cistatic inline int NEG32(long long x) 6453a5a1b3Sopenharmony_ci{ 6553a5a1b3Sopenharmony_ci long long res; 6653a5a1b3Sopenharmony_ci if (!VERIFY_INT(x)) 6753a5a1b3Sopenharmony_ci { 6853a5a1b3Sopenharmony_ci fprintf (stderr, "NEG16: input is not int: %d\n", (int)x); 6953a5a1b3Sopenharmony_ci } 7053a5a1b3Sopenharmony_ci res = -x; 7153a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 7253a5a1b3Sopenharmony_ci fprintf (stderr, "NEG16: output is not int: %d\n", (int)res); 7353a5a1b3Sopenharmony_ci spx_mips++; 7453a5a1b3Sopenharmony_ci return res; 7553a5a1b3Sopenharmony_ci} 7653a5a1b3Sopenharmony_ci 7753a5a1b3Sopenharmony_ci#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__) 7853a5a1b3Sopenharmony_cistatic inline short _EXTRACT16(int x, char *file, int line) 7953a5a1b3Sopenharmony_ci{ 8053a5a1b3Sopenharmony_ci int res; 8153a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(x)) 8253a5a1b3Sopenharmony_ci { 8353a5a1b3Sopenharmony_ci fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); 8453a5a1b3Sopenharmony_ci } 8553a5a1b3Sopenharmony_ci res = x; 8653a5a1b3Sopenharmony_ci spx_mips++; 8753a5a1b3Sopenharmony_ci return res; 8853a5a1b3Sopenharmony_ci} 8953a5a1b3Sopenharmony_ci 9053a5a1b3Sopenharmony_ci#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__) 9153a5a1b3Sopenharmony_cistatic inline int _EXTEND32(int x, char *file, int line) 9253a5a1b3Sopenharmony_ci{ 9353a5a1b3Sopenharmony_ci int res; 9453a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(x)) 9553a5a1b3Sopenharmony_ci { 9653a5a1b3Sopenharmony_ci fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); 9753a5a1b3Sopenharmony_ci } 9853a5a1b3Sopenharmony_ci res = x; 9953a5a1b3Sopenharmony_ci spx_mips++; 10053a5a1b3Sopenharmony_ci return res; 10153a5a1b3Sopenharmony_ci} 10253a5a1b3Sopenharmony_ci 10353a5a1b3Sopenharmony_ci#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__) 10453a5a1b3Sopenharmony_cistatic inline short _SHR16(int a, int shift, char *file, int line) 10553a5a1b3Sopenharmony_ci{ 10653a5a1b3Sopenharmony_ci int res; 10753a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) 10853a5a1b3Sopenharmony_ci { 10953a5a1b3Sopenharmony_ci fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); 11053a5a1b3Sopenharmony_ci } 11153a5a1b3Sopenharmony_ci res = a>>shift; 11253a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 11353a5a1b3Sopenharmony_ci fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); 11453a5a1b3Sopenharmony_ci spx_mips++; 11553a5a1b3Sopenharmony_ci return res; 11653a5a1b3Sopenharmony_ci} 11753a5a1b3Sopenharmony_ci#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__) 11853a5a1b3Sopenharmony_cistatic inline short _SHL16(int a, int shift, char *file, int line) 11953a5a1b3Sopenharmony_ci{ 12053a5a1b3Sopenharmony_ci int res; 12153a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) 12253a5a1b3Sopenharmony_ci { 12353a5a1b3Sopenharmony_ci fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); 12453a5a1b3Sopenharmony_ci } 12553a5a1b3Sopenharmony_ci res = a<<shift; 12653a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 12753a5a1b3Sopenharmony_ci fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line); 12853a5a1b3Sopenharmony_ci spx_mips++; 12953a5a1b3Sopenharmony_ci return res; 13053a5a1b3Sopenharmony_ci} 13153a5a1b3Sopenharmony_ci 13253a5a1b3Sopenharmony_cistatic inline int SHR32(long long a, int shift) 13353a5a1b3Sopenharmony_ci{ 13453a5a1b3Sopenharmony_ci long long res; 13553a5a1b3Sopenharmony_ci if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) 13653a5a1b3Sopenharmony_ci { 13753a5a1b3Sopenharmony_ci fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift); 13853a5a1b3Sopenharmony_ci } 13953a5a1b3Sopenharmony_ci res = a>>shift; 14053a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 14153a5a1b3Sopenharmony_ci { 14253a5a1b3Sopenharmony_ci fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); 14353a5a1b3Sopenharmony_ci } 14453a5a1b3Sopenharmony_ci spx_mips++; 14553a5a1b3Sopenharmony_ci return res; 14653a5a1b3Sopenharmony_ci} 14753a5a1b3Sopenharmony_cistatic inline int SHL32(long long a, int shift) 14853a5a1b3Sopenharmony_ci{ 14953a5a1b3Sopenharmony_ci long long res; 15053a5a1b3Sopenharmony_ci if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) 15153a5a1b3Sopenharmony_ci { 15253a5a1b3Sopenharmony_ci fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift); 15353a5a1b3Sopenharmony_ci } 15453a5a1b3Sopenharmony_ci res = a<<shift; 15553a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 15653a5a1b3Sopenharmony_ci { 15753a5a1b3Sopenharmony_ci fprintf (stderr, "SHL32: output is not int: %d\n", (int)res); 15853a5a1b3Sopenharmony_ci } 15953a5a1b3Sopenharmony_ci spx_mips++; 16053a5a1b3Sopenharmony_ci return res; 16153a5a1b3Sopenharmony_ci} 16253a5a1b3Sopenharmony_ci 16353a5a1b3Sopenharmony_ci#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift)) 16453a5a1b3Sopenharmony_ci#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift)) 16553a5a1b3Sopenharmony_ci#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) 16653a5a1b3Sopenharmony_ci 16753a5a1b3Sopenharmony_ci#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) 16853a5a1b3Sopenharmony_ci#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) 16953a5a1b3Sopenharmony_ci 17053a5a1b3Sopenharmony_ci//#define SHR(a,shift) ((a) >> (shift)) 17153a5a1b3Sopenharmony_ci//#define SHL(a,shift) ((a) << (shift)) 17253a5a1b3Sopenharmony_ci 17353a5a1b3Sopenharmony_ci#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__) 17453a5a1b3Sopenharmony_cistatic inline short _ADD16(int a, int b, char *file, int line) 17553a5a1b3Sopenharmony_ci{ 17653a5a1b3Sopenharmony_ci int res; 17753a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 17853a5a1b3Sopenharmony_ci { 17953a5a1b3Sopenharmony_ci fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 18053a5a1b3Sopenharmony_ci } 18153a5a1b3Sopenharmony_ci res = a+b; 18253a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 18353a5a1b3Sopenharmony_ci { 18453a5a1b3Sopenharmony_ci fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line); 18553a5a1b3Sopenharmony_ci } 18653a5a1b3Sopenharmony_ci spx_mips++; 18753a5a1b3Sopenharmony_ci return res; 18853a5a1b3Sopenharmony_ci} 18953a5a1b3Sopenharmony_ci 19053a5a1b3Sopenharmony_ci#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__) 19153a5a1b3Sopenharmony_cistatic inline short _SUB16(int a, int b, char *file, int line) 19253a5a1b3Sopenharmony_ci{ 19353a5a1b3Sopenharmony_ci int res; 19453a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 19553a5a1b3Sopenharmony_ci { 19653a5a1b3Sopenharmony_ci fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 19753a5a1b3Sopenharmony_ci } 19853a5a1b3Sopenharmony_ci res = a-b; 19953a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 20053a5a1b3Sopenharmony_ci fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line); 20153a5a1b3Sopenharmony_ci spx_mips++; 20253a5a1b3Sopenharmony_ci return res; 20353a5a1b3Sopenharmony_ci} 20453a5a1b3Sopenharmony_ci 20553a5a1b3Sopenharmony_ci#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__) 20653a5a1b3Sopenharmony_cistatic inline int _ADD32(long long a, long long b, char *file, int line) 20753a5a1b3Sopenharmony_ci{ 20853a5a1b3Sopenharmony_ci long long res; 20953a5a1b3Sopenharmony_ci if (!VERIFY_INT(a) || !VERIFY_INT(b)) 21053a5a1b3Sopenharmony_ci { 21153a5a1b3Sopenharmony_ci fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 21253a5a1b3Sopenharmony_ci } 21353a5a1b3Sopenharmony_ci res = a+b; 21453a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 21553a5a1b3Sopenharmony_ci { 21653a5a1b3Sopenharmony_ci fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line); 21753a5a1b3Sopenharmony_ci } 21853a5a1b3Sopenharmony_ci spx_mips++; 21953a5a1b3Sopenharmony_ci return res; 22053a5a1b3Sopenharmony_ci} 22153a5a1b3Sopenharmony_ci 22253a5a1b3Sopenharmony_cistatic inline int SUB32(long long a, long long b) 22353a5a1b3Sopenharmony_ci{ 22453a5a1b3Sopenharmony_ci long long res; 22553a5a1b3Sopenharmony_ci if (!VERIFY_INT(a) || !VERIFY_INT(b)) 22653a5a1b3Sopenharmony_ci { 22753a5a1b3Sopenharmony_ci fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b); 22853a5a1b3Sopenharmony_ci } 22953a5a1b3Sopenharmony_ci res = a-b; 23053a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 23153a5a1b3Sopenharmony_ci fprintf (stderr, "SUB32: output is not int: %d\n", (int)res); 23253a5a1b3Sopenharmony_ci spx_mips++; 23353a5a1b3Sopenharmony_ci return res; 23453a5a1b3Sopenharmony_ci} 23553a5a1b3Sopenharmony_ci 23653a5a1b3Sopenharmony_ci#define ADD64(a,b) (MIPS_INC(a)+(b)) 23753a5a1b3Sopenharmony_ci 23853a5a1b3Sopenharmony_ci/* result fits in 16 bits */ 23953a5a1b3Sopenharmony_cistatic inline short MULT16_16_16(int a, int b) 24053a5a1b3Sopenharmony_ci{ 24153a5a1b3Sopenharmony_ci int res; 24253a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 24353a5a1b3Sopenharmony_ci { 24453a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b); 24553a5a1b3Sopenharmony_ci } 24653a5a1b3Sopenharmony_ci res = a*b; 24753a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 24853a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res); 24953a5a1b3Sopenharmony_ci spx_mips++; 25053a5a1b3Sopenharmony_ci return res; 25153a5a1b3Sopenharmony_ci} 25253a5a1b3Sopenharmony_ci 25353a5a1b3Sopenharmony_ci#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__) 25453a5a1b3Sopenharmony_cistatic inline int _MULT16_16(int a, int b, char *file, int line) 25553a5a1b3Sopenharmony_ci{ 25653a5a1b3Sopenharmony_ci long long res; 25753a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 25853a5a1b3Sopenharmony_ci { 25953a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 26053a5a1b3Sopenharmony_ci } 26153a5a1b3Sopenharmony_ci res = ((long long)a)*b; 26253a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 26353a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line); 26453a5a1b3Sopenharmony_ci spx_mips++; 26553a5a1b3Sopenharmony_ci return res; 26653a5a1b3Sopenharmony_ci} 26753a5a1b3Sopenharmony_ci 26853a5a1b3Sopenharmony_ci#define MAC16_16(c,a,b) (spx_mips--,ADD32((c),MULT16_16((a),(b)))) 26953a5a1b3Sopenharmony_ci#define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11))))) 27053a5a1b3Sopenharmony_ci#define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13))))) 27153a5a1b3Sopenharmony_ci#define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13)))) 27253a5a1b3Sopenharmony_ci 27353a5a1b3Sopenharmony_ci 27453a5a1b3Sopenharmony_ci#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__) 27553a5a1b3Sopenharmony_cistatic inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line) 27653a5a1b3Sopenharmony_ci{ 27753a5a1b3Sopenharmony_ci long long res; 27853a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) 27953a5a1b3Sopenharmony_ci { 28053a5a1b3Sopenharmony_ci 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); 28153a5a1b3Sopenharmony_ci } 28253a5a1b3Sopenharmony_ci if (ABS32(b)>=(EXTEND32(1)<<(15+Q))) 28353a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); 28453a5a1b3Sopenharmony_ci res = (((long long)a)*(long long)b) >> Q; 28553a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 28653a5a1b3Sopenharmony_ci 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); 28753a5a1b3Sopenharmony_ci spx_mips+=5; 28853a5a1b3Sopenharmony_ci return res; 28953a5a1b3Sopenharmony_ci} 29053a5a1b3Sopenharmony_ci 29153a5a1b3Sopenharmony_cistatic inline int MULT16_32_PX(int a, long long b, int Q) 29253a5a1b3Sopenharmony_ci{ 29353a5a1b3Sopenharmony_ci long long res; 29453a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) 29553a5a1b3Sopenharmony_ci { 29653a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b); 29753a5a1b3Sopenharmony_ci } 29853a5a1b3Sopenharmony_ci if (ABS32(b)>=(EXTEND32(1)<<(15+Q))) 29953a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b); 30053a5a1b3Sopenharmony_ci res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<<Q)>>1))>> Q; 30153a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 30253a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res); 30353a5a1b3Sopenharmony_ci spx_mips+=5; 30453a5a1b3Sopenharmony_ci return res; 30553a5a1b3Sopenharmony_ci} 30653a5a1b3Sopenharmony_ci 30753a5a1b3Sopenharmony_ci 30853a5a1b3Sopenharmony_ci#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11) 30953a5a1b3Sopenharmony_ci#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b))) 31053a5a1b3Sopenharmony_ci#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12) 31153a5a1b3Sopenharmony_ci#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13) 31253a5a1b3Sopenharmony_ci#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14) 31353a5a1b3Sopenharmony_ci#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) 31453a5a1b3Sopenharmony_ci#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15) 31553a5a1b3Sopenharmony_ci#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b))) 31653a5a1b3Sopenharmony_ci 31753a5a1b3Sopenharmony_cistatic inline int SATURATE(int a, int b) 31853a5a1b3Sopenharmony_ci{ 31953a5a1b3Sopenharmony_ci if (a>b) 32053a5a1b3Sopenharmony_ci a=b; 32153a5a1b3Sopenharmony_ci if (a<-b) 32253a5a1b3Sopenharmony_ci a = -b; 32353a5a1b3Sopenharmony_ci return a; 32453a5a1b3Sopenharmony_ci} 32553a5a1b3Sopenharmony_ci 32653a5a1b3Sopenharmony_cistatic inline int MULT16_16_Q11_32(int a, int b) 32753a5a1b3Sopenharmony_ci{ 32853a5a1b3Sopenharmony_ci long long res; 32953a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 33053a5a1b3Sopenharmony_ci { 33153a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b); 33253a5a1b3Sopenharmony_ci } 33353a5a1b3Sopenharmony_ci res = ((long long)a)*b; 33453a5a1b3Sopenharmony_ci res >>= 11; 33553a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 33653a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res); 33753a5a1b3Sopenharmony_ci spx_mips+=3; 33853a5a1b3Sopenharmony_ci return res; 33953a5a1b3Sopenharmony_ci} 34053a5a1b3Sopenharmony_cistatic inline short MULT16_16_Q13(int a, int b) 34153a5a1b3Sopenharmony_ci{ 34253a5a1b3Sopenharmony_ci long long res; 34353a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 34453a5a1b3Sopenharmony_ci { 34553a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b); 34653a5a1b3Sopenharmony_ci } 34753a5a1b3Sopenharmony_ci res = ((long long)a)*b; 34853a5a1b3Sopenharmony_ci res >>= 13; 34953a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 35053a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res); 35153a5a1b3Sopenharmony_ci spx_mips+=3; 35253a5a1b3Sopenharmony_ci return res; 35353a5a1b3Sopenharmony_ci} 35453a5a1b3Sopenharmony_cistatic inline short MULT16_16_Q14(int a, int b) 35553a5a1b3Sopenharmony_ci{ 35653a5a1b3Sopenharmony_ci long long res; 35753a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 35853a5a1b3Sopenharmony_ci { 35953a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b); 36053a5a1b3Sopenharmony_ci } 36153a5a1b3Sopenharmony_ci res = ((long long)a)*b; 36253a5a1b3Sopenharmony_ci res >>= 14; 36353a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 36453a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res); 36553a5a1b3Sopenharmony_ci spx_mips+=3; 36653a5a1b3Sopenharmony_ci return res; 36753a5a1b3Sopenharmony_ci} 36853a5a1b3Sopenharmony_cistatic inline short MULT16_16_Q15(int a, int b) 36953a5a1b3Sopenharmony_ci{ 37053a5a1b3Sopenharmony_ci long long res; 37153a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 37253a5a1b3Sopenharmony_ci { 37353a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b); 37453a5a1b3Sopenharmony_ci } 37553a5a1b3Sopenharmony_ci res = ((long long)a)*b; 37653a5a1b3Sopenharmony_ci res >>= 15; 37753a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 37853a5a1b3Sopenharmony_ci { 37953a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res); 38053a5a1b3Sopenharmony_ci } 38153a5a1b3Sopenharmony_ci spx_mips+=3; 38253a5a1b3Sopenharmony_ci return res; 38353a5a1b3Sopenharmony_ci} 38453a5a1b3Sopenharmony_ci 38553a5a1b3Sopenharmony_cistatic inline short MULT16_16_P13(int a, int b) 38653a5a1b3Sopenharmony_ci{ 38753a5a1b3Sopenharmony_ci long long res; 38853a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 38953a5a1b3Sopenharmony_ci { 39053a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b); 39153a5a1b3Sopenharmony_ci } 39253a5a1b3Sopenharmony_ci res = ((long long)a)*b; 39353a5a1b3Sopenharmony_ci res += 4096; 39453a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 39553a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res); 39653a5a1b3Sopenharmony_ci res >>= 13; 39753a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 39853a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res); 39953a5a1b3Sopenharmony_ci spx_mips+=4; 40053a5a1b3Sopenharmony_ci return res; 40153a5a1b3Sopenharmony_ci} 40253a5a1b3Sopenharmony_cistatic inline short MULT16_16_P14(int a, int b) 40353a5a1b3Sopenharmony_ci{ 40453a5a1b3Sopenharmony_ci long long res; 40553a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 40653a5a1b3Sopenharmony_ci { 40753a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b); 40853a5a1b3Sopenharmony_ci } 40953a5a1b3Sopenharmony_ci res = ((long long)a)*b; 41053a5a1b3Sopenharmony_ci res += 8192; 41153a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 41253a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res); 41353a5a1b3Sopenharmony_ci res >>= 14; 41453a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 41553a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res); 41653a5a1b3Sopenharmony_ci spx_mips+=4; 41753a5a1b3Sopenharmony_ci return res; 41853a5a1b3Sopenharmony_ci} 41953a5a1b3Sopenharmony_cistatic inline short MULT16_16_P15(int a, int b) 42053a5a1b3Sopenharmony_ci{ 42153a5a1b3Sopenharmony_ci long long res; 42253a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 42353a5a1b3Sopenharmony_ci { 42453a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b); 42553a5a1b3Sopenharmony_ci } 42653a5a1b3Sopenharmony_ci res = ((long long)a)*b; 42753a5a1b3Sopenharmony_ci res += 16384; 42853a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 42953a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res); 43053a5a1b3Sopenharmony_ci res >>= 15; 43153a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 43253a5a1b3Sopenharmony_ci fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res); 43353a5a1b3Sopenharmony_ci spx_mips+=4; 43453a5a1b3Sopenharmony_ci return res; 43553a5a1b3Sopenharmony_ci} 43653a5a1b3Sopenharmony_ci 43753a5a1b3Sopenharmony_ci#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__) 43853a5a1b3Sopenharmony_ci 43953a5a1b3Sopenharmony_cistatic inline int _DIV32_16(long long a, long long b, char *file, int line) 44053a5a1b3Sopenharmony_ci{ 44153a5a1b3Sopenharmony_ci long long res; 44253a5a1b3Sopenharmony_ci if (b==0) 44353a5a1b3Sopenharmony_ci { 44453a5a1b3Sopenharmony_ci fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); 44553a5a1b3Sopenharmony_ci return 0; 44653a5a1b3Sopenharmony_ci } 44753a5a1b3Sopenharmony_ci if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) 44853a5a1b3Sopenharmony_ci { 44953a5a1b3Sopenharmony_ci fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 45053a5a1b3Sopenharmony_ci } 45153a5a1b3Sopenharmony_ci res = a/b; 45253a5a1b3Sopenharmony_ci if (!VERIFY_SHORT(res)) 45353a5a1b3Sopenharmony_ci { 45453a5a1b3Sopenharmony_ci fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line); 45553a5a1b3Sopenharmony_ci if (res>32767) 45653a5a1b3Sopenharmony_ci res = 32767; 45753a5a1b3Sopenharmony_ci if (res<-32768) 45853a5a1b3Sopenharmony_ci res = -32768; 45953a5a1b3Sopenharmony_ci } 46053a5a1b3Sopenharmony_ci spx_mips+=20; 46153a5a1b3Sopenharmony_ci return res; 46253a5a1b3Sopenharmony_ci} 46353a5a1b3Sopenharmony_ci 46453a5a1b3Sopenharmony_ci#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__) 46553a5a1b3Sopenharmony_cistatic inline int _DIV32(long long a, long long b, char *file, int line) 46653a5a1b3Sopenharmony_ci{ 46753a5a1b3Sopenharmony_ci long long res; 46853a5a1b3Sopenharmony_ci if (b==0) 46953a5a1b3Sopenharmony_ci { 47053a5a1b3Sopenharmony_ci fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); 47153a5a1b3Sopenharmony_ci return 0; 47253a5a1b3Sopenharmony_ci } 47353a5a1b3Sopenharmony_ci 47453a5a1b3Sopenharmony_ci if (!VERIFY_INT(a) || !VERIFY_INT(b)) 47553a5a1b3Sopenharmony_ci { 47653a5a1b3Sopenharmony_ci fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 47753a5a1b3Sopenharmony_ci } 47853a5a1b3Sopenharmony_ci res = a/b; 47953a5a1b3Sopenharmony_ci if (!VERIFY_INT(res)) 48053a5a1b3Sopenharmony_ci fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); 48153a5a1b3Sopenharmony_ci spx_mips+=36; 48253a5a1b3Sopenharmony_ci return res; 48353a5a1b3Sopenharmony_ci} 48453a5a1b3Sopenharmony_ci#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b) 48553a5a1b3Sopenharmony_ci#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b) 48653a5a1b3Sopenharmony_ci 48753a5a1b3Sopenharmony_ci#endif 488