basic_op.h revision e2e838afcf03e603a41a0455846eaf9614537c16
1/*
2 ** Copyright 2003-2010, VisualOn, Inc.
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 **     http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17
18#ifndef __BASIC_OP_H__
19#define __BASIC_OP_H__
20
21#include <stdio.h>
22#include <stdlib.h>
23#include "typedef.h"
24
25#define MAX_32 (Word32)0x7fffffffL
26#define MIN_32 (Word32)0x80000000L
27
28#define MAX_16 (Word16)+32767	/* 0x7fff */
29#define MIN_16 (Word16)-32768	/* 0x8000 */
30
31
32#ifdef LINUX
33#define  static_vo  static __inline__
34#else
35#define  static_vo  static __inline
36#endif
37
38#define saturate(L_var1) (((L_var1) > 0X00007fffL) ? (MAX_16): (((L_var1) < (Word32) 0xffff8000L) ? (MIN_16): ((L_var1) & 0xffff)))
39
40#define abs_s(x)       ((Word16)(((x) != MIN_16) ? (((x) >= 0) ? (x) : (-(x))) : MAX_16))  /* Short abs,           1   */
41#define L_deposit_h(x) (((Word32)(x)) << 16)                                               /* 16 bit var1 -> MSB,     2 */
42#define L_deposit_l(x) ((Word32)(x))                                                       /* 16 bit var1 -> LSB,     2 */
43#define L_abs(x) (((x) != MIN_32) ? (((x) >= 0) ? (x) : (-(x))) : MAX_32)                  /* Long abs,              3*/
44#define negate(var1) ((Word16)(((var1) == MIN_16) ? MAX_16 : (-(var1))))                   /* Short negate,        1*/
45#define L_negate(L_var1) (((L_var1) == (MIN_32)) ? (MAX_32) : (-(L_var1)))                 /* Long negate,     2*/
46
47
48#define extract_h(a)			((Word16)(a >> 16))
49#define extract_l(x)            	(Word16)((x))
50#define add1(a,b)			(a + b)
51#define vo_L_msu(a,b,c)			( a - (( b * c ) << 1) )
52#define vo_mult32(a, b)         ((a) * (b))
53#define vo_mult(a,b)			(( a * b ) >> 15 )
54#define	vo_L_mult(a,b)	    		(((a) * (b)) << 1)
55#define vo_shr_r(var1, var2)   		((var1+((Word16)(1L<<(var2-1))))>>var2)
56#define vo_sub(a,b)			(a - b)
57#define vo_L_deposit_h(a)		((Word32)((a) << 16))
58#define vo_round(a)			((a + 0x00008000) >> 16)
59#define vo_extract_l(a)			((Word16)(a))
60#define vo_L_add(a,b)			(a + b)
61#define vo_L_sub(a,b)			(a - b)
62#define vo_mult_r(a,b)			((( a * b ) + 0x4000 ) >> 15 )
63#define vo_negate(a)		        (-a)
64#define vo_L_shr_r(L_var1, var2)        ((L_var1+((Word32)(1L<<(var2-1))))>>var2)
65
66
67/*___________________________________________________________________________
68|                                                                           |
69|   Prototypes for basic arithmetic operators                               |
70|___________________________________________________________________________|
71*/
72static_vo Word16 add (Word16 var1, Word16 var2);				/* Short add,1 */
73static_vo Word16 sub (Word16 var1, Word16 var2);				/* Short sub,1 */
74static_vo Word16 shl (Word16 var1, Word16 var2);                                /* Short shift left,    1   */
75static_vo Word16 shr (Word16 var1, Word16 var2);                                /* Short shift right,   1   */
76static_vo Word16 mult (Word16 var1, Word16 var2);                               /* Short mult,          1   */
77static_vo Word32 L_mult (Word16 var1, Word16 var2);                             /* Long mult,           1   */
78static_vo Word16 voround (Word32 L_var1);                                       /* Round,               1   */
79static_vo Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);            	/* Mac,  1  */
80static_vo Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);   		/* Msu,  1  */
81static_vo Word32 L_add (Word32 L_var1, Word32 L_var2);   		 	/* Long add,        2 */
82static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2);   			/* Long sub,        2 */
83static_vo Word16 mult_r (Word16 var1, Word16 var2);      		 	/* Mult with round, 2 */
84static_vo Word32 L_shl2(Word32 L_var1, Word16 var2);             		/* var2 > 0*/
85static_vo Word32 L_shl (Word32 L_var1, Word16 var2);    	 	 	/* Long shift left, 2 */
86static_vo Word32 L_shr (Word32 L_var1, Word16 var2);    	 	 	/* Long shift right, 2*/
87static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2); 				/* Long shift right with round,  3   */
88static_vo Word16 norm_s (Word16 var1);             				/* Short norm,           15  */
89static_vo Word16 div_s (Word16 var1, Word16 var2); 				/* Short division,       18  */
90static_vo Word16 norm_l (Word32 L_var1);           				/* Long norm,            30  */
91
92/*___________________________________________________________________________
93|                                                                           |
94|   Functions                                                               |
95|___________________________________________________________________________|
96*/
97/*___________________________________________________________________________
98|                                                                           |
99|   Function Name : add                                                     |
100|                                                                           |
101|   Purpose :                                                               |
102|                                                                           |
103|    Performs the addition (var1+var2) with overflow control and saturation;|
104|    the 16 bit result is set at +32767 when overflow occurs or at -32768   |
105|    when underflow occurs.                                                 |
106|                                                                           |
107|   Complexity weight : 1                                                   |
108|                                                                           |
109|   Inputs :                                                                |
110|                                                                           |
111|    var1                                                                   |
112|             16 bit short signed integer (Word16) whose value falls in the |
113|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
114|                                                                           |
115|    var2                                                                   |
116|             16 bit short signed integer (Word16) whose value falls in the |
117|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
118|                                                                           |
119|   Outputs :                                                               |
120|                                                                           |
121|    none                                                                   |
122|                                                                           |
123|   Return Value :                                                          |
124|                                                                           |
125|    var_out                                                                |
126|             16 bit short signed integer (Word16) whose value falls in the |
127|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
128|___________________________________________________________________________|
129*/
130static_vo Word16 add (Word16 var1, Word16 var2)
131{
132	Word16 var_out;
133	Word32 L_sum;
134	L_sum = (Word32) var1 + var2;
135	var_out = saturate (L_sum);
136	return (var_out);
137}
138
139/*___________________________________________________________________________
140|                                                                           |
141|   Function Name : sub                                                     |
142|                                                                           |
143|   Purpose :                                                               |
144|                                                                           |
145|    Performs the subtraction (var1+var2) with overflow control and satu-   |
146|    ration; the 16 bit result is set at +32767 when overflow occurs or at  |
147|    -32768 when underflow occurs.                                          |
148|                                                                           |
149|   Complexity weight : 1                                                   |
150|                                                                           |
151|   Inputs :                                                                |
152|                                                                           |
153|    var1                                                                   |
154|             16 bit short signed integer (Word16) whose value falls in the |
155|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
156|                                                                           |
157|    var2                                                                   |
158|             16 bit short signed integer (Word16) whose value falls in the |
159|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
160|                                                                           |
161|   Outputs :                                                               |
162|                                                                           |
163|    none                                                                   |
164|                                                                           |
165|   Return Value :                                                          |
166|                                                                           |
167|    var_out                                                                |
168|             16 bit short signed integer (Word16) whose value falls in the |
169|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
170|___________________________________________________________________________|
171*/
172
173static_vo Word16 sub (Word16 var1, Word16 var2)
174{
175	Word16 var_out;
176	Word32 L_diff;
177	L_diff = (Word32) var1 - var2;
178	var_out = saturate (L_diff);
179	return (var_out);
180}
181
182/*___________________________________________________________________________
183|                                                                           |
184|   Function Name : shl                                                     |
185|                                                                           |
186|   Purpose :                                                               |
187|                                                                           |
188|   Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill|
189|   the var2 LSB of the result. If var2 is negative, arithmetically shift   |
190|   var1 right by -var2 with sign extension. Saturate the result in case of |
191|   underflows or overflows.                                                |
192|                                                                           |
193|   Complexity weight : 1                                                   |
194|                                                                           |
195|   Inputs :                                                                |
196|                                                                           |
197|    var1                                                                   |
198|             16 bit short signed integer (Word16) whose value falls in the |
199|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
200|                                                                           |
201|    var2                                                                   |
202|             16 bit short signed integer (Word16) whose value falls in the |
203|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
204|                                                                           |
205|   Outputs :                                                               |
206|                                                                           |
207|    none                                                                   |
208|                                                                           |
209|   Return Value :                                                          |
210|                                                                           |
211|    var_out                                                                |
212|             16 bit short signed integer (Word16) whose value falls in the |
213|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
214|___________________________________________________________________________|
215*/
216
217static_vo Word16 shl (Word16 var1, Word16 var2)
218{
219	Word16 var_out;
220	Word32 result;
221	if (var2 < 0)
222	{
223		if (var2 < -16)
224			var2 = -16;
225		var_out = var1 >> ((Word16)-var2);
226	}
227	else
228	{
229		result = (Word32) var1 *((Word32) 1 << var2);
230		if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
231		{
232			var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
233		}
234		else
235		{
236			var_out = extract_l (result);
237		}
238	}
239	return (var_out);
240}
241
242/*___________________________________________________________________________
243|                                                                           |
244|   Function Name : shr                                                     |
245|                                                                           |
246|   Purpose :                                                               |
247|                                                                           |
248|   Arithmetically shift the 16 bit input var1 right var2 positions with    |
249|   sign extension. If var2 is negative, arithmetically shift var1 left by  |
250|   -var2 with sign extension. Saturate the result in case of underflows or |
251|   overflows.                                                              |
252|                                                                           |
253|   Complexity weight : 1                                                   |
254|                                                                           |
255|   Inputs :                                                                |
256|                                                                           |
257|    var1                                                                   |
258|             16 bit short signed integer (Word16) whose value falls in the |
259|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
260|                                                                           |
261|    var2                                                                   |
262|             16 bit short signed integer (Word16) whose value falls in the |
263|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
264|                                                                           |
265|   Outputs :                                                               |
266|                                                                           |
267|    none                                                                   |
268|                                                                           |
269|   Return Value :                                                          |
270|                                                                           |
271|    var_out                                                                |
272|             16 bit short signed integer (Word16) whose value falls in the |
273|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
274|___________________________________________________________________________|
275*/
276
277static_vo Word16 shr (Word16 var1, Word16 var2)
278{
279	Word16 var_out;
280	if (var2 < 0)
281	{
282		if (var2 < -16)
283			var2 = -16;
284		var_out = shl(var1, (Word16)-var2);
285	}
286	else
287	{
288		if (var2 >= 15)
289		{
290			var_out = (Word16)((var1 < 0) ? -1 : 0);
291		}
292		else
293		{
294			if (var1 < 0)
295			{
296				var_out = (Word16)(~((~var1) >> var2));
297			}
298			else
299			{
300				var_out = (Word16)(var1 >> var2);
301			}
302		}
303	}
304	return (var_out);
305}
306
307/*___________________________________________________________________________
308|                                                                           |
309|   Function Name : mult                                                    |
310|                                                                           |
311|   Purpose :                                                               |
312|                                                                           |
313|    Performs the multiplication of var1 by var2 and gives a 16 bit result  |
314|    which is scaled i.e.:                                                  |
315|             mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and  |
316|             mult(-32768,-32768) = 32767.                                  |
317|                                                                           |
318|   Complexity weight : 1                                                   |
319|                                                                           |
320|   Inputs :                                                                |
321|                                                                           |
322|    var1                                                                   |
323|             16 bit short signed integer (Word16) whose value falls in the |
324|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
325|                                                                           |
326|    var2                                                                   |
327|             16 bit short signed integer (Word16) whose value falls in the |
328|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
329|                                                                           |
330|   Outputs :                                                               |
331|                                                                           |
332|    none                                                                   |
333|                                                                           |
334|   Return Value :                                                          |
335|                                                                           |
336|    var_out                                                                |
337|             16 bit short signed integer (Word16) whose value falls in the |
338|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
339|___________________________________________________________________________|
340*/
341
342static_vo Word16 mult (Word16 var1, Word16 var2)
343{
344	Word16 var_out;
345	Word32 L_product;
346	L_product = (Word32) var1 *(Word32) var2;
347	L_product = (L_product & (Word32) 0xffff8000L) >> 15;
348	if (L_product & (Word32) 0x00010000L)
349		L_product = L_product | (Word32) 0xffff0000L;
350	var_out = saturate (L_product);
351	return (var_out);
352}
353
354/*___________________________________________________________________________
355|                                                                           |
356|   Function Name : L_mult                                                  |
357|                                                                           |
358|   Purpose :                                                               |
359|                                                                           |
360|   L_mult is the 32 bit result of the multiplication of var1 times var2    |
361|   with one shift left i.e.:                                               |
362|        L_mult(var1,var2) = L_shl((var1 times var2),1) and                   |
363|        L_mult(-32768,-32768) = 2147483647.                                |
364|                                                                           |
365|   Complexity weight : 1                                                   |
366|                                                                           |
367|   Inputs :                                                                |
368|                                                                           |
369|    var1                                                                   |
370|             16 bit short signed integer (Word16) whose value falls in the |
371|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
372|                                                                           |
373|    var2                                                                   |
374|             16 bit short signed integer (Word16) whose value falls in the |
375|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
376|                                                                           |
377|   Outputs :                                                               |
378|                                                                           |
379|    none                                                                   |
380|                                                                           |
381|   Return Value :                                                          |
382|                                                                           |
383|    L_var_out                                                              |
384|             32 bit long signed integer (Word32) whose value falls in the  |
385|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
386|___________________________________________________________________________|
387*/
388
389static_vo Word32 L_mult (Word16 var1, Word16 var2)
390{
391	Word32 L_var_out;
392	L_var_out = (Word32) var1 *(Word32) var2;
393	if (L_var_out != (Word32) 0x40000000L)
394	{
395		L_var_out *= 2;
396	}
397	else
398	{
399		L_var_out = MAX_32;
400	}
401	return (L_var_out);
402}
403
404/*___________________________________________________________________________
405|                                                                           |
406|   Function Name : round                                                   |
407|                                                                           |
408|   Purpose :                                                               |
409|                                                                           |
410|   Round the lower 16 bits of the 32 bit input number into the MS 16 bits  |
411|   with saturation. Shift the resulting bits right by 16 and return the 16 |
412|   bit number:                                                             |
413|               round(L_var1) = extract_h(L_add(L_var1,32768))              |
414|                                                                           |
415|   Complexity weight : 1                                                   |
416|                                                                           |
417|   Inputs :                                                                |
418|                                                                           |
419|    L_var1                                                                 |
420|             32 bit long signed integer (Word32 ) whose value falls in the |
421|             range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.                 |
422|                                                                           |
423|   Outputs :                                                               |
424|                                                                           |
425|    none                                                                   |
426|                                                                           |
427|   Return Value :                                                          |
428|                                                                           |
429|    var_out                                                                |
430|             16 bit short signed integer (Word16) whose value falls in the |
431|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
432|___________________________________________________________________________|
433*/
434
435static_vo Word16 voround (Word32 L_var1)
436{
437	Word16 var_out;
438	Word32 L_rounded;
439	L_rounded = L_add (L_var1, (Word32) 0x00008000L);
440	var_out = extract_h (L_rounded);
441	return (var_out);
442}
443
444/*___________________________________________________________________________
445|                                                                           |
446|   Function Name : L_mac                                                   |
447|                                                                           |
448|   Purpose :                                                               |
449|                                                                           |
450|   Multiply var1 by var2 and shift the result left by 1. Add the 32 bit    |
451|   result to L_var3 with saturation, return a 32 bit result:               |
452|        L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)).         |
453|                                                                           |
454|   Complexity weight : 1                                                   |
455|                                                                           |
456|   Inputs :                                                                |
457|                                                                           |
458|    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
459|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
460|                                                                           |
461|    var1                                                                   |
462|             16 bit short signed integer (Word16) whose value falls in the |
463|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
464|                                                                           |
465|    var2                                                                   |
466|             16 bit short signed integer (Word16) whose value falls in the |
467|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
468|                                                                           |
469|   Outputs :                                                               |
470|                                                                           |
471|    none                                                                   |
472|                                                                           |
473|   Return Value :                                                          |
474|                                                                           |
475|    L_var_out                                                              |
476|             32 bit long signed integer (Word32) whose value falls in the  |
477|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
478|___________________________________________________________________________|
479*/
480
481static_vo Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
482{
483	Word32 L_var_out;
484	Word32 L_product;
485	L_product = ((var1 * var2) << 1);
486	L_var_out = L_add (L_var3, L_product);
487	return (L_var_out);
488}
489
490/*___________________________________________________________________________
491|                                                                           |
492|   Function Name : L_msu                                                   |
493|                                                                           |
494|   Purpose :                                                               |
495|                                                                           |
496|   Multiply var1 by var2 and shift the result left by 1. Subtract the 32   |
497|   bit result to L_var3 with saturation, return a 32 bit result:           |
498|        L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)).         |
499|                                                                           |
500|   Complexity weight : 1                                                   |
501|                                                                           |
502|   Inputs :                                                                |
503|                                                                           |
504|    L_var3   32 bit long signed integer (Word32) whose value falls in the  |
505|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
506|                                                                           |
507|    var1                                                                   |
508|             16 bit short signed integer (Word16) whose value falls in the |
509|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
510|                                                                           |
511|    var2                                                                   |
512|             16 bit short signed integer (Word16) whose value falls in the |
513|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
514|                                                                           |
515|   Outputs :                                                               |
516|                                                                           |
517|    none                                                                   |
518|                                                                           |
519|   Return Value :                                                          |
520|                                                                           |
521|    L_var_out                                                              |
522|             32 bit long signed integer (Word32) whose value falls in the  |
523|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
524|___________________________________________________________________________|
525*/
526
527static_vo Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
528{
529	Word32 L_var_out;
530	Word32 L_product;
531	L_product = (var1 * var2)<<1;
532	L_var_out = L_sub (L_var3, L_product);
533	return (L_var_out);
534}
535
536/*___________________________________________________________________________
537|                                                                           |
538|   Function Name : L_add                                                   |
539|                                                                           |
540|   Purpose :                                                               |
541|                                                                           |
542|   32 bits addition of the two 32 bits variables (L_var1+L_var2) with      |
543|   overflow control and saturation; the result is set at +2147483647 when  |
544|   overflow occurs or at -2147483648 when underflow occurs.                |
545|                                                                           |
546|   Complexity weight : 2                                                   |
547|                                                                           |
548|   Inputs :                                                                |
549|                                                                           |
550|    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
551|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
552|                                                                           |
553|    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
554|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
555|                                                                           |
556|   Outputs :                                                               |
557|                                                                           |
558|    none                                                                   |
559|                                                                           |
560|   Return Value :                                                          |
561|                                                                           |
562|    L_var_out                                                              |
563|             32 bit long signed integer (Word32) whose value falls in the  |
564|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
565|___________________________________________________________________________|
566*/
567
568static_vo Word32 L_add (Word32 L_var1, Word32 L_var2)
569{
570	Word32 L_var_out;
571	L_var_out = L_var1 + L_var2;
572	if (((L_var1 ^ L_var2) & MIN_32) == 0)
573	{
574		if ((L_var_out ^ L_var1) & MIN_32)
575		{
576			L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
577		}
578	}
579	return (L_var_out);
580}
581
582/*___________________________________________________________________________
583|                                                                           |
584|   Function Name : L_sub                                                   |
585|                                                                           |
586|   Purpose :                                                               |
587|                                                                           |
588|   32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with   |
589|   overflow control and saturation; the result is set at +2147483647 when  |
590|   overflow occurs or at -2147483648 when underflow occurs.                |
591|                                                                           |
592|   Complexity weight : 2                                                   |
593|                                                                           |
594|   Inputs :                                                                |
595|                                                                           |
596|    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
597|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
598|                                                                           |
599|    L_var2   32 bit long signed integer (Word32) whose value falls in the  |
600|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
601|                                                                           |
602|   Outputs :                                                               |
603|                                                                           |
604|    none                                                                   |
605|                                                                           |
606|   Return Value :                                                          |
607|                                                                           |
608|    L_var_out                                                              |
609|             32 bit long signed integer (Word32) whose value falls in the  |
610|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
611|___________________________________________________________________________|
612*/
613
614static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2)
615{
616	Word32 L_var_out;
617	L_var_out = L_var1 - L_var2;
618	if (((L_var1 ^ L_var2) & MIN_32) != 0)
619	{
620		if ((L_var_out ^ L_var1) & MIN_32)
621		{
622			L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
623		}
624	}
625	return (L_var_out);
626}
627
628
629/*___________________________________________________________________________
630|                                                                           |
631|   Function Name : mult_r                                                  |
632|                                                                           |
633|   Purpose :                                                               |
634|                                                                           |
635|   Same as mult with rounding, i.e.:                                       |
636|     mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and  |
637|     mult_r(-32768,-32768) = 32767.                                        |
638|                                                                           |
639|   Complexity weight : 2                                                   |
640|                                                                           |
641|   Inputs :                                                                |
642|                                                                           |
643|    var1                                                                   |
644|             16 bit short signed integer (Word16) whose value falls in the |
645|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
646|                                                                           |
647|    var2                                                                   |
648|             16 bit short signed integer (Word16) whose value falls in the |
649|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
650|                                                                           |
651|   Outputs :                                                               |
652|                                                                           |
653|    none                                                                   |
654|                                                                           |
655|   Return Value :                                                          |
656|                                                                           |
657|    var_out                                                                |
658|             16 bit short signed integer (Word16) whose value falls in the |
659|             range : 0xffff 8000 <= var_out <= 0x0000 7fff.                |
660|___________________________________________________________________________|
661*/
662
663static_vo Word16 mult_r (Word16 var1, Word16 var2)
664{
665	Word16 var_out;
666	Word32 L_product_arr;
667	L_product_arr = (Word32) var1 *(Word32) var2;       /* product */
668	L_product_arr += (Word32) 0x00004000L;      /* round */
669	L_product_arr &= (Word32) 0xffff8000L;
670	L_product_arr >>= 15;       /* shift */
671	if (L_product_arr & (Word32) 0x00010000L)   /* sign extend when necessary */
672	{
673		L_product_arr |= (Word32) 0xffff0000L;
674	}
675	var_out = saturate (L_product_arr);
676	return (var_out);
677}
678
679/*___________________________________________________________________________
680|                                                                           |
681|   Function Name : L_shl                                                   |
682|                                                                           |
683|   Purpose :                                                               |
684|                                                                           |
685|   Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero  |
686|   fill the var2 LSB of the result. If var2 is negative, arithmetically    |
687|   shift L_var1 right by -var2 with sign extension. Saturate the result in |
688|   case of underflows or overflows.                                        |
689|                                                                           |
690|   Complexity weight : 2                                                   |
691|                                                                           |
692|   Inputs :                                                                |
693|                                                                           |
694|    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
695|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
696|                                                                           |
697|    var2                                                                   |
698|             16 bit short signed integer (Word16) whose value falls in the |
699|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
700|                                                                           |
701|   Outputs :                                                               |
702|                                                                           |
703|    none                                                                   |
704|                                                                           |
705|   Return Value :                                                          |
706|                                                                           |
707|    L_var_out                                                              |
708|             32 bit long signed integer (Word32) whose value falls in the  |
709|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
710|___________________________________________________________________________|
711*/
712
713static_vo Word32 L_shl (Word32 L_var1, Word16 var2)
714{
715	Word32 L_var_out = 0L;
716	if (var2 <= 0)
717	{
718		if (var2 < -32)
719			var2 = -32;
720		L_var_out = (L_var1 >> (Word16)-var2);
721	}
722	else
723	{
724		for (; var2 > 0; var2--)
725		{
726			if (L_var1 > (Word32) 0X3fffffffL)
727			{
728				L_var_out = MAX_32;
729				break;
730			}
731			else
732			{
733				if (L_var1 < (Word32) 0xc0000000L)
734				{
735					//Overflow = 1;
736					L_var_out = MIN_32;
737					break;
738				}
739			}
740			L_var1 *= 2;
741			L_var_out = L_var1;
742		}
743	}
744	return (L_var_out);
745}
746
747static_vo Word32 L_shl2(Word32 L_var1, Word16 var2)
748{
749	Word32 L_var_out = 0L;
750
751	for (; var2 > 0; var2--)
752	{
753		if (L_var1 > (Word32) 0X3fffffffL)
754		{
755			L_var_out = MAX_32;
756			break;
757		}
758		else
759		{
760			if (L_var1 < (Word32) 0xc0000000L)
761			{
762				L_var_out = MIN_32;
763				break;
764			}
765		}
766		L_var1 <<=1 ;
767		L_var_out = L_var1;
768	}
769	return (L_var_out);
770}
771
772/*___________________________________________________________________________
773|                                                                           |
774|   Function Name : L_shr                                                   |
775|                                                                           |
776|   Purpose :                                                               |
777|                                                                           |
778|   Arithmetically shift the 32 bit input L_var1 right var2 positions with  |
779|   sign extension. If var2 is negative, arithmetically shift L_var1 left   |
780|   by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
781|   in case of underflows or overflows.                                     |
782|                                                                           |
783|   Complexity weight : 2                                                   |
784|                                                                           |
785|   Inputs :                                                                |
786|                                                                           |
787|    L_var1   32 bit long signed integer (Word32) whose value falls in the  |
788|             range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.                 |
789|                                                                           |
790|    var2                                                                   |
791|             16 bit short signed integer (Word16) whose value falls in the |
792|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
793|                                                                           |
794|   Outputs :                                                               |
795|                                                                           |
796|    none                                                                   |
797|                                                                           |
798|   Return Value :                                                          |
799|                                                                           |
800|    L_var_out                                                              |
801|             32 bit long signed integer (Word32) whose value falls in the  |
802|             range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.              |
803|___________________________________________________________________________|
804*/
805
806static_vo Word32 L_shr (Word32 L_var1, Word16 var2)
807{
808	Word32 L_var_out;
809	if (var2 < 0)
810	{
811		if (var2 < -32)
812			var2 = -32;
813		L_var_out = L_shl2(L_var1, (Word16)-var2);
814	}
815	else
816	{
817		if (var2 >= 31)
818		{
819			L_var_out = (L_var1 < 0L) ? -1 : 0;
820		}
821		else
822		{
823			if (L_var1 < 0)
824			{
825				L_var_out = ~((~L_var1) >> var2);
826			}
827			else
828			{
829				L_var_out = L_var1 >> var2;
830			}
831		}
832	}
833	return (L_var_out);
834}
835
836/*___________________________________________________________________________
837|                                                                           |
838|   Function Name : L_shr_r                                                 |
839|                                                                           |
840|   Purpose :                                                               |
841|                                                                           |
842|   Same as L_shr(L_var1,var2) but with rounding. Saturate the result in    |
843|   case of underflows or overflows :                                       |
844|    - If var2 is greater than zero :                                       |
845|          if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|
846|          is equal to zero                                                 |
847|                     then                                                  |
848|                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2)             |
849|                     else                                                  |
850|                     L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1)    |
851|    - If var2 is less than or equal to zero :                              |
852|                     L_shr_r(L_var1,var2) = L_shr(L_var1,var2).            |
853|                                                                           |
854|   Complexity weight : 3                                                   |
855|                                                                           |
856|   Inputs :                                                                |
857|                                                                           |
858|    L_var1                                                                 |
859|             32 bit long signed integer (Word32) whose value falls in the  |
860|             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
861|                                                                           |
862|    var2                                                                   |
863|             16 bit short signed integer (Word16) whose value falls in the |
864|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
865|                                                                           |
866|   Outputs :                                                               |
867|                                                                           |
868|    none                                                                   |
869|                                                                           |
870|   Return Value :                                                          |
871|                                                                           |
872|    L_var_out                                                              |
873|             32 bit long signed integer (Word32) whose value falls in the  |
874|             range : 0x8000 0000 <= var_out <= 0x7fff ffff.                |
875|___________________________________________________________________________|
876*/
877
878static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2)
879{
880	Word32 L_var_out;
881	if (var2 > 31)
882	{
883		L_var_out = 0;
884	}
885	else
886	{
887		L_var_out = L_shr (L_var1, var2);
888		if (var2 > 0)
889		{
890			if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
891			{
892				L_var_out++;
893			}
894		}
895	}
896	return (L_var_out);
897}
898
899/*___________________________________________________________________________
900|                                                                           |
901|   Function Name : norm_s                                                  |
902|                                                                           |
903|   Purpose :                                                               |
904|                                                                           |
905|   Produces the number of left shift needed to normalize the 16 bit varia- |
906|   ble var1 for positive values on the interval with minimum of 16384 and  |
907|   maximum of 32767, and for negative values on the interval with minimum  |
908|   of -32768 and maximum of -16384; in order to normalize the result, the  |
909|   following operation must be done :                                      |
910|                    norm_var1 = shl(var1,norm_s(var1)).                    |
911|                                                                           |
912|   Complexity weight : 15                                                  |
913|                                                                           |
914|   Inputs :                                                                |
915|                                                                           |
916|    var1                                                                   |
917|             16 bit short signed integer (Word16) whose value falls in the |
918|             range : 0xffff 8000 <= var1 <= 0x0000 7fff.                   |
919|                                                                           |
920|   Outputs :                                                               |
921|                                                                           |
922|    none                                                                   |
923|                                                                           |
924|   Return Value :                                                          |
925|                                                                           |
926|    var_out                                                                |
927|             16 bit short signed integer (Word16) whose value falls in the |
928|             range : 0x0000 0000 <= var_out <= 0x0000 000f.                |
929|___________________________________________________________________________|
930*/
931
932static_vo Word16 norm_s (Word16 var1)
933{
934	Word16 var_out = 0;
935	if (var1 == 0)
936	{
937		var_out = 0;
938	}
939	else
940	{
941		if (var1 == -1)
942		{
943			var_out = 15;
944		}
945		else
946		{
947			if (var1 < 0)
948			{
949				var1 = (Word16)~var1;
950			}
951			for (var_out = 0; var1 < 0x4000; var_out++)
952			{
953				var1 <<= 1;
954			}
955		}
956	}
957	return (var_out);
958}
959
960/*___________________________________________________________________________
961|                                                                           |
962|   Function Name : div_s                                                   |
963|                                                                           |
964|   Purpose :                                                               |
965|                                                                           |
966|   Produces a result which is the fractional integer division of var1  by  |
967|   var2; var1 and var2 must be positive and var2 must be greater or equal  |
968|   to var1; the result is positive (leading bit equal to 0) and truncated  |
969|   to 16 bits.                                                             |
970|   If var1 = var2 then div(var1,var2) = 32767.                             |
971|                                                                           |
972|   Complexity weight : 18                                                  |
973|                                                                           |
974|   Inputs :                                                                |
975|                                                                           |
976|    var1                                                                   |
977|             16 bit short signed integer (Word16) whose value falls in the |
978|             range : 0x0000 0000 <= var1 <= var2 and var2 != 0.            |
979|                                                                           |
980|    var2                                                                   |
981|             16 bit short signed integer (Word16) whose value falls in the |
982|             range : var1 <= var2 <= 0x0000 7fff and var2 != 0.            |
983|                                                                           |
984|   Outputs :                                                               |
985|                                                                           |
986|    none                                                                   |
987|                                                                           |
988|   Return Value :                                                          |
989|                                                                           |
990|    var_out                                                                |
991|             16 bit short signed integer (Word16) whose value falls in the |
992|             range : 0x0000 0000 <= var_out <= 0x0000 7fff.                |
993|             It's a Q15 value (point between b15 and b14).                 |
994|___________________________________________________________________________|
995*/
996
997static_vo Word16 div_s (Word16 var1, Word16 var2)
998{
999	Word16 var_out = 0;
1000	Word16 iteration;
1001	Word32 L_num;
1002	Word32 L_denom;
1003	if ((var1 < 0) || (var2 < 0))
1004	{
1005		var_out = MAX_16;
1006		return var_out;
1007	}
1008	if (var2 == 0)
1009	{
1010		var_out = MAX_16;
1011		return var_out;
1012	}
1013	if (var1 == 0)
1014	{
1015		var_out = 0;
1016	}
1017	else
1018	{
1019		if (var1 == var2)
1020		{
1021			var_out = MAX_16;
1022		}
1023		else
1024		{
1025			L_num = L_deposit_l (var1);
1026			L_denom = L_deposit_l(var2);
1027			for (iteration = 0; iteration < 15; iteration++)
1028			{
1029				var_out <<= 1;
1030				L_num <<= 1;
1031				if (L_num >= L_denom)
1032				{
1033					L_num -= L_denom;
1034					var_out += 1;
1035				}
1036			}
1037		}
1038	}
1039	return (var_out);
1040}
1041
1042/*___________________________________________________________________________
1043|                                                                           |
1044|   Function Name : norm_l                                                  |
1045|                                                                           |
1046|   Purpose :                                                               |
1047|                                                                           |
1048|   Produces the number of left shifts needed to normalize the 32 bit varia-|
1049|   ble L_var1 for positive values on the interval with minimum of          |
1050|   1073741824 and maximum of 2147483647, and for negative values on the in-|
1051|   terval with minimum of -2147483648 and maximum of -1073741824; in order |
1052|   to normalize the result, the following operation must be done :         |
1053|                   norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).             |
1054|                                                                           |
1055|   Complexity weight : 30                                                  |
1056|                                                                           |
1057|   Inputs :                                                                |
1058|                                                                           |
1059|    L_var1                                                                 |
1060|             32 bit long signed integer (Word32) whose value falls in the  |
1061|             range : 0x8000 0000 <= var1 <= 0x7fff ffff.                   |
1062|                                                                           |
1063|   Outputs :                                                               |
1064|                                                                           |
1065|    none                                                                   |
1066|                                                                           |
1067|   Return Value :                                                          |
1068|                                                                           |
1069|    var_out                                                                |
1070|             16 bit short signed integer (Word16) whose value falls in the |
1071|             range : 0x0000 0000 <= var_out <= 0x0000 001f.                |
1072|___________________________________________________________________________|
1073*/
1074
1075static_vo Word16 norm_l (Word32 L_var1)
1076{
1077	Word16 var_out = 0;
1078	if (L_var1 != 0)
1079	{
1080		var_out = 31;
1081		if (L_var1 != (Word32) 0xffffffffL)
1082		{
1083			L_var1 ^= (L_var1 >>31);
1084			for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
1085			{
1086				L_var1 <<= 1;
1087			}
1088		}
1089	}
1090	return (var_out);
1091}
1092
1093#endif //__BASIC_OP_H__
1094
1095