Merge commit 'silk-repo/master'
[opus.git] / src_SigProc_FIX / SKP_Silk_MacroDebug.h
1 /***********************************************************************\r
2 Copyright (c) 2006-2011, Skype Limited. All rights reserved. \r
3 Redistribution and use in source and binary forms, with or without \r
4 modification, (subject to the limitations in the disclaimer below) \r
5 are permitted provided that the following conditions are met:\r
6 - Redistributions of source code must retain the above copyright notice,\r
7 this list of conditions and the following disclaimer.\r
8 - Redistributions in binary form must reproduce the above copyright \r
9 notice, this list of conditions and the following disclaimer in the \r
10 documentation and/or other materials provided with the distribution.\r
11 - Neither the name of Skype Limited, nor the names of specific \r
12 contributors, may be used to endorse or promote products derived from \r
13 this software without specific prior written permission.\r
14 NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
15 BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
16 CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
17 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
18 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
19 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
22 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
23 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
26 ***********************************************************************/\r
27 \r
28 #ifndef _SIGPROCFIX_API_DEBUG_H_\r
29 #define _SIGPROCFIX_API_DEBUG_H_\r
30 \r
31 // Redefine macro functions with extensive assertion in Win32_DEBUG mode. \r
32 // As function can't be undefined, this file can't work with SigProcFIX_MacroCount.h\r
33 \r
34 #if 0 && defined (_WIN32) && defined (_DEBUG) && !defined (SKP_MACRO_COUNT)\r
35 \r
36 #undef  SKP_ADD16\r
37 SKP_INLINE SKP_int16 SKP_ADD16(SKP_int16 a, SKP_int16 b){\r
38         SKP_int16 ret;\r
39 \r
40         ret = a + b;\r
41         SKP_assert( ret == SKP_ADD_SAT16( a, b ));\r
42         return ret;\r
43 }\r
44 \r
45 #undef  SKP_ADD32\r
46 SKP_INLINE SKP_int32 SKP_ADD32(SKP_int32 a, SKP_int32 b){\r
47         SKP_int32 ret;\r
48 \r
49         ret = a + b;\r
50         SKP_assert( ret == SKP_ADD_SAT32( a, b ));\r
51         return ret;\r
52 }\r
53 \r
54 #undef  SKP_ADD64\r
55 SKP_INLINE SKP_int64 SKP_ADD64(SKP_int64 a, SKP_int64 b){\r
56         SKP_int64 ret;\r
57 \r
58         ret = a + b;\r
59         SKP_assert( ret == SKP_ADD_SAT64( a, b ));\r
60         return ret;\r
61 }\r
62 \r
63 #undef  SKP_SUB16\r
64 SKP_INLINE SKP_int16 SKP_SUB16(SKP_int16 a, SKP_int16 b){\r
65         SKP_int16 ret;\r
66 \r
67         ret = a - b;\r
68         SKP_assert( ret == SKP_SUB_SAT16( a, b ));\r
69         return ret;\r
70 }\r
71 \r
72 #undef  SKP_SUB32\r
73 SKP_INLINE SKP_int32 SKP_SUB32(SKP_int32 a, SKP_int32 b){\r
74         SKP_int32 ret;\r
75 \r
76         ret = a - b;\r
77         SKP_assert( ret == SKP_SUB_SAT32( a, b ));\r
78         return ret;\r
79 }\r
80 \r
81 #undef  SKP_SUB64\r
82 SKP_INLINE SKP_int64 SKP_SUB64(SKP_int64 a, SKP_int64 b){\r
83         SKP_int64 ret;\r
84 \r
85         ret = a - b;\r
86         SKP_assert( ret == SKP_SUB_SAT64( a, b ));\r
87         return ret;\r
88 }\r
89 \r
90 #undef SKP_ADD_SAT16\r
91 SKP_INLINE SKP_int16 SKP_ADD_SAT16( SKP_int16 a16, SKP_int16 b16 ) {\r
92         SKP_int16 res;\r
93         res = (SKP_int16)SKP_SAT16( SKP_ADD32( (SKP_int32)(a16), (b16) ) );\r
94         SKP_assert( res == SKP_SAT16( ( SKP_int32 )a16 + ( SKP_int32 )b16 ) );\r
95         return res;\r
96 }\r
97 \r
98 #undef SKP_ADD_SAT32\r
99 SKP_INLINE SKP_int32 SKP_ADD_SAT32(SKP_int32 a32, SKP_int32 b32){\r
100         SKP_int32 res;\r
101         res =   ((((a32) + (b32)) & 0x80000000) == 0 ?                                                                  \\r
102                         ((((a32) & (b32)) & 0x80000000) != 0 ? SKP_int32_MIN : (a32)+(b32)) :   \\r
103                         ((((a32) | (b32)) & 0x80000000) == 0 ? SKP_int32_MAX : (a32)+(b32)) );\r
104         SKP_assert( res == SKP_SAT32( ( SKP_int64 )a32 + ( SKP_int64 )b32 ) );\r
105         return res;\r
106 }\r
107 \r
108 #undef SKP_ADD_SAT64\r
109 SKP_INLINE SKP_int64 SKP_ADD_SAT64( SKP_int64 a64, SKP_int64 b64 ) {\r
110         SKP_int64 res;\r
111         res =   ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ?                                                                \\r
112                         ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? SKP_int64_MIN : (a64)+(b64)) : \\r
113                         ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? SKP_int64_MAX : (a64)+(b64)) );\r
114         if( res != a64 + b64 ) {\r
115                 // Check that we saturated to the correct extreme value\r
116                 SKP_assert( ( res == SKP_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( SKP_int64_MAX >> 3 ) ) ) ||\r
117                                         ( res == SKP_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( SKP_int64_MIN >> 3 ) ) ) );\r
118         } else {\r
119                 // Saturation not necessary\r
120                 SKP_assert( res == a64 + b64 );\r
121         }\r
122         return res;\r
123 }\r
124 \r
125 #undef SKP_SUB_SAT16\r
126 SKP_INLINE SKP_int16 SKP_SUB_SAT16( SKP_int16 a16, SKP_int16 b16 ) {\r
127         SKP_int16 res;\r
128         res = (SKP_int16)SKP_SAT16( SKP_SUB32( (SKP_int32)(a16), (b16) ) );\r
129         SKP_assert( res == SKP_SAT16( ( SKP_int32 )a16 - ( SKP_int32 )b16 ) );\r
130         return res;\r
131 }\r
132 \r
133 #undef SKP_SUB_SAT32\r
134 SKP_INLINE SKP_int32 SKP_SUB_SAT32( SKP_int32 a32, SKP_int32 b32 ) {\r
135         SKP_int32 res;\r
136         res =   ((((a32)-(b32)) & 0x80000000) == 0 ?                                                                                    \\r
137                         (( (a32) & ((b32)^0x80000000) & 0x80000000) ? SKP_int32_MIN : (a32)-(b32)) :    \\r
138                         ((((a32)^0x80000000) & (b32)  & 0x80000000) ? SKP_int32_MAX : (a32)-(b32)) );\r
139         SKP_assert( res == SKP_SAT32( ( SKP_int64 )a32 - ( SKP_int64 )b32 ) );\r
140         return res;\r
141 }\r
142 \r
143 #undef SKP_SUB_SAT64\r
144 SKP_INLINE SKP_int64 SKP_SUB_SAT64( SKP_int64 a64, SKP_int64 b64 ) {\r
145         SKP_int64 res;\r
146         res =   ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ?                                                                                                          \\r
147                         (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? SKP_int64_MIN : (a64)-(b64)) :        \\r
148                         ((((a64)^0x8000000000000000LL) & (b64)  & 0x8000000000000000LL) ? SKP_int64_MAX : (a64)-(b64)) );\r
149 \r
150         if( res != a64 - b64 ) {\r
151                 // Check that we saturated to the correct extreme value\r
152                 SKP_assert( ( res == SKP_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( SKP_int64_MAX >> 3 ) ) ) ||\r
153                                         ( res == SKP_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( SKP_int64_MIN >> 3 ) ) ) );\r
154         } else {\r
155                 // Saturation not necessary\r
156                 SKP_assert( res == a64 - b64 );\r
157         }\r
158         return res;\r
159 }\r
160 \r
161 #undef SKP_MUL\r
162 SKP_INLINE SKP_int32 SKP_MUL(SKP_int32 a32, SKP_int32 b32){\r
163         SKP_int32 ret;\r
164         SKP_int64 ret64; // Will easily show how many bits that are needed\r
165         ret = a32 * b32;\r
166         ret64 = (SKP_int64)a32 * (SKP_int64)b32; \r
167         SKP_assert((SKP_int64)ret == ret64 );           //Check output overflow\r
168         return ret;\r
169 }\r
170 \r
171 #undef SKP_MUL_uint\r
172 SKP_INLINE SKP_uint32 SKP_MUL_uint(SKP_uint32 a32, SKP_uint32 b32){\r
173         SKP_uint32 ret;\r
174         ret = a32 * b32;\r
175         SKP_assert((SKP_uint64)ret == (SKP_uint64)a32 * (SKP_uint64)b32);               //Check output overflow\r
176         return ret;\r
177 }\r
178 #undef SKP_MLA\r
179 SKP_INLINE SKP_int32 SKP_MLA(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32){\r
180         SKP_int32 ret;\r
181         ret = a32 + b32 * c32;\r
182         SKP_assert((SKP_int64)ret == (SKP_int64)a32 + (SKP_int64)b32 * (SKP_int64)c32); //Check output overflow\r
183         return ret;\r
184 }\r
185 \r
186 #undef SKP_MLA_uint\r
187 SKP_INLINE SKP_int32 SKP_MLA_uint(SKP_uint32 a32, SKP_uint32 b32, SKP_uint32 c32){\r
188         SKP_uint32 ret;\r
189         ret = a32 + b32 * c32;\r
190         SKP_assert((SKP_int64)ret == (SKP_int64)a32 + (SKP_int64)b32 * (SKP_int64)c32); //Check output overflow\r
191         return ret;\r
192 }\r
193 \r
194 #undef  SKP_SMULWB\r
195 SKP_INLINE SKP_int32 SKP_SMULWB(SKP_int32 a32, SKP_int32 b32){  \r
196         SKP_int32 ret;\r
197         ret = (a32 >> 16) * (SKP_int32)((SKP_int16)b32) + (((a32 & 0x0000FFFF) * (SKP_int32)((SKP_int16)b32)) >> 16);\r
198         SKP_assert((SKP_int64)ret == ((SKP_int64)a32 * (SKP_int16)b32) >> 16);\r
199         return ret;\r
200 }\r
201 #undef  SKP_SMLAWB\r
202 SKP_INLINE SKP_int32 SKP_SMLAWB(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32){   \r
203         SKP_int32 ret;\r
204         ret = SKP_ADD32( a32, SKP_SMULWB( b32, c32 ) );\r
205         SKP_assert(SKP_ADD32( a32, SKP_SMULWB( b32, c32 ) ) == SKP_ADD_SAT32( a32, SKP_SMULWB( b32, c32 ) ));\r
206         return ret;\r
207 }\r
208 \r
209 #undef SKP_SMULWT\r
210 SKP_INLINE SKP_int32 SKP_SMULWT(SKP_int32 a32, SKP_int32 b32){\r
211         SKP_int32 ret;\r
212         ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16);\r
213         SKP_assert((SKP_int64)ret == ((SKP_int64)a32 * (b32 >> 16)) >> 16);\r
214         return ret;\r
215 }\r
216 #undef SKP_SMLAWT\r
217 SKP_INLINE SKP_int32 SKP_SMLAWT(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32){\r
218         SKP_int32 ret;\r
219         ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16));\r
220         SKP_assert((SKP_int64)ret == (SKP_int64)a32 + (((SKP_int64)b32 * (c32 >> 16)) >> 16));\r
221         return ret;\r
222 }\r
223 \r
224 #undef SKP_SMULL\r
225 SKP_INLINE SKP_int64 SKP_SMULL(SKP_int64 a64, SKP_int64 b64){\r
226         SKP_int64 ret64;\r
227         ret64 = a64 * b64;\r
228         if( b64 != 0 ) {\r
229                 SKP_assert( a64 == (ret64 / b64) );\r
230         } else if( a64 != 0 ) {\r
231                 SKP_assert( b64 == (ret64 / a64) );\r
232         }\r
233         return ret64;\r
234 }\r
235 \r
236 // no checking needed for SKP_SMULBB\r
237 #undef  SKP_SMLABB\r
238 SKP_INLINE SKP_int32 SKP_SMLABB(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32){\r
239         SKP_int32 ret;\r
240         ret = a32 + (SKP_int32)((SKP_int16)b32) * (SKP_int32)((SKP_int16)c32);\r
241         SKP_assert((SKP_int64)ret == (SKP_int64)a32 + (SKP_int64)b32 * (SKP_int16)c32);\r
242         return ret;\r
243 }\r
244 \r
245 // no checking needed for SKP_SMULBT\r
246 #undef  SKP_SMLABT\r
247 SKP_INLINE SKP_int32 SKP_SMLABT(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32){\r
248         SKP_int32 ret;\r
249         ret = a32 + ((SKP_int32)((SKP_int16)b32)) * (c32 >> 16);\r
250         SKP_assert((SKP_int64)ret == (SKP_int64)a32 + (SKP_int64)b32 * (c32 >> 16));\r
251         return ret;\r
252 }\r
253 \r
254 // no checking needed for SKP_SMULTT\r
255 #undef  SKP_SMLATT\r
256 SKP_INLINE SKP_int32 SKP_SMLATT(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32){\r
257         SKP_int32 ret;\r
258         ret = a32 + (b32 >> 16) * (c32 >> 16);\r
259         SKP_assert((SKP_int64)ret == (SKP_int64)a32 + (b32 >> 16) * (c32 >> 16));\r
260         return ret;\r
261 }\r
262 \r
263 #undef  SKP_SMULWW\r
264 SKP_INLINE SKP_int32 SKP_SMULWW(SKP_int32 a32, SKP_int32 b32){  \r
265         SKP_int32 ret, tmp1, tmp2;\r
266         SKP_int64 ret64;\r
267 \r
268         ret  = SKP_SMULWB( a32, b32 );\r
269         tmp1 = SKP_RSHIFT_ROUND( b32, 16 );\r
270         tmp2 = SKP_MUL( a32, tmp1 );\r
271         \r
272         SKP_assert( (SKP_int64)tmp2 == (SKP_int64) a32 * (SKP_int64) tmp1 );\r
273         \r
274         tmp1 = ret;\r
275         ret  = SKP_ADD32( tmp1, tmp2 );\r
276         SKP_assert( SKP_ADD32( tmp1, tmp2 ) == SKP_ADD_SAT32( tmp1, tmp2 ) );\r
277         \r
278         ret64 = SKP_RSHIFT64( SKP_SMULL( a32, b32 ), 16 );\r
279         SKP_assert( (SKP_int64)ret == ret64 );\r
280 \r
281         return ret;\r
282 }\r
283 \r
284 #undef  SKP_SMLAWW\r
285 SKP_INLINE SKP_int32 SKP_SMLAWW(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32){   \r
286         SKP_int32 ret, tmp;\r
287 \r
288         tmp = SKP_SMULWW( b32, c32 );\r
289         ret = SKP_ADD32( a32, tmp );\r
290         SKP_assert( ret == SKP_ADD_SAT32( a32, tmp ) ); \r
291         return ret;\r
292 }\r
293 \r
294 // multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)\r
295 #undef  SKP_MLA_ovflw\r
296 #define SKP_MLA_ovflw(a32, b32, c32)    ((a32) + ((b32) * (c32)))\r
297 #undef  SKP_SMLABB_ovflw\r
298 #define SKP_SMLABB_ovflw(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * (SKP_int32)((SKP_int16)(c32)))\r
299 #undef  SKP_SMLABT_ovflw\r
300 #define SKP_SMLABT_ovflw(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * ((c32) >> 16))\r
301 #undef  SKP_SMLATT_ovflw\r
302 #define SKP_SMLATT_ovflw(a32, b32, c32) ((a32) + ((b32) >> 16) * ((c32) >> 16))\r
303 #undef  SKP_SMLAWB_ovflw\r
304 #define SKP_SMLAWB_ovflw(a32, b32, c32) ((a32) + ((((b32) >> 16) * (SKP_int32)((SKP_int16)(c32))) + ((((b32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(c32))) >> 16)))\r
305 #undef  SKP_SMLAWT_ovflw\r
306 #define SKP_SMLAWT_ovflw(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))\r
307 \r
308 // no checking needed for SKP_SMULL\r
309 // no checking needed for SKP_SMLAL\r
310 // no checking needed for SKP_SMLALBB\r
311 // no checking needed for SigProcFIX_CLZ16\r
312 // no checking needed for SigProcFIX_CLZ32\r
313 \r
314 #undef SKP_DIV32\r
315 SKP_INLINE SKP_int32 SKP_DIV32(SKP_int32 a32, SKP_int32 b32){\r
316         SKP_assert( b32 != 0 );\r
317         return a32 / b32;\r
318 }\r
319 \r
320 #undef SKP_DIV32_16\r
321 SKP_INLINE SKP_int32 SKP_DIV32_16(SKP_int32 a32, SKP_int32 b32){\r
322         SKP_assert( b32 != 0 );\r
323         SKP_assert( b32 <= SKP_int16_MAX );\r
324         SKP_assert( b32 >= SKP_int16_MIN );\r
325         return a32 / b32;\r
326 }\r
327 \r
328 // no checking needed for SKP_SAT8\r
329 // no checking needed for SKP_SAT16\r
330 // no checking needed for SKP_SAT32\r
331 // no checking needed for SKP_POS_SAT32\r
332 // no checking needed for SKP_ADD_POS_SAT8\r
333 // no checking needed for SKP_ADD_POS_SAT16\r
334 // no checking needed for SKP_ADD_POS_SAT32\r
335 // no checking needed for SKP_ADD_POS_SAT64\r
336 #undef  SKP_LSHIFT8\r
337 SKP_INLINE SKP_int8 SKP_LSHIFT8(SKP_int8 a, SKP_int32 shift){\r
338         SKP_int8 ret;\r
339         ret = a << shift;\r
340         SKP_assert(shift >= 0);\r
341         SKP_assert(shift < 8);\r
342         SKP_assert((SKP_int64)ret == ((SKP_int64)a) << shift);\r
343         return ret;\r
344 }\r
345 #undef  SKP_LSHIFT16\r
346 SKP_INLINE SKP_int16 SKP_LSHIFT16(SKP_int16 a, SKP_int32 shift){\r
347         SKP_int16 ret;\r
348         ret = a << shift;\r
349         SKP_assert(shift >= 0);\r
350         SKP_assert(shift < 16);\r
351         SKP_assert((SKP_int64)ret == ((SKP_int64)a) << shift);\r
352         return ret;\r
353 }\r
354 #undef  SKP_LSHIFT32\r
355 SKP_INLINE SKP_int32 SKP_LSHIFT32(SKP_int32 a, SKP_int32 shift){\r
356         SKP_int32 ret;\r
357         ret = a << shift;\r
358         SKP_assert(shift >= 0);\r
359         SKP_assert(shift < 32);\r
360         SKP_assert((SKP_int64)ret == ((SKP_int64)a) << shift);\r
361         return ret;\r
362 }\r
363 #undef  SKP_LSHIFT64\r
364 SKP_INLINE SKP_int64 SKP_LSHIFT64(SKP_int64 a, SKP_int shift){\r
365         SKP_assert(shift >= 0);\r
366         SKP_assert(shift < 64);\r
367         return a << shift;\r
368 }\r
369 \r
370 #undef  SKP_LSHIFT_ovflw\r
371 SKP_INLINE SKP_int32 SKP_LSHIFT_ovflw(SKP_int32 a, SKP_int32 shift){\r
372         SKP_assert(shift >= 0);                 /* no check for overflow */\r
373         return a << shift;\r
374 }\r
375 \r
376 #undef  SKP_LSHIFT_uint\r
377 SKP_INLINE SKP_uint32 SKP_LSHIFT_uint(SKP_uint32 a, SKP_int32 shift){\r
378         SKP_uint32 ret;\r
379         ret = a << shift;\r
380         SKP_assert(shift >= 0);\r
381         SKP_assert((SKP_int64)ret == ((SKP_int64)a) << shift);\r
382         return ret;\r
383 }\r
384 \r
385 #undef  SKP_RSHIFT8\r
386 SKP_INLINE SKP_int8 SKP_RSHIFT8(SKP_int8 a, SKP_int32 shift){\r
387         SKP_assert(shift >=  0);\r
388         SKP_assert(shift < 8);\r
389         return a >> shift;\r
390 }\r
391 #undef  SKP_RSHIFT16\r
392 SKP_INLINE SKP_int16 SKP_RSHIFT16(SKP_int16 a, SKP_int32 shift){\r
393         SKP_assert(shift >=  0);\r
394         SKP_assert(shift < 16);\r
395         return a >> shift;\r
396 }\r
397 #undef  SKP_RSHIFT32\r
398 SKP_INLINE SKP_int32 SKP_RSHIFT32(SKP_int32 a, SKP_int32 shift){\r
399         SKP_assert(shift >=  0);\r
400         SKP_assert(shift < 32);\r
401         return a >> shift;\r
402 }\r
403 #undef  SKP_RSHIFT64\r
404 SKP_INLINE SKP_int64 SKP_RSHIFT64(SKP_int64 a, SKP_int64 shift){\r
405         SKP_assert(shift >=  0);\r
406         SKP_assert(shift <= 63);\r
407         return a >> shift;\r
408 }\r
409 \r
410 #undef  SKP_RSHIFT_uint\r
411 SKP_INLINE SKP_uint32 SKP_RSHIFT_uint(SKP_uint32 a, SKP_int32 shift){\r
412         SKP_assert(shift >=  0);\r
413         SKP_assert(shift <= 32);\r
414         return a >> shift;\r
415 }\r
416 \r
417 #undef  SKP_ADD_LSHIFT\r
418 SKP_INLINE SKP_int32 SKP_ADD_LSHIFT(SKP_int32 a, SKP_int32 b, SKP_int32 shift){\r
419         SKP_int32 ret;\r
420         SKP_assert(shift >= 0);\r
421         SKP_assert(shift <= 31);\r
422         ret = a + (b << shift);\r
423         SKP_assert((SKP_int64)ret == (SKP_int64)a + (((SKP_int64)b) << shift));\r
424         return ret;                             // shift >= 0\r
425 }\r
426 #undef  SKP_ADD_LSHIFT32\r
427 SKP_INLINE SKP_int32 SKP_ADD_LSHIFT32(SKP_int32 a, SKP_int32 b, SKP_int32 shift){\r
428         SKP_int32 ret;\r
429         SKP_assert(shift >= 0);\r
430         SKP_assert(shift <= 31);\r
431         ret = a + (b << shift);\r
432         SKP_assert((SKP_int64)ret == (SKP_int64)a + (((SKP_int64)b) << shift));\r
433         return ret;                             // shift >= 0\r
434 }\r
435 #undef  SKP_ADD_LSHIFT_uint\r
436 SKP_INLINE SKP_uint32 SKP_ADD_LSHIFT_uint(SKP_uint32 a, SKP_uint32 b, SKP_int32 shift){\r
437         SKP_uint32 ret;\r
438         SKP_assert(shift >= 0);\r
439         SKP_assert(shift <= 32);\r
440         ret = a + (b << shift);\r
441         SKP_assert((SKP_int64)ret == (SKP_int64)a + (((SKP_int64)b) << shift));\r
442         return ret;                             // shift >= 0\r
443 }\r
444 #undef  SKP_ADD_RSHIFT\r
445 SKP_INLINE SKP_int32 SKP_ADD_RSHIFT(SKP_int32 a, SKP_int32 b, SKP_int32 shift){         \r
446         SKP_int32 ret;\r
447         SKP_assert(shift >= 0);\r
448         SKP_assert(shift <= 31);\r
449         ret = a + (b >> shift);\r
450         SKP_assert((SKP_int64)ret == (SKP_int64)a + (((SKP_int64)b) >> shift));\r
451         return ret;                             // shift  > 0\r
452 }\r
453 #undef  SKP_ADD_RSHIFT32\r
454 SKP_INLINE SKP_int32 SKP_ADD_RSHIFT32(SKP_int32 a, SKP_int32 b, SKP_int32 shift){               \r
455         SKP_int32 ret;\r
456         SKP_assert(shift >= 0);\r
457         SKP_assert(shift <= 31);\r
458         ret = a + (b >> shift);\r
459         SKP_assert((SKP_int64)ret == (SKP_int64)a + (((SKP_int64)b) >> shift));\r
460         return ret;                             // shift  > 0\r
461 }\r
462 #undef  SKP_ADD_RSHIFT_uint\r
463 SKP_INLINE SKP_uint32 SKP_ADD_RSHIFT_uint(SKP_uint32 a, SKP_uint32 b, SKP_int32 shift){         \r
464         SKP_uint32 ret;\r
465         SKP_assert(shift >= 0);\r
466         SKP_assert(shift <= 32);\r
467         ret = a + (b >> shift);\r
468         SKP_assert((SKP_int64)ret == (SKP_int64)a + (((SKP_int64)b) >> shift));\r
469         return ret;                             // shift  > 0\r
470 }\r
471 #undef  SKP_SUB_LSHIFT32\r
472 SKP_INLINE SKP_int32 SKP_SUB_LSHIFT32(SKP_int32 a, SKP_int32 b, SKP_int32 shift){\r
473         SKP_int32 ret;\r
474         SKP_assert(shift >= 0);\r
475         SKP_assert(shift <= 31);\r
476         ret = a - (b << shift);\r
477         SKP_assert((SKP_int64)ret == (SKP_int64)a - (((SKP_int64)b) << shift));\r
478         return ret;                             // shift >= 0\r
479 }\r
480 #undef  SKP_SUB_RSHIFT32\r
481 SKP_INLINE SKP_int32 SKP_SUB_RSHIFT32(SKP_int32 a, SKP_int32 b, SKP_int32 shift){               \r
482         SKP_int32 ret;\r
483         SKP_assert(shift >= 0);\r
484         SKP_assert(shift <= 31);\r
485         ret = a - (b >> shift);\r
486         SKP_assert((SKP_int64)ret == (SKP_int64)a - (((SKP_int64)b) >> shift));\r
487         return ret;                             // shift  > 0\r
488 }\r
489 \r
490 #undef  SKP_RSHIFT_ROUND\r
491 SKP_INLINE SKP_int32 SKP_RSHIFT_ROUND(SKP_int32 a, SKP_int32 shift){\r
492         SKP_int32 ret;\r
493         SKP_assert(shift > 0);          /* the marco definition can't handle a shift of zero */\r
494         SKP_assert(shift < 32);\r
495         ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;\r
496         SKP_assert((SKP_int64)ret == ((SKP_int64)a + ((SKP_int64)1 << (shift - 1))) >> shift);\r
497         return ret;\r
498 }\r
499 \r
500 #undef  SKP_RSHIFT_ROUND64\r
501 SKP_INLINE SKP_int64 SKP_RSHIFT_ROUND64(SKP_int64 a, SKP_int32 shift){\r
502         SKP_int64 ret;\r
503         SKP_assert(shift > 0);          /* the marco definition can't handle a shift of zero */\r
504         SKP_assert(shift < 64);\r
505         ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;\r
506         return ret;\r
507 }\r
508 \r
509 // SKP_abs is used on floats also, so doesn't work...\r
510 //#undef        SKP_abs\r
511 //SKP_INLINE SKP_int32 SKP_abs(SKP_int32 a){\r
512 //      SKP_assert(a != 0x80000000);\r
513 //      return (((a) >  0)  ? (a) : -(a));                      // Be careful, SKP_abs returns wrong when input equals to SKP_intXX_MIN\r
514 //}\r
515 \r
516 #undef  SKP_abs_int64\r
517 SKP_INLINE SKP_int64 SKP_abs_int64(SKP_int64 a){\r
518         SKP_assert(a != 0x8000000000000000);\r
519         return (((a) >  0)  ? (a) : -(a));                      // Be careful, SKP_abs returns wrong when input equals to SKP_intXX_MIN\r
520 }\r
521 \r
522 #undef  SKP_abs_int32\r
523 SKP_INLINE SKP_int32 SKP_abs_int32(SKP_int32 a){\r
524         SKP_assert(a != 0x80000000);\r
525         return abs(a);\r
526 }\r
527 \r
528 #undef  SKP_CHECK_FIT8\r
529 SKP_INLINE SKP_int8 SKP_CHECK_FIT8( SKP_int64 a ){\r
530         SKP_int8 ret;\r
531         ret = (SKP_int8)a;\r
532         SKP_assert( (SKP_int64)ret == a );\r
533         return( ret ); \r
534 }\r
535 \r
536 #undef  SKP_CHECK_FIT16\r
537 SKP_INLINE SKP_int16 SKP_CHECK_FIT16( SKP_int64 a ){\r
538         SKP_int16 ret;\r
539         ret = (SKP_int16)a;\r
540         SKP_assert( (SKP_int64)ret == a );\r
541         return( ret ); \r
542 }\r
543 \r
544 #undef  SKP_CHECK_FIT32\r
545 SKP_INLINE SKP_int32 SKP_CHECK_FIT32( SKP_int64 a ){\r
546         SKP_int32 ret;\r
547         ret = (SKP_int32)a;\r
548         SKP_assert( (SKP_int64)ret == a );\r
549         return( ret ); \r
550 }\r
551 \r
552 // no checking for SKP_NSHIFT_MUL_32_32\r
553 // no checking for SKP_NSHIFT_MUL_16_16 \r
554 // no checking needed for SKP_min\r
555 // no checking needed for SKP_max\r
556 // no checking needed for SKP_sign\r
557 \r
558 #endif\r
559 #endif\r