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 */
68 static_vo Word16 add (Word16 var1, Word16 var2); /* Short add,1 */
69 static_vo Word16 sub (Word16 var1, Word16 var2); /* Short sub,1 */
70 static_vo Word16 shl (Word16 var1, Word16 var2); /* Short shift left, 1 */
71 static_vo Word16 shr (Word16 var1, Word16 var2); /* Short shift right, 1 */
72 static_vo Word16 mult (Word16 var1, Word16 var2); /* Short mult, 1 */
73 static_vo Word32 L_mult (Word16 var1, Word16 var2); /* Long mult, 1 */
74 static_vo Word16 voround (Word32 L_var1); /* Round, 1 */
75 static_vo Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); /* Mac, 1 */
76 static_vo Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); /* Msu, 1 */
77 static_vo Word32 L_add (Word32 L_var1, Word32 L_var2); /* Long add, 2 */
78 static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2); /* Long sub, 2 */
79 static_vo Word16 mult_r (Word16 var1, Word16 var2); /* Mult with round, 2 */
80 static_vo Word32 L_shl2(Word32 L_var1, Word16 var2); /* var2 > 0*/
81 static_vo Word32 L_shl (Word32 L_var1, Word16 var2); /* Long shift left, 2 */
82 static_vo Word32 L_shr (Word32 L_var1, Word16 var2); /* Long shift right, 2*/
83 static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with round, 3 */
84 static_vo Word16 norm_s (Word16 var1); /* Short norm, 15 */
85 static_vo Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */
86 static_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 */
add(Word16 var1,Word16 var2)126 static_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
sub(Word16 var1,Word16 var2)169 static_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
shl(Word16 var1,Word16 var2)213 static_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
shr(Word16 var1,Word16 var2)273 static_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
mult(Word16 var1,Word16 var2)338 static_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
L_mult(Word16 var1,Word16 var2)385 static_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
voround(Word32 L_var1)431 static_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
L_mac(Word32 L_var3,Word16 var1,Word16 var2)477 static_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
L_msu(Word32 L_var3,Word16 var1,Word16 var2)523 static_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
L_add(Word32 L_var1,Word32 L_var2)564 static_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
L_sub(Word32 L_var1,Word32 L_var2)610 static_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
mult_r(Word16 var1,Word16 var2)659 static_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
L_shl(Word32 L_var1,Word16 var2)709 static_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
L_shl2(Word32 L_var1,Word16 var2)743 static_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
L_shr(Word32 L_var1,Word16 var2)802 static_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
L_shr_r(Word32 L_var1,Word16 var2)874 static_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
norm_s(Word16 var1)928 static_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
div_s(Word16 var1,Word16 var2)993 static_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
norm_l(Word32 L_var1)1071 static_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