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