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) >> 15) + 1) >> 1)
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) ) >> 14) + 1 ) >> 1 )
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 if (var2 > 15 && var1 != 0)
226 {
227 var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
228 }
229 else
230 {
231 result = (Word32) var1 *((Word32) 1 << var2);
232 if ((result != (Word32) ((Word16) result))) {
233 var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
234 } else {
235 var_out = extract_l (result);
236 }
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
shr(Word16 var1,Word16 var2)277 static_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
mult(Word16 var1,Word16 var2)342 static_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
L_mult(Word16 var1,Word16 var2)389 static_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
voround(Word32 L_var1)435 static_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
L_mac(Word32 L_var3,Word16 var1,Word16 var2)481 static_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
L_msu(Word32 L_var3,Word16 var1,Word16 var2)527 static_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
568 __attribute__((no_sanitize("integer")))
L_add(Word32 L_var1,Word32 L_var2)569 static_vo Word32 L_add (Word32 L_var1, Word32 L_var2)
570 {
571 Word32 L_var_out;
572 L_var_out = L_var1 + L_var2;
573 if (((L_var1 ^ L_var2) & MIN_32) == 0)
574 {
575 if ((L_var_out ^ L_var1) & MIN_32)
576 {
577 L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
578 }
579 }
580 return (L_var_out);
581 }
582
583 /*___________________________________________________________________________
584 | |
585 | Function Name : L_sub |
586 | |
587 | Purpose : |
588 | |
589 | 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with |
590 | overflow control and saturation; the result is set at +2147483647 when |
591 | overflow occurs or at -2147483648 when underflow occurs. |
592 | |
593 | Complexity weight : 2 |
594 | |
595 | Inputs : |
596 | |
597 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
598 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
599 | |
600 | L_var2 32 bit long signed integer (Word32) whose value falls in the |
601 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
602 | |
603 | Outputs : |
604 | |
605 | none |
606 | |
607 | Return Value : |
608 | |
609 | L_var_out |
610 | 32 bit long signed integer (Word32) whose value falls in the |
611 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
612 |___________________________________________________________________________|
613 */
614
615 __attribute__((no_sanitize("integer")))
L_sub(Word32 L_var1,Word32 L_var2)616 static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2)
617 {
618 Word32 L_var_out;
619 L_var_out = L_var1 - L_var2;
620 if (((L_var1 ^ L_var2) & MIN_32) != 0)
621 {
622 if ((L_var_out ^ L_var1) & MIN_32)
623 {
624 L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
625 }
626 }
627 return (L_var_out);
628 }
629
630
631 /*___________________________________________________________________________
632 | |
633 | Function Name : mult_r |
634 | |
635 | Purpose : |
636 | |
637 | Same as mult with rounding, i.e.: |
638 | mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and |
639 | mult_r(-32768,-32768) = 32767. |
640 | |
641 | Complexity weight : 2 |
642 | |
643 | Inputs : |
644 | |
645 | var1 |
646 | 16 bit short signed integer (Word16) whose value falls in the |
647 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
648 | |
649 | var2 |
650 | 16 bit short signed integer (Word16) whose value falls in the |
651 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
652 | |
653 | Outputs : |
654 | |
655 | none |
656 | |
657 | Return Value : |
658 | |
659 | var_out |
660 | 16 bit short signed integer (Word16) whose value falls in the |
661 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
662 |___________________________________________________________________________|
663 */
664
mult_r(Word16 var1,Word16 var2)665 static_vo Word16 mult_r (Word16 var1, Word16 var2)
666 {
667 Word16 var_out;
668 Word32 L_product_arr;
669 L_product_arr = (Word32) var1 *(Word32) var2; /* product */
670 L_product_arr += (Word32) 0x00004000L; /* round */
671 L_product_arr &= (Word32) 0xffff8000L;
672 L_product_arr >>= 15; /* shift */
673 if (L_product_arr & (Word32) 0x00010000L) /* sign extend when necessary */
674 {
675 L_product_arr |= (Word32) 0xffff0000L;
676 }
677 var_out = saturate (L_product_arr);
678 return (var_out);
679 }
680
681 /*___________________________________________________________________________
682 | |
683 | Function Name : L_shl |
684 | |
685 | Purpose : |
686 | |
687 | Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero |
688 | fill the var2 LSB of the result. If var2 is negative, arithmetically |
689 | shift L_var1 right by -var2 with sign extension. Saturate the result in |
690 | case of underflows or overflows. |
691 | |
692 | Complexity weight : 2 |
693 | |
694 | Inputs : |
695 | |
696 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
697 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
698 | |
699 | var2 |
700 | 16 bit short signed integer (Word16) whose value falls in the |
701 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
702 | |
703 | Outputs : |
704 | |
705 | none |
706 | |
707 | Return Value : |
708 | |
709 | L_var_out |
710 | 32 bit long signed integer (Word32) whose value falls in the |
711 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
712 |___________________________________________________________________________|
713 */
714
L_shl(Word32 L_var1,Word16 var2)715 static_vo Word32 L_shl (Word32 L_var1, Word16 var2)
716 {
717 Word32 L_var_out = 0L;
718 if (var2 <= 0)
719 {
720 if (var2 < -32)
721 var2 = -32;
722 L_var_out = (L_var1 >> (Word16)-var2);
723 }
724 else
725 {
726 for (; var2 > 0; var2--)
727 {
728 if (L_var1 > (Word32) 0X3fffffffL)
729 {
730 L_var_out = MAX_32;
731 break;
732 }
733 else
734 {
735 if (L_var1 < (Word32) 0xc0000000L)
736 {
737 //Overflow = 1;
738 L_var_out = MIN_32;
739 break;
740 }
741 }
742 L_var1 *= 2;
743 L_var_out = L_var1;
744 }
745 }
746 return (L_var_out);
747 }
748
L_shl2(Word32 L_var1,Word16 var2)749 static_vo Word32 L_shl2(Word32 L_var1, Word16 var2)
750 {
751 Word32 L_var_out = 0L;
752
753 for (; var2 > 0; var2--)
754 {
755 if (L_var1 > (Word32) 0X3fffffffL)
756 {
757 L_var_out = MAX_32;
758 break;
759 }
760 else
761 {
762 if (L_var1 < (Word32) 0xc0000000L)
763 {
764 L_var_out = MIN_32;
765 break;
766 }
767 }
768 L_var1 *= 2 ;
769 L_var_out = L_var1;
770 }
771 return (L_var_out);
772 }
773
774 /*___________________________________________________________________________
775 | |
776 | Function Name : L_shr |
777 | |
778 | Purpose : |
779 | |
780 | Arithmetically shift the 32 bit input L_var1 right var2 positions with |
781 | sign extension. If var2 is negative, arithmetically shift L_var1 left |
782 | by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
783 | in case of underflows or overflows. |
784 | |
785 | Complexity weight : 2 |
786 | |
787 | Inputs : |
788 | |
789 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
790 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
791 | |
792 | var2 |
793 | 16 bit short signed integer (Word16) whose value falls in the |
794 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
795 | |
796 | Outputs : |
797 | |
798 | none |
799 | |
800 | Return Value : |
801 | |
802 | L_var_out |
803 | 32 bit long signed integer (Word32) whose value falls in the |
804 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
805 |___________________________________________________________________________|
806 */
807
L_shr(Word32 L_var1,Word16 var2)808 static_vo Word32 L_shr (Word32 L_var1, Word16 var2)
809 {
810 Word32 L_var_out;
811 if (var2 < 0)
812 {
813 if (var2 < -32)
814 var2 = -32;
815 L_var_out = L_shl2(L_var1, (Word16)-var2);
816 }
817 else
818 {
819 if (var2 >= 31)
820 {
821 L_var_out = (L_var1 < 0L) ? -1 : 0;
822 }
823 else
824 {
825 if (L_var1 < 0)
826 {
827 L_var_out = ~((~L_var1) >> var2);
828 }
829 else
830 {
831 L_var_out = L_var1 >> var2;
832 }
833 }
834 }
835 return (L_var_out);
836 }
837
838 /*___________________________________________________________________________
839 | |
840 | Function Name : L_shr_r |
841 | |
842 | Purpose : |
843 | |
844 | Same as L_shr(L_var1,var2) but with rounding. Saturate the result in |
845 | case of underflows or overflows : |
846 | - If var2 is greater than zero : |
847 | if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|
848 | is equal to zero |
849 | then |
850 | L_shr_r(L_var1,var2) = L_shr(L_var1,var2) |
851 | else |
852 | L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1) |
853 | - If var2 is less than or equal to zero : |
854 | L_shr_r(L_var1,var2) = L_shr(L_var1,var2). |
855 | |
856 | Complexity weight : 3 |
857 | |
858 | Inputs : |
859 | |
860 | L_var1 |
861 | 32 bit long signed integer (Word32) whose value falls in the |
862 | range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
863 | |
864 | var2 |
865 | 16 bit short signed integer (Word16) whose value falls in the |
866 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
867 | |
868 | Outputs : |
869 | |
870 | none |
871 | |
872 | Return Value : |
873 | |
874 | L_var_out |
875 | 32 bit long signed integer (Word32) whose value falls in the |
876 | range : 0x8000 0000 <= var_out <= 0x7fff ffff. |
877 |___________________________________________________________________________|
878 */
879
L_shr_r(Word32 L_var1,Word16 var2)880 static_vo Word32 L_shr_r (Word32 L_var1, Word16 var2)
881 {
882 Word32 L_var_out;
883 if (var2 > 31)
884 {
885 L_var_out = 0;
886 }
887 else
888 {
889 L_var_out = L_shr (L_var1, var2);
890 if (var2 > 0)
891 {
892 if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
893 {
894 L_var_out++;
895 }
896 }
897 }
898 return (L_var_out);
899 }
900
901 /*___________________________________________________________________________
902 | |
903 | Function Name : norm_s |
904 | |
905 | Purpose : |
906 | |
907 | Produces the number of left shift needed to normalize the 16 bit varia- |
908 | ble var1 for positive values on the interval with minimum of 16384 and |
909 | maximum of 32767, and for negative values on the interval with minimum |
910 | of -32768 and maximum of -16384; in order to normalize the result, the |
911 | following operation must be done : |
912 | norm_var1 = shl(var1,norm_s(var1)). |
913 | |
914 | Complexity weight : 15 |
915 | |
916 | Inputs : |
917 | |
918 | var1 |
919 | 16 bit short signed integer (Word16) whose value falls in the |
920 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
921 | |
922 | Outputs : |
923 | |
924 | none |
925 | |
926 | Return Value : |
927 | |
928 | var_out |
929 | 16 bit short signed integer (Word16) whose value falls in the |
930 | range : 0x0000 0000 <= var_out <= 0x0000 000f. |
931 |___________________________________________________________________________|
932 */
933
norm_s(Word16 var1)934 static_vo Word16 norm_s (Word16 var1)
935 {
936 Word16 var_out = 0;
937 if (var1 == 0)
938 {
939 var_out = 0;
940 }
941 else
942 {
943 if (var1 == -1)
944 {
945 var_out = 15;
946 }
947 else
948 {
949 if (var1 < 0)
950 {
951 var1 = (Word16)~var1;
952 }
953 for (var_out = 0; var1 < 0x4000; var_out++)
954 {
955 var1 <<= 1;
956 }
957 }
958 }
959 return (var_out);
960 }
961
962 /*___________________________________________________________________________
963 | |
964 | Function Name : div_s |
965 | |
966 | Purpose : |
967 | |
968 | Produces a result which is the fractional integer division of var1 by |
969 | var2; var1 and var2 must be positive and var2 must be greater or equal |
970 | to var1; the result is positive (leading bit equal to 0) and truncated |
971 | to 16 bits. |
972 | If var1 = var2 then div(var1,var2) = 32767. |
973 | |
974 | Complexity weight : 18 |
975 | |
976 | Inputs : |
977 | |
978 | var1 |
979 | 16 bit short signed integer (Word16) whose value falls in the |
980 | range : 0x0000 0000 <= var1 <= var2 and var2 != 0. |
981 | |
982 | var2 |
983 | 16 bit short signed integer (Word16) whose value falls in the |
984 | range : var1 <= var2 <= 0x0000 7fff and var2 != 0. |
985 | |
986 | Outputs : |
987 | |
988 | none |
989 | |
990 | Return Value : |
991 | |
992 | var_out |
993 | 16 bit short signed integer (Word16) whose value falls in the |
994 | range : 0x0000 0000 <= var_out <= 0x0000 7fff. |
995 | It's a Q15 value (point between b15 and b14). |
996 |___________________________________________________________________________|
997 */
998
div_s(Word16 var1,Word16 var2)999 static_vo Word16 div_s (Word16 var1, Word16 var2)
1000 {
1001 Word16 var_out = 0;
1002 Word16 iteration;
1003 Word32 L_num;
1004 Word32 L_denom;
1005 if ((var1 < 0) || (var2 < 0))
1006 {
1007 var_out = MAX_16;
1008 return var_out;
1009 }
1010 if (var2 == 0)
1011 {
1012 var_out = MAX_16;
1013 return var_out;
1014 }
1015 if (var1 == 0)
1016 {
1017 var_out = 0;
1018 }
1019 else
1020 {
1021 if (var1 == var2)
1022 {
1023 var_out = MAX_16;
1024 }
1025 else
1026 {
1027 L_num = L_deposit_l (var1);
1028 L_denom = L_deposit_l(var2);
1029 for (iteration = 0; iteration < 15; iteration++)
1030 {
1031 var_out <<= 1;
1032 L_num <<= 1;
1033 if (L_num >= L_denom)
1034 {
1035 L_num -= L_denom;
1036 var_out += 1;
1037 }
1038 }
1039 }
1040 }
1041 return (var_out);
1042 }
1043
1044 /*___________________________________________________________________________
1045 | |
1046 | Function Name : norm_l |
1047 | |
1048 | Purpose : |
1049 | |
1050 | Produces the number of left shifts needed to normalize the 32 bit varia-|
1051 | ble L_var1 for positive values on the interval with minimum of |
1052 | 1073741824 and maximum of 2147483647, and for negative values on the in-|
1053 | terval with minimum of -2147483648 and maximum of -1073741824; in order |
1054 | to normalize the result, the following operation must be done : |
1055 | norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). |
1056 | |
1057 | Complexity weight : 30 |
1058 | |
1059 | Inputs : |
1060 | |
1061 | L_var1 |
1062 | 32 bit long signed integer (Word32) whose value falls in the |
1063 | range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
1064 | |
1065 | Outputs : |
1066 | |
1067 | none |
1068 | |
1069 | Return Value : |
1070 | |
1071 | var_out |
1072 | 16 bit short signed integer (Word16) whose value falls in the |
1073 | range : 0x0000 0000 <= var_out <= 0x0000 001f. |
1074 |___________________________________________________________________________|
1075 */
1076
norm_l(Word32 L_var1)1077 static_vo Word16 norm_l (Word32 L_var1)
1078 {
1079 Word16 var_out = 0;
1080 if (L_var1 != 0)
1081 {
1082 var_out = 31;
1083 if (L_var1 != (Word32) 0xffffffffL)
1084 {
1085 L_var1 ^= (L_var1 >>31);
1086 for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
1087 {
1088 L_var1 <<= 1;
1089 }
1090 }
1091 }
1092 return (var_out);
1093 }
1094
1095 #endif //__BASIC_OP_H__
1096
1097