00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
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