comparison src/basicop2.c @ 0:56410792419a

src: original EFR source from ETSI
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 03 Apr 2024 05:31:37 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:56410792419a
1 /*___________________________________________________________________________
2 | |
3 | Basic arithmetic operators. |
4 |___________________________________________________________________________|
5 */
6
7 /*___________________________________________________________________________
8 | |
9 | Include-Files |
10 |___________________________________________________________________________|
11 */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include "typedef.h"
16 #include "basic_op.h"
17
18 #if (WMOPS)
19 #include "count.h"
20 extern BASIC_OP counter;
21
22 #endif
23
24 /*___________________________________________________________________________
25 | |
26 | Local Functions |
27 |___________________________________________________________________________|
28 */
29 Word16 saturate (Word32 L_var1);
30
31 /*___________________________________________________________________________
32 | |
33 | Constants and Globals |
34 |___________________________________________________________________________|
35 */
36 Flag Overflow = 0;
37 Flag Carry = 0;
38
39 /*___________________________________________________________________________
40 | |
41 | Functions |
42 |___________________________________________________________________________|
43 */
44
45 /*___________________________________________________________________________
46 | |
47 | Function Name : saturate |
48 | |
49 | Purpose : |
50 | |
51 | Limit the 32 bit input to the range of a 16 bit word. |
52 | |
53 | Inputs : |
54 | |
55 | L_var1 |
56 | 32 bit long signed integer (Word32) whose value falls in the |
57 | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
58 | |
59 | Outputs : |
60 | |
61 | none |
62 | |
63 | Return Value : |
64 | |
65 | var_out |
66 | 16 bit short signed integer (Word16) whose value falls in the |
67 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
68 |___________________________________________________________________________|
69 */
70
71 Word16
72 saturate (Word32 L_var1)
73 {
74 Word16 var_out;
75
76 if (L_var1 > 0X00007fffL)
77 {
78 Overflow = 1;
79 var_out = MAX_16;
80 }
81 else if (L_var1 < (Word32) 0xffff8000L)
82 {
83 Overflow = 1;
84 var_out = MIN_16;
85 }
86 else
87 {
88 Overflow = 0;
89 var_out = extract_l (L_var1);
90 #if (WMOPS)
91 counter.extract_l--;
92 #endif
93 }
94
95 return (var_out);
96 }
97
98 /*___________________________________________________________________________
99 | |
100 | Function Name : add |
101 | |
102 | Purpose : |
103 | |
104 | Performs the addition (var1+var2) with overflow control and saturation;|
105 | the 16 bit result is set at +32767 when overflow occurs or at -32768 |
106 | when underflow occurs. |
107 | |
108 | Complexity weight : 1 |
109 | |
110 | Inputs : |
111 | |
112 | var1 |
113 | 16 bit short signed integer (Word16) whose value falls in the |
114 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
115 | |
116 | var2 |
117 | 16 bit short signed integer (Word16) whose value falls in the |
118 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
119 | |
120 | Outputs : |
121 | |
122 | none |
123 | |
124 | Return Value : |
125 | |
126 | var_out |
127 | 16 bit short signed integer (Word16) whose value falls in the |
128 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
129 |___________________________________________________________________________|
130 */
131
132 Word16 add (Word16 var1, Word16 var2)
133 {
134 Word16 var_out;
135 Word32 L_sum;
136
137 L_sum = (Word32) var1 + var2;
138 var_out = saturate (L_sum);
139 #if (WMOPS)
140 counter.add++;
141 #endif
142 return (var_out);
143 }
144
145 /*___________________________________________________________________________
146 | |
147 | Function Name : sub |
148 | |
149 | Purpose : |
150 | |
151 | Performs the subtraction (var1+var2) with overflow control and satu- |
152 | ration; the 16 bit result is set at +32767 when overflow occurs or at |
153 | -32768 when underflow occurs. |
154 | |
155 | Complexity weight : 1 |
156 | |
157 | Inputs : |
158 | |
159 | var1 |
160 | 16 bit short signed integer (Word16) whose value falls in the |
161 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
162 | |
163 | var2 |
164 | 16 bit short signed integer (Word16) whose value falls in the |
165 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
166 | |
167 | Outputs : |
168 | |
169 | none |
170 | |
171 | Return Value : |
172 | |
173 | var_out |
174 | 16 bit short signed integer (Word16) whose value falls in the |
175 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
176 |___________________________________________________________________________|
177 */
178
179 Word16 sub (Word16 var1, Word16 var2)
180 {
181 Word16 var_out;
182 Word32 L_diff;
183
184 L_diff = (Word32) var1 - var2;
185 var_out = saturate (L_diff);
186 #if (WMOPS)
187 counter.sub++;
188 #endif
189 return (var_out);
190 }
191
192 /*___________________________________________________________________________
193 | |
194 | Function Name : abs_s |
195 | |
196 | Purpose : |
197 | |
198 | Absolute value of var1; abs_s(-32768) = 32767. |
199 | |
200 | Complexity weight : 1 |
201 | |
202 | Inputs : |
203 | |
204 | var1 |
205 | 16 bit short signed integer (Word16) whose value falls in the |
206 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
207 | |
208 | Outputs : |
209 | |
210 | none |
211 | |
212 | Return Value : |
213 | |
214 | var_out |
215 | 16 bit short signed integer (Word16) whose value falls in the |
216 | range : 0x0000 0000 <= var_out <= 0x0000 7fff. |
217 |___________________________________________________________________________|
218 */
219
220 Word16 abs_s (Word16 var1)
221 {
222 Word16 var_out;
223
224 if (var1 == (Word16) 0X8000)
225 {
226 var_out = MAX_16;
227 }
228 else
229 {
230 if (var1 < 0)
231 {
232 var_out = -var1;
233 }
234 else
235 {
236 var_out = var1;
237 }
238 }
239 #if (WMOPS)
240 counter.abs_s++;
241 #endif
242 return (var_out);
243 }
244
245 /*___________________________________________________________________________
246 | |
247 | Function Name : shl |
248 | |
249 | Purpose : |
250 | |
251 | Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill|
252 | the var2 LSB of the result. If var2 is negative, arithmetically shift |
253 | var1 right by -var2 with sign extension. Saturate the result in case of |
254 | underflows or overflows. |
255 | |
256 | Complexity weight : 1 |
257 | |
258 | Inputs : |
259 | |
260 | var1 |
261 | 16 bit short signed integer (Word16) whose value falls in the |
262 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
263 | |
264 | var2 |
265 | 16 bit short signed integer (Word16) whose value falls in the |
266 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
267 | |
268 | Outputs : |
269 | |
270 | none |
271 | |
272 | Return Value : |
273 | |
274 | var_out |
275 | 16 bit short signed integer (Word16) whose value falls in the |
276 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
277 |___________________________________________________________________________|
278 */
279
280 Word16 shl (Word16 var1, Word16 var2)
281 {
282 Word16 var_out;
283 Word32 result;
284
285 if (var2 < 0)
286 {
287 var_out = shr (var1, -var2);
288 #if (WMOPS)
289 counter.shr--;
290 #endif
291 }
292 else
293 {
294 result = (Word32) var1 *((Word32) 1 << var2);
295
296 if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
297 {
298 Overflow = 1;
299 var_out = (var1 > 0) ? MAX_16 : MIN_16;
300 }
301 else
302 {
303 var_out = extract_l (result);
304 #if (WMOPS)
305 counter.extract_l--;
306 #endif
307 }
308 }
309 #if (WMOPS)
310 counter.shl++;
311 #endif
312 return (var_out);
313 }
314
315 /*___________________________________________________________________________
316 | |
317 | Function Name : shr |
318 | |
319 | Purpose : |
320 | |
321 | Arithmetically shift the 16 bit input var1 right var2 positions with |
322 | sign extension. If var2 is negative, arithmetically shift var1 left by |
323 | -var2 with sign extension. Saturate the result in case of underflows or |
324 | overflows. |
325 | |
326 | Complexity weight : 1 |
327 | |
328 | Inputs : |
329 | |
330 | var1 |
331 | 16 bit short signed integer (Word16) whose value falls in the |
332 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
333 | |
334 | var2 |
335 | 16 bit short signed integer (Word16) whose value falls in the |
336 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
337 | |
338 | Outputs : |
339 | |
340 | none |
341 | |
342 | Return Value : |
343 | |
344 | var_out |
345 | 16 bit short signed integer (Word16) whose value falls in the |
346 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
347 |___________________________________________________________________________|
348 */
349
350 Word16 shr (Word16 var1, Word16 var2)
351 {
352 Word16 var_out;
353
354 if (var2 < 0)
355 {
356 var_out = shl (var1, -var2);
357 #if (WMOPS)
358 counter.shl--;
359 #endif
360 }
361 else
362 {
363 if (var2 >= 15)
364 {
365 var_out = (var1 < 0) ? -1 : 0;
366 }
367 else
368 {
369 if (var1 < 0)
370 {
371 var_out = ~((~var1) >> var2);
372 }
373 else
374 {
375 var_out = var1 >> var2;
376 }
377 }
378 }
379
380 #if (WMOPS)
381 counter.shr++;
382 #endif
383 return (var_out);
384 }
385
386 /*___________________________________________________________________________
387 | |
388 | Function Name : mult |
389 | |
390 | Purpose : |
391 | |
392 | Performs the multiplication of var1 by var2 and gives a 16 bit result |
393 | which is scaled i.e.: |
394 | mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and |
395 | mult(-32768,-32768) = 32767. |
396 | |
397 | Complexity weight : 1 |
398 | |
399 | Inputs : |
400 | |
401 | var1 |
402 | 16 bit short signed integer (Word16) whose value falls in the |
403 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
404 | |
405 | var2 |
406 | 16 bit short signed integer (Word16) whose value falls in the |
407 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
408 | |
409 | Outputs : |
410 | |
411 | none |
412 | |
413 | Return Value : |
414 | |
415 | var_out |
416 | 16 bit short signed integer (Word16) whose value falls in the |
417 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
418 |___________________________________________________________________________|
419 */
420
421 Word16 mult (Word16 var1, Word16 var2)
422 {
423 Word16 var_out;
424 Word32 L_product;
425
426 L_product = (Word32) var1 *(Word32) var2;
427
428 L_product = (L_product & (Word32) 0xffff8000L) >> 15;
429
430 if (L_product & (Word32) 0x00010000L)
431 L_product = L_product | (Word32) 0xffff0000L;
432
433 var_out = saturate (L_product);
434 #if (WMOPS)
435 counter.mult++;
436 #endif
437 return (var_out);
438 }
439
440 /*___________________________________________________________________________
441 | |
442 | Function Name : L_mult |
443 | |
444 | Purpose : |
445 | |
446 | L_mult is the 32 bit result of the multiplication of var1 times var2 |
447 | with one shift left i.e.: |
448 | L_mult(var1,var2) = L_shl((var1 times var2),1) and |
449 | L_mult(-32768,-32768) = 2147483647. |
450 | |
451 | Complexity weight : 1 |
452 | |
453 | Inputs : |
454 | |
455 | var1 |
456 | 16 bit short signed integer (Word16) whose value falls in the |
457 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
458 | |
459 | var2 |
460 | 16 bit short signed integer (Word16) whose value falls in the |
461 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
462 | |
463 | Outputs : |
464 | |
465 | none |
466 | |
467 | Return Value : |
468 | |
469 | L_var_out |
470 | 32 bit long signed integer (Word32) whose value falls in the |
471 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
472 |___________________________________________________________________________|
473 */
474
475 Word32 L_mult (Word16 var1, Word16 var2)
476 {
477 Word32 L_var_out;
478
479 L_var_out = (Word32) var1 *(Word32) var2;
480
481 if (L_var_out != (Word32) 0x40000000L)
482 {
483 L_var_out *= 2;
484 }
485 else
486 {
487 Overflow = 1;
488 L_var_out = MAX_32;
489 }
490
491 #if (WMOPS)
492 counter.L_mult++;
493 #endif
494 return (L_var_out);
495 }
496
497 /*___________________________________________________________________________
498 | |
499 | Function Name : negate |
500 | |
501 | Purpose : |
502 | |
503 | Negate var1 with saturation, saturate in the case where input is -32768:|
504 | negate(var1) = sub(0,var1). |
505 | |
506 | Complexity weight : 1 |
507 | |
508 | Inputs : |
509 | |
510 | var1 |
511 | 16 bit short signed integer (Word16) whose value falls in the |
512 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
513 | |
514 | Outputs : |
515 | |
516 | none |
517 | |
518 | Return Value : |
519 | |
520 | var_out |
521 | 16 bit short signed integer (Word16) whose value falls in the |
522 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
523 |___________________________________________________________________________|
524 */
525
526 Word16 negate (Word16 var1)
527 {
528 Word16 var_out;
529
530 var_out = (var1 == MIN_16) ? MAX_16 : -var1;
531 #if (WMOPS)
532 counter.negate++;
533 #endif
534 return (var_out);
535 }
536
537 /*___________________________________________________________________________
538 | |
539 | Function Name : extract_h |
540 | |
541 | Purpose : |
542 | |
543 | Return the 16 MSB of L_var1. |
544 | |
545 | Complexity weight : 1 |
546 | |
547 | Inputs : |
548 | |
549 | L_var1 |
550 | 32 bit long signed integer (Word32 ) whose value falls in the |
551 | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
552 | |
553 | Outputs : |
554 | |
555 | none |
556 | |
557 | Return Value : |
558 | |
559 | var_out |
560 | 16 bit short signed integer (Word16) whose value falls in the |
561 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
562 |___________________________________________________________________________|
563 */
564
565 Word16 extract_h (Word32 L_var1)
566 {
567 Word16 var_out;
568
569 var_out = (Word16) (L_var1 >> 16);
570 #if (WMOPS)
571 counter.extract_h++;
572 #endif
573 return (var_out);
574 }
575
576 /*___________________________________________________________________________
577 | |
578 | Function Name : extract_l |
579 | |
580 | Purpose : |
581 | |
582 | Return the 16 LSB of L_var1. |
583 | |
584 | Complexity weight : 1 |
585 | |
586 | Inputs : |
587 | |
588 | L_var1 |
589 | 32 bit long signed integer (Word32 ) whose value falls in the |
590 | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
591 | |
592 | Outputs : |
593 | |
594 | none |
595 | |
596 | Return Value : |
597 | |
598 | var_out |
599 | 16 bit short signed integer (Word16) whose value falls in the |
600 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
601 |___________________________________________________________________________|
602 */
603
604 Word16 extract_l (Word32 L_var1)
605 {
606 Word16 var_out;
607
608 var_out = (Word16) L_var1;
609 #if (WMOPS)
610 counter.extract_l++;
611 #endif
612 return (var_out);
613 }
614
615 /*___________________________________________________________________________
616 | |
617 | Function Name : round |
618 | |
619 | Purpose : |
620 | |
621 | Round the lower 16 bits of the 32 bit input number into the MS 16 bits |
622 | with saturation. Shift the resulting bits right by 16 and return the 16 |
623 | bit number: |
624 | round(L_var1) = extract_h(L_add(L_var1,32768)) |
625 | |
626 | Complexity weight : 1 |
627 | |
628 | Inputs : |
629 | |
630 | L_var1 |
631 | 32 bit long signed integer (Word32 ) whose value falls in the |
632 | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
633 | |
634 | Outputs : |
635 | |
636 | none |
637 | |
638 | Return Value : |
639 | |
640 | var_out |
641 | 16 bit short signed integer (Word16) whose value falls in the |
642 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
643 |___________________________________________________________________________|
644 */
645
646 Word16 round (Word32 L_var1)
647 {
648 Word16 var_out;
649 Word32 L_rounded;
650
651 L_rounded = L_add (L_var1, (Word32) 0x00008000L);
652 #if (WMOPS)
653 counter.L_add--;
654 #endif
655 var_out = extract_h (L_rounded);
656 #if (WMOPS)
657 counter.extract_h--;
658 counter.round++;
659 #endif
660 return (var_out);
661 }
662
663 /*___________________________________________________________________________
664 | |
665 | Function Name : L_mac |
666 | |
667 | Purpose : |
668 | |
669 | Multiply var1 by var2 and shift the result left by 1. Add the 32 bit |
670 | result to L_var3 with saturation, return a 32 bit result: |
671 | L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)). |
672 | |
673 | Complexity weight : 1 |
674 | |
675 | Inputs : |
676 | |
677 | L_var3 32 bit long signed integer (Word32) whose value falls in the |
678 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
679 | |
680 | var1 |
681 | 16 bit short signed integer (Word16) whose value falls in the |
682 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
683 | |
684 | var2 |
685 | 16 bit short signed integer (Word16) whose value falls in the |
686 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
687 | |
688 | Outputs : |
689 | |
690 | none |
691 | |
692 | Return Value : |
693 | |
694 | L_var_out |
695 | 32 bit long signed integer (Word32) whose value falls in the |
696 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
697 |___________________________________________________________________________|
698 */
699
700 Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
701 {
702 Word32 L_var_out;
703 Word32 L_product;
704
705 L_product = L_mult (var1, var2);
706 #if (WMOPS)
707 counter.L_mult--;
708 #endif
709 L_var_out = L_add (L_var3, L_product);
710 #if (WMOPS)
711 counter.L_add--;
712 counter.L_mac++;
713 #endif
714 return (L_var_out);
715 }
716
717 /*___________________________________________________________________________
718 | |
719 | Function Name : L_msu |
720 | |
721 | Purpose : |
722 | |
723 | Multiply var1 by var2 and shift the result left by 1. Subtract the 32 |
724 | bit result to L_var3 with saturation, return a 32 bit result: |
725 | L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)). |
726 | |
727 | Complexity weight : 1 |
728 | |
729 | Inputs : |
730 | |
731 | L_var3 32 bit long signed integer (Word32) whose value falls in the |
732 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
733 | |
734 | var1 |
735 | 16 bit short signed integer (Word16) whose value falls in the |
736 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
737 | |
738 | var2 |
739 | 16 bit short signed integer (Word16) whose value falls in the |
740 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
741 | |
742 | Outputs : |
743 | |
744 | none |
745 | |
746 | Return Value : |
747 | |
748 | L_var_out |
749 | 32 bit long signed integer (Word32) whose value falls in the |
750 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
751 |___________________________________________________________________________|
752 */
753
754 Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
755 {
756 Word32 L_var_out;
757 Word32 L_product;
758
759 L_product = L_mult (var1, var2);
760 #if (WMOPS)
761 counter.L_mult--;
762 #endif
763 L_var_out = L_sub (L_var3, L_product);
764 #if (WMOPS)
765 counter.L_sub--;
766 counter.L_msu++;
767 #endif
768 return (L_var_out);
769 }
770
771 /*___________________________________________________________________________
772 | |
773 | Function Name : L_macNs |
774 | |
775 | Purpose : |
776 | |
777 | Multiply var1 by var2 and shift the result left by 1. Add the 32 bit |
778 | result to L_var3 without saturation, return a 32 bit result. Generate |
779 | carry and overflow values : |
780 | L_macNs(L_var3,var1,var2) = L_add_c(L_var3,L_mult(var1,var2)). |
781 | |
782 | Complexity weight : 1 |
783 | |
784 | Inputs : |
785 | |
786 | L_var3 32 bit long signed integer (Word32) whose value falls in the |
787 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
788 | |
789 | var1 |
790 | 16 bit short signed integer (Word16) whose value falls in the |
791 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
792 | |
793 | var2 |
794 | 16 bit short signed integer (Word16) whose value falls in the |
795 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
796 | |
797 | Outputs : |
798 | |
799 | none |
800 | |
801 | Return Value : |
802 | |
803 | L_var_out |
804 | 32 bit long signed integer (Word32) whose value falls in the |
805 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
806 | |
807 | Caution : |
808 | |
809 | In some cases the Carry flag has to be cleared or set before using |
810 | operators which take into account its value. |
811 |___________________________________________________________________________|
812 */
813
814 Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2)
815 {
816 Word32 L_var_out;
817
818 L_var_out = L_mult (var1, var2);
819 #if (WMOPS)
820 counter.L_mult--;
821 #endif
822 L_var_out = L_add_c (L_var3, L_var_out);
823 #if (WMOPS)
824 counter.L_add_c--;
825 counter.L_macNs++;
826 #endif
827 return (L_var_out);
828 }
829
830 /*___________________________________________________________________________
831 | |
832 | Function Name : L_msuNs |
833 | |
834 | Purpose : |
835 | |
836 | Multiply var1 by var2 and shift the result left by 1. Subtract the 32 |
837 | bit result from L_var3 without saturation, return a 32 bit result. Ge- |
838 | nerate carry and overflow values : |
839 | L_msuNs(L_var3,var1,var2) = L_sub_c(L_var3,L_mult(var1,var2)). |
840 | |
841 | Complexity weight : 1 |
842 | |
843 | Inputs : |
844 | |
845 | L_var3 32 bit long signed integer (Word32) whose value falls in the |
846 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
847 | |
848 | var1 |
849 | 16 bit short signed integer (Word16) whose value falls in the |
850 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
851 | |
852 | var2 |
853 | 16 bit short signed integer (Word16) whose value falls in the |
854 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
855 | |
856 | Outputs : |
857 | |
858 | none |
859 | |
860 | Return Value : |
861 | |
862 | L_var_out |
863 | 32 bit long signed integer (Word32) whose value falls in the |
864 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
865 | |
866 | Caution : |
867 | |
868 | In some cases the Carry flag has to be cleared or set before using |
869 | operators which take into account its value. |
870 |___________________________________________________________________________|
871 */
872
873 Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2)
874 {
875 Word32 L_var_out;
876
877 L_var_out = L_mult (var1, var2);
878 #if (WMOPS)
879 counter.L_mult--;
880 #endif
881 L_var_out = L_sub_c (L_var3, L_var_out);
882 #if (WMOPS)
883 counter.L_sub_c--;
884 counter.L_msuNs++;
885 #endif
886 return (L_var_out);
887 }
888
889 /*___________________________________________________________________________
890 | |
891 | Function Name : L_add |
892 | |
893 | Purpose : |
894 | |
895 | 32 bits addition of the two 32 bits variables (L_var1+L_var2) with |
896 | overflow control and saturation; the result is set at +2147483647 when |
897 | overflow occurs or at -2147483648 when underflow occurs. |
898 | |
899 | Complexity weight : 2 |
900 | |
901 | Inputs : |
902 | |
903 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
904 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
905 | |
906 | L_var2 32 bit long signed integer (Word32) whose value falls in the |
907 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
908 | |
909 | Outputs : |
910 | |
911 | none |
912 | |
913 | Return Value : |
914 | |
915 | L_var_out |
916 | 32 bit long signed integer (Word32) whose value falls in the |
917 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
918 |___________________________________________________________________________|
919 */
920
921 Word32 L_add (Word32 L_var1, Word32 L_var2)
922 {
923 Word32 L_var_out;
924
925 L_var_out = L_var1 + L_var2;
926
927 if (((L_var1 ^ L_var2) & MIN_32) == 0)
928 {
929 if ((L_var_out ^ L_var1) & MIN_32)
930 {
931 L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
932 Overflow = 1;
933 }
934 }
935 #if (WMOPS)
936 counter.L_add++;
937 #endif
938 return (L_var_out);
939 }
940
941 /*___________________________________________________________________________
942 | |
943 | Function Name : L_sub |
944 | |
945 | Purpose : |
946 | |
947 | 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with |
948 | overflow control and saturation; the result is set at +2147483647 when |
949 | overflow occurs or at -2147483648 when underflow occurs. |
950 | |
951 | Complexity weight : 2 |
952 | |
953 | Inputs : |
954 | |
955 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
956 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
957 | |
958 | L_var2 32 bit long signed integer (Word32) whose value falls in the |
959 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
960 | |
961 | Outputs : |
962 | |
963 | none |
964 | |
965 | Return Value : |
966 | |
967 | L_var_out |
968 | 32 bit long signed integer (Word32) whose value falls in the |
969 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
970 |___________________________________________________________________________|
971 */
972
973 Word32 L_sub (Word32 L_var1, Word32 L_var2)
974 {
975 Word32 L_var_out;
976
977 L_var_out = L_var1 - L_var2;
978
979 if (((L_var1 ^ L_var2) & MIN_32) != 0)
980 {
981 if ((L_var_out ^ L_var1) & MIN_32)
982 {
983 L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
984 Overflow = 1;
985 }
986 }
987 #if (WMOPS)
988 counter.L_sub++;
989 #endif
990 return (L_var_out);
991 }
992
993 /*___________________________________________________________________________
994 | |
995 | Function Name : L_add_c |
996 | |
997 | Purpose : |
998 | |
999 | Performs 32 bits addition of the two 32 bits variables (L_var1+L_var2+C)|
1000 | with carry. No saturation. Generate carry and Overflow values. The car- |
1001 | ry and overflow values are binary variables which can be tested and as- |
1002 | signed values. |
1003 | |
1004 | Complexity weight : 2 |
1005 | |
1006 | Inputs : |
1007 | |
1008 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
1009 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
1010 | |
1011 | L_var2 32 bit long signed integer (Word32) whose value falls in the |
1012 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
1013 | |
1014 | Outputs : |
1015 | |
1016 | none |
1017 | |
1018 | Return Value : |
1019 | |
1020 | L_var_out |
1021 | 32 bit long signed integer (Word32) whose value falls in the |
1022 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
1023 | |
1024 | Caution : |
1025 | |
1026 | In some cases the Carry flag has to be cleared or set before using |
1027 | operators which take into account its value. |
1028 |___________________________________________________________________________|
1029 */
1030 Word32 L_add_c (Word32 L_var1, Word32 L_var2)
1031 {
1032 Word32 L_var_out;
1033 Word32 L_test;
1034 Flag carry_int = 0;
1035
1036 L_var_out = L_var1 + L_var2 + Carry;
1037
1038 L_test = L_var1 + L_var2;
1039
1040 if ((L_var1 > 0) && (L_var2 > 0) && (L_test < 0))
1041 {
1042 Overflow = 1;
1043 carry_int = 0;
1044 }
1045 else
1046 {
1047 if ((L_var1 < 0) && (L_var2 < 0))
1048 {
1049 if (L_test >= 0)
1050 {
1051 Overflow = 1;
1052 carry_int = 1;
1053 }
1054 else
1055 {
1056 Overflow = 0;
1057 carry_int = 1;
1058 }
1059 }
1060 else
1061 {
1062 if (((L_var1 ^ L_var2) < 0) && (L_test >= 0))
1063 {
1064 Overflow = 0;
1065 carry_int = 1;
1066 }
1067 else
1068 {
1069 Overflow = 0;
1070 carry_int = 0;
1071 }
1072 }
1073 }
1074
1075 if (Carry)
1076 {
1077 if (L_test == MAX_32)
1078 {
1079 Overflow = 1;
1080 Carry = carry_int;
1081 }
1082 else
1083 {
1084 if (L_test == (Word32) 0xFFFFFFFFL)
1085 {
1086 Carry = 1;
1087 }
1088 else
1089 {
1090 Carry = carry_int;
1091 }
1092 }
1093 }
1094 else
1095 {
1096 Carry = carry_int;
1097 }
1098
1099 #if (WMOPS)
1100 counter.L_add_c++;
1101 #endif
1102 return (L_var_out);
1103 }
1104
1105 /*___________________________________________________________________________
1106 | |
1107 | Function Name : L_sub_c |
1108 | |
1109 | Purpose : |
1110 | |
1111 | Performs 32 bits subtraction of the two 32 bits variables with carry |
1112 | (borrow) : L_var1-L_var2-C. No saturation. Generate carry and Overflow |
1113 | values. The carry and overflow values are binary variables which can |
1114 | be tested and assigned values. |
1115 | |
1116 | Complexity weight : 2 |
1117 | |
1118 | Inputs : |
1119 | |
1120 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
1121 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
1122 | |
1123 | L_var2 32 bit long signed integer (Word32) whose value falls in the |
1124 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
1125 | |
1126 | Outputs : |
1127 | |
1128 | none |
1129 | |
1130 | Return Value : |
1131 | |
1132 | L_var_out |
1133 | 32 bit long signed integer (Word32) whose value falls in the |
1134 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
1135 | |
1136 | Caution : |
1137 | |
1138 | In some cases the Carry flag has to be cleared or set before using |
1139 | operators which take into account its value. |
1140 |___________________________________________________________________________|
1141 */
1142
1143 Word32 L_sub_c (Word32 L_var1, Word32 L_var2)
1144 {
1145 Word32 L_var_out;
1146 Word32 L_test;
1147 Flag carry_int = 0;
1148
1149 if (Carry)
1150 {
1151 Carry = 0;
1152 if (L_var2 != MIN_32)
1153 {
1154 L_var_out = L_add_c (L_var1, -L_var2);
1155 #if (WMOPS)
1156 counter.L_add_c--;
1157 #endif
1158 }
1159 else
1160 {
1161 L_var_out = L_var1 - L_var2;
1162 if (L_var1 > 0L)
1163 {
1164 Overflow = 1;
1165 Carry = 0;
1166 }
1167 }
1168 }
1169 else
1170 {
1171 L_var_out = L_var1 - L_var2 - (Word32) 0X00000001L;
1172 L_test = L_var1 - L_var2;
1173
1174 if ((L_test < 0) && (L_var1 > 0) && (L_var2 < 0))
1175 {
1176 Overflow = 1;
1177 carry_int = 0;
1178 }
1179 else if ((L_test > 0) && (L_var1 < 0) && (L_var2 > 0))
1180 {
1181 Overflow = 1;
1182 carry_int = 1;
1183 }
1184 else if ((L_test > 0) && ((L_var1 ^ L_var2) > 0))
1185 {
1186 Overflow = 0;
1187 carry_int = 1;
1188 }
1189 if (L_test == MIN_32)
1190 {
1191 Overflow = 1;
1192 Carry = carry_int;
1193 }
1194 else
1195 {
1196 Carry = carry_int;
1197 }
1198 }
1199
1200 #if (WMOPS)
1201 counter.L_sub_c++;
1202 #endif
1203 return (L_var_out);
1204 }
1205
1206 /*___________________________________________________________________________
1207 | |
1208 | Function Name : L_negate |
1209 | |
1210 | Purpose : |
1211 | |
1212 | Negate the 32 bit variable L_var1 with saturation; saturate in the case |
1213 | where input is -2147483648 (0x8000 0000). |
1214 | |
1215 | Complexity weight : 2 |
1216 | |
1217 | Inputs : |
1218 | |
1219 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
1220 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
1221 | |
1222 | Outputs : |
1223 | |
1224 | none |
1225 | |
1226 | Return Value : |
1227 | |
1228 | L_var_out |
1229 | 32 bit long signed integer (Word32) whose value falls in the |
1230 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
1231 |___________________________________________________________________________|
1232 */
1233
1234 Word32 L_negate (Word32 L_var1)
1235 {
1236 Word32 L_var_out;
1237
1238 L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1;
1239 #if (WMOPS)
1240 counter.L_negate++;
1241 #endif
1242 return (L_var_out);
1243 }
1244
1245 /*___________________________________________________________________________
1246 | |
1247 | Function Name : mult_r |
1248 | |
1249 | Purpose : |
1250 | |
1251 | Same as mult with rounding, i.e.: |
1252 | mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and |
1253 | mult_r(-32768,-32768) = 32767. |
1254 | |
1255 | Complexity weight : 2 |
1256 | |
1257 | Inputs : |
1258 | |
1259 | var1 |
1260 | 16 bit short signed integer (Word16) whose value falls in the |
1261 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1262 | |
1263 | var2 |
1264 | 16 bit short signed integer (Word16) whose value falls in the |
1265 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1266 | |
1267 | Outputs : |
1268 | |
1269 | none |
1270 | |
1271 | Return Value : |
1272 | |
1273 | var_out |
1274 | 16 bit short signed integer (Word16) whose value falls in the |
1275 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
1276 |___________________________________________________________________________|
1277 */
1278
1279 Word16 mult_r (Word16 var1, Word16 var2)
1280 {
1281 Word16 var_out;
1282 Word32 L_product_arr;
1283
1284 L_product_arr = (Word32) var1 *(Word32) var2; /* product */
1285 L_product_arr += (Word32) 0x00004000L; /* round */
1286 L_product_arr &= (Word32) 0xffff8000L;
1287 L_product_arr >>= 15; /* shift */
1288
1289 if (L_product_arr & (Word32) 0x00010000L) /* sign extend when necessary */
1290 {
1291 L_product_arr |= (Word32) 0xffff0000L;
1292 }
1293 var_out = saturate (L_product_arr);
1294 #if (WMOPS)
1295 counter.mult_r++;
1296 #endif
1297 return (var_out);
1298 }
1299
1300 /*___________________________________________________________________________
1301 | |
1302 | Function Name : L_shl |
1303 | |
1304 | Purpose : |
1305 | |
1306 | Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero |
1307 | fill the var2 LSB of the result. If var2 is negative, arithmetically |
1308 | shift L_var1 right by -var2 with sign extension. Saturate the result in |
1309 | case of underflows or overflows. |
1310 | |
1311 | Complexity weight : 2 |
1312 | |
1313 | Inputs : |
1314 | |
1315 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
1316 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
1317 | |
1318 | var2 |
1319 | 16 bit short signed integer (Word16) whose value falls in the |
1320 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1321 | |
1322 | Outputs : |
1323 | |
1324 | none |
1325 | |
1326 | Return Value : |
1327 | |
1328 | L_var_out |
1329 | 32 bit long signed integer (Word32) whose value falls in the |
1330 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
1331 |___________________________________________________________________________|
1332 */
1333
1334 Word32 L_shl (Word32 L_var1, Word16 var2)
1335 {
1336 Word32 L_var_out;
1337
1338 if (var2 <= 0)
1339 {
1340 L_var_out = L_shr (L_var1, -var2);
1341 #if (WMOPS)
1342 counter.L_shr--;
1343 #endif
1344 }
1345 else
1346 {
1347 for (; var2 > 0; var2--)
1348 {
1349 if (L_var1 > (Word32) 0X3fffffffL)
1350 {
1351 Overflow = 1;
1352 L_var_out = MAX_32;
1353 break;
1354 }
1355 else
1356 {
1357 if (L_var1 < (Word32) 0xc0000000L)
1358 {
1359 Overflow = 1;
1360 L_var_out = MIN_32;
1361 break;
1362 }
1363 }
1364 L_var1 *= 2;
1365 L_var_out = L_var1;
1366 }
1367 }
1368 #if (WMOPS)
1369 counter.L_shl++;
1370 #endif
1371 return (L_var_out);
1372 }
1373
1374 /*___________________________________________________________________________
1375 | |
1376 | Function Name : L_shr |
1377 | |
1378 | Purpose : |
1379 | |
1380 | Arithmetically shift the 32 bit input L_var1 right var2 positions with |
1381 | sign extension. If var2 is negative, arithmetically shift L_var1 left |
1382 | by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
1383 | in case of underflows or overflows. |
1384 | |
1385 | Complexity weight : 2 |
1386 | |
1387 | Inputs : |
1388 | |
1389 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
1390 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
1391 | |
1392 | var2 |
1393 | 16 bit short signed integer (Word16) whose value falls in the |
1394 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1395 | |
1396 | Outputs : |
1397 | |
1398 | none |
1399 | |
1400 | Return Value : |
1401 | |
1402 | L_var_out |
1403 | 32 bit long signed integer (Word32) whose value falls in the |
1404 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
1405 |___________________________________________________________________________|
1406 */
1407
1408 Word32 L_shr (Word32 L_var1, Word16 var2)
1409 {
1410 Word32 L_var_out;
1411
1412 if (var2 < 0)
1413 {
1414 L_var_out = L_shl (L_var1, -var2);
1415 #if (WMOPS)
1416 counter.L_shl--;
1417 #endif
1418 }
1419 else
1420 {
1421 if (var2 >= 31)
1422 {
1423 L_var_out = (L_var1 < 0L) ? -1 : 0;
1424 }
1425 else
1426 {
1427 if (L_var1 < 0)
1428 {
1429 L_var_out = ~((~L_var1) >> var2);
1430 }
1431 else
1432 {
1433 L_var_out = L_var1 >> var2;
1434 }
1435 }
1436 }
1437 #if (WMOPS)
1438 counter.L_shr++;
1439 #endif
1440 return (L_var_out);
1441 }
1442
1443 /*___________________________________________________________________________
1444 | |
1445 | Function Name : shr_r |
1446 | |
1447 | Purpose : |
1448 | |
1449 | Same as shr(var1,var2) but with rounding. Saturate the result in case of|
1450 | underflows or overflows : |
1451 | - If var2 is greater than zero : |
1452 | if (sub(shl(shr(var1,var2),1),shr(var1,sub(var2,1)))) |
1453 | is equal to zero |
1454 | then |
1455 | shr_r(var1,var2) = shr(var1,var2) |
1456 | else |
1457 | shr_r(var1,var2) = add(shr(var1,var2),1) |
1458 | - If var2 is less than or equal to zero : |
1459 | shr_r(var1,var2) = shr(var1,var2). |
1460 | |
1461 | Complexity weight : 2 |
1462 | |
1463 | Inputs : |
1464 | |
1465 | var1 |
1466 | 16 bit short signed integer (Word16) whose value falls in the |
1467 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1468 | |
1469 | var2 |
1470 | 16 bit short signed integer (Word16) whose value falls in the |
1471 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1472 | |
1473 | Outputs : |
1474 | |
1475 | none |
1476 | |
1477 | Return Value : |
1478 | |
1479 | var_out |
1480 | 16 bit short signed integer (Word16) whose value falls in the |
1481 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
1482 |___________________________________________________________________________|
1483 */
1484
1485 Word16 shr_r (Word16 var1, Word16 var2)
1486 {
1487 Word16 var_out;
1488
1489 if (var2 > 15)
1490 {
1491 var_out = 0;
1492 }
1493 else
1494 {
1495 var_out = shr (var1, var2);
1496 #if (WMOPS)
1497 counter.shr--;
1498 #endif
1499
1500 if (var2 > 0)
1501 {
1502 if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
1503 {
1504 var_out++;
1505 }
1506 }
1507 }
1508 #if (WMOPS)
1509 counter.shr_r++;
1510 #endif
1511 return (var_out);
1512 }
1513
1514 /*___________________________________________________________________________
1515 | |
1516 | Function Name : mac_r |
1517 | |
1518 | Purpose : |
1519 | |
1520 | Multiply var1 by var2 and shift the result left by 1. Add the 32 bit |
1521 | result to L_var3 with saturation. Round the LS 16 bits of the result |
1522 | into the MS 16 bits with saturation and shift the result right by 16. |
1523 | Return a 16 bit result. |
1524 | mac_r(L_var3,var1,var2) = round(L_mac(L_var3,var1,var2)) |
1525 | |
1526 | Complexity weight : 2 |
1527 | |
1528 | Inputs : |
1529 | |
1530 | L_var3 32 bit long signed integer (Word32) whose value falls in the |
1531 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
1532 | |
1533 | var1 |
1534 | 16 bit short signed integer (Word16) whose value falls in the |
1535 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1536 | |
1537 | var2 |
1538 | 16 bit short signed integer (Word16) whose value falls in the |
1539 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1540 | |
1541 | Outputs : |
1542 | |
1543 | none |
1544 | |
1545 | Return Value : |
1546 | |
1547 | var_out |
1548 | 16 bit short signed integer (Word16) whose value falls in the |
1549 | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. |
1550 |___________________________________________________________________________|
1551 */
1552
1553 Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
1554 {
1555 Word16 var_out;
1556
1557 L_var3 = L_mac (L_var3, var1, var2);
1558 #if (WMOPS)
1559 counter.L_mac--;
1560 #endif
1561 L_var3 = L_add (L_var3, (Word32) 0x00008000L);
1562 #if (WMOPS)
1563 counter.L_add--;
1564 #endif
1565 var_out = extract_h (L_var3);
1566 #if (WMOPS)
1567 counter.extract_h--;
1568 counter.mac_r++;
1569 #endif
1570 return (var_out);
1571 }
1572
1573 /*___________________________________________________________________________
1574 | |
1575 | Function Name : msu_r |
1576 | |
1577 | Purpose : |
1578 | |
1579 | Multiply var1 by var2 and shift the result left by 1. Subtract the 32 |
1580 | bit result to L_var3 with saturation. Round the LS 16 bits of the res- |
1581 | ult into the MS 16 bits with saturation and shift the result right by |
1582 | 16. Return a 16 bit result. |
1583 | msu_r(L_var3,var1,var2) = round(L_msu(L_var3,var1,var2)) |
1584 | |
1585 | Complexity weight : 2 |
1586 | |
1587 | Inputs : |
1588 | |
1589 | L_var3 32 bit long signed integer (Word32) whose value falls in the |
1590 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
1591 | |
1592 | var1 |
1593 | 16 bit short signed integer (Word16) whose value falls in the |
1594 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1595 | |
1596 | var2 |
1597 | 16 bit short signed integer (Word16) whose value falls in the |
1598 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1599 | |
1600 | Outputs : |
1601 | |
1602 | none |
1603 | |
1604 | Return Value : |
1605 | |
1606 | var_out |
1607 | 16 bit short signed integer (Word16) whose value falls in the |
1608 | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. |
1609 |___________________________________________________________________________|
1610 */
1611
1612 Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
1613 {
1614 Word16 var_out;
1615
1616 L_var3 = L_msu (L_var3, var1, var2);
1617 #if (WMOPS)
1618 counter.L_msu--;
1619 #endif
1620 L_var3 = L_add (L_var3, (Word32) 0x00008000L);
1621 #if (WMOPS)
1622 counter.L_add--;
1623 #endif
1624 var_out = extract_h (L_var3);
1625 #if (WMOPS)
1626 counter.extract_h--;
1627 counter.msu_r++;
1628 #endif
1629 return (var_out);
1630 }
1631
1632 /*___________________________________________________________________________
1633 | |
1634 | Function Name : L_deposit_h |
1635 | |
1636 | Purpose : |
1637 | |
1638 | Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The |
1639 | 16 LS bits of the output are zeroed. |
1640 | |
1641 | Complexity weight : 2 |
1642 | |
1643 | Inputs : |
1644 | |
1645 | var1 |
1646 | 16 bit short signed integer (Word16) whose value falls in the |
1647 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1648 | |
1649 | Outputs : |
1650 | |
1651 | none |
1652 | |
1653 | Return Value : |
1654 | |
1655 | L_var_out |
1656 | 32 bit long signed integer (Word32) whose value falls in the |
1657 | range : 0x8000 0000 <= var_out <= 0x7fff 0000. |
1658 |___________________________________________________________________________|
1659 */
1660
1661 Word32 L_deposit_h (Word16 var1)
1662 {
1663 Word32 L_var_out;
1664
1665 L_var_out = (Word32) var1 << 16;
1666 #if (WMOPS)
1667 counter.L_deposit_h++;
1668 #endif
1669 return (L_var_out);
1670 }
1671
1672 /*___________________________________________________________________________
1673 | |
1674 | Function Name : L_deposit_l |
1675 | |
1676 | Purpose : |
1677 | |
1678 | Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The |
1679 | 16 MS bits of the output are sign extended. |
1680 | |
1681 | Complexity weight : 2 |
1682 | |
1683 | Inputs : |
1684 | |
1685 | var1 |
1686 | 16 bit short signed integer (Word16) whose value falls in the |
1687 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1688 | |
1689 | Outputs : |
1690 | |
1691 | none |
1692 | |
1693 | Return Value : |
1694 | |
1695 | L_var_out |
1696 | 32 bit long signed integer (Word32) whose value falls in the |
1697 | range : 0xFFFF 8000 <= var_out <= 0x0000 7fff. |
1698 |___________________________________________________________________________|
1699 */
1700
1701 Word32 L_deposit_l (Word16 var1)
1702 {
1703 Word32 L_var_out;
1704
1705 L_var_out = (Word32) var1;
1706 #if (WMOPS)
1707 counter.L_deposit_l++;
1708 #endif
1709 return (L_var_out);
1710 }
1711
1712 /*___________________________________________________________________________
1713 | |
1714 | Function Name : L_shr_r |
1715 | |
1716 | Purpose : |
1717 | |
1718 | Same as L_shr(L_var1,var2) but with rounding. Saturate the result in |
1719 | case of underflows or overflows : |
1720 | - If var2 is greater than zero : |
1721 | if (L_sub(L_shl(L_shr(L_var1,var2),1),L_shr(L_var1,sub(var2,1))))|
1722 | is equal to zero |
1723 | then |
1724 | L_shr_r(L_var1,var2) = L_shr(L_var1,var2) |
1725 | else |
1726 | L_shr_r(L_var1,var2) = L_add(L_shr(L_var1,var2),1) |
1727 | - If var2 is less than or equal to zero : |
1728 | L_shr_r(L_var1,var2) = L_shr(L_var1,var2). |
1729 | |
1730 | Complexity weight : 3 |
1731 | |
1732 | Inputs : |
1733 | |
1734 | L_var1 |
1735 | 32 bit long signed integer (Word32) whose value falls in the |
1736 | range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
1737 | |
1738 | var2 |
1739 | 16 bit short signed integer (Word16) whose value falls in the |
1740 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1741 | |
1742 | Outputs : |
1743 | |
1744 | none |
1745 | |
1746 | Return Value : |
1747 | |
1748 | L_var_out |
1749 | 32 bit long signed integer (Word32) whose value falls in the |
1750 | range : 0x8000 0000 <= var_out <= 0x7fff ffff. |
1751 |___________________________________________________________________________|
1752 */
1753
1754 Word32 L_shr_r (Word32 L_var1, Word16 var2)
1755 {
1756 Word32 L_var_out;
1757
1758 if (var2 > 31)
1759 {
1760 L_var_out = 0;
1761 }
1762 else
1763 {
1764 L_var_out = L_shr (L_var1, var2);
1765 #if (WMOPS)
1766 counter.L_shr--;
1767 #endif
1768 if (var2 > 0)
1769 {
1770 if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
1771 {
1772 L_var_out++;
1773 }
1774 }
1775 }
1776 #if (WMOPS)
1777 counter.L_shr_r++;
1778 #endif
1779 return (L_var_out);
1780 }
1781
1782 /*___________________________________________________________________________
1783 | |
1784 | Function Name : L_abs |
1785 | |
1786 | Purpose : |
1787 | |
1788 | Absolute value of L_var1; Saturate in case where the input is |
1789 | -214783648 |
1790 | |
1791 | Complexity weight : 3 |
1792 | |
1793 | Inputs : |
1794 | |
1795 | L_var1 |
1796 | 32 bit long signed integer (Word32) whose value falls in the |
1797 | range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
1798 | |
1799 | Outputs : |
1800 | |
1801 | none |
1802 | |
1803 | Return Value : |
1804 | |
1805 | L_var_out |
1806 | 32 bit long signed integer (Word32) whose value falls in the |
1807 | range : 0x0000 0000 <= var_out <= 0x7fff ffff. |
1808 |___________________________________________________________________________|
1809 */
1810
1811 Word32 L_abs (Word32 L_var1)
1812 {
1813 Word32 L_var_out;
1814
1815 if (L_var1 == MIN_32)
1816 {
1817 L_var_out = MAX_32;
1818 }
1819 else
1820 {
1821 if (L_var1 < 0)
1822 {
1823 L_var_out = -L_var1;
1824 }
1825 else
1826 {
1827 L_var_out = L_var1;
1828 }
1829 }
1830
1831 #if (WMOPS)
1832 counter.L_abs++;
1833 #endif
1834 return (L_var_out);
1835 }
1836
1837 /*___________________________________________________________________________
1838 | |
1839 | Function Name : L_sat |
1840 | |
1841 | Purpose : |
1842 | |
1843 | 32 bit L_var1 is set to 2147483647 if an overflow occured or to |
1844 | -2147483648 if an underflow occured on the most recent L_add_c, |
1845 | L_sub_c, L_macNs or L_msuNs operations. The carry and overflow values |
1846 | are binary values which can be tested and assigned values. |
1847 | |
1848 | Complexity weight : 4 |
1849 | |
1850 | Inputs : |
1851 | |
1852 | L_var1 |
1853 | 32 bit long signed integer (Word32) whose value falls in the |
1854 | range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
1855 | |
1856 | Outputs : |
1857 | |
1858 | none |
1859 | |
1860 | Return Value : |
1861 | |
1862 | L_var_out |
1863 | 32 bit long signed integer (Word32) whose value falls in the |
1864 | range : 0x8000 0000 <= var_out <= 0x7fff ffff. |
1865 |___________________________________________________________________________|
1866 */
1867
1868 Word32 L_sat (Word32 L_var1)
1869 {
1870 Word32 L_var_out;
1871
1872 L_var_out = L_var1;
1873
1874 if (Overflow)
1875 {
1876
1877 if (Carry)
1878 {
1879 L_var_out = MIN_32;
1880 }
1881 else
1882 {
1883 L_var_out = MAX_32;
1884 }
1885
1886 Carry = 0;
1887 Overflow = 0;
1888 }
1889 #if (WMOPS)
1890 counter.L_sat++;
1891 #endif
1892 return (L_var_out);
1893 }
1894
1895 /*___________________________________________________________________________
1896 | |
1897 | Function Name : norm_s |
1898 | |
1899 | Purpose : |
1900 | |
1901 | Produces the number of left shift needed to normalize the 16 bit varia- |
1902 | ble var1 for positive values on the interval with minimum of 16384 and |
1903 | maximum of 32767, and for negative values on the interval with minimum |
1904 | of -32768 and maximum of -16384; in order to normalize the result, the |
1905 | following operation must be done : |
1906 | norm_var1 = shl(var1,norm_s(var1)). |
1907 | |
1908 | Complexity weight : 15 |
1909 | |
1910 | Inputs : |
1911 | |
1912 | var1 |
1913 | 16 bit short signed integer (Word16) whose value falls in the |
1914 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1915 | |
1916 | Outputs : |
1917 | |
1918 | none |
1919 | |
1920 | Return Value : |
1921 | |
1922 | var_out |
1923 | 16 bit short signed integer (Word16) whose value falls in the |
1924 | range : 0x0000 0000 <= var_out <= 0x0000 000f. |
1925 |___________________________________________________________________________|
1926 */
1927
1928 Word16 norm_s (Word16 var1)
1929 {
1930 Word16 var_out;
1931
1932 if (var1 == 0)
1933 {
1934 var_out = 0;
1935 }
1936 else
1937 {
1938 if (var1 == (Word16) 0xffff)
1939 {
1940 var_out = 15;
1941 }
1942 else
1943 {
1944 if (var1 < 0)
1945 {
1946 var1 = ~var1;
1947 }
1948 for (var_out = 0; var1 < 0x4000; var_out++)
1949 {
1950 var1 <<= 1;
1951 }
1952 }
1953 }
1954
1955 #if (WMOPS)
1956 counter.norm_s++;
1957 #endif
1958 return (var_out);
1959 }
1960
1961 /*___________________________________________________________________________
1962 | |
1963 | Function Name : div_s |
1964 | |
1965 | Purpose : |
1966 | |
1967 | Produces a result which is the fractional integer division of var1 by |
1968 | var2; var1 and var2 must be positive and var2 must be greater or equal |
1969 | to var1; the result is positive (leading bit equal to 0) and truncated |
1970 | to 16 bits. |
1971 | If var1 = var2 then div(var1,var2) = 32767. |
1972 | |
1973 | Complexity weight : 18 |
1974 | |
1975 | Inputs : |
1976 | |
1977 | var1 |
1978 | 16 bit short signed integer (Word16) whose value falls in the |
1979 | range : 0x0000 0000 <= var1 <= var2 and var2 != 0. |
1980 | |
1981 | var2 |
1982 | 16 bit short signed integer (Word16) whose value falls in the |
1983 | range : var1 <= var2 <= 0x0000 7fff and var2 != 0. |
1984 | |
1985 | Outputs : |
1986 | |
1987 | none |
1988 | |
1989 | Return Value : |
1990 | |
1991 | var_out |
1992 | 16 bit short signed integer (Word16) whose value falls in the |
1993 | range : 0x0000 0000 <= var_out <= 0x0000 7fff. |
1994 | It's a Q15 value (point between b15 and b14). |
1995 |___________________________________________________________________________|
1996 */
1997
1998 Word16 div_s (Word16 var1, Word16 var2)
1999 {
2000 Word16 var_out = 0;
2001 Word16 iteration;
2002 Word32 L_num;
2003 Word32 L_denom;
2004
2005 if ((var1 > var2) || (var1 < 0) || (var2 < 0))
2006 {
2007 printf ("Division Error var1=%d var2=%d\n", var1, var2);
2008 exit (0);
2009 }
2010 if (var2 == 0)
2011 {
2012 printf ("Division by 0, Fatal error \n");
2013 exit (0);
2014 }
2015 if (var1 == 0)
2016 {
2017 var_out = 0;
2018 }
2019 else
2020 {
2021 if (var1 == var2)
2022 {
2023 var_out = MAX_16;
2024 }
2025 else
2026 {
2027 L_num = L_deposit_l (var1);
2028 #if (WMOPS)
2029 counter.L_deposit_l--;
2030 #endif
2031 L_denom = L_deposit_l (var2);
2032 #if (WMOPS)
2033 counter.L_deposit_l--;
2034 #endif
2035
2036 for (iteration = 0; iteration < 15; iteration++)
2037 {
2038 var_out <<= 1;
2039 L_num <<= 1;
2040
2041 if (L_num >= L_denom)
2042 {
2043 L_num = L_sub (L_num, L_denom);
2044 #if (WMOPS)
2045 counter.L_sub--;
2046 #endif
2047 var_out = add (var_out, 1);
2048 #if (WMOPS)
2049 counter.add--;
2050 #endif
2051 }
2052 }
2053 }
2054 }
2055
2056 #if (WMOPS)
2057 counter.div_s++;
2058 #endif
2059 return (var_out);
2060 }
2061
2062 /*___________________________________________________________________________
2063 | |
2064 | Function Name : norm_l |
2065 | |
2066 | Purpose : |
2067 | |
2068 | Produces the number of left shifts needed to normalize the 32 bit varia-|
2069 | ble L_var1 for positive values on the interval with minimum of |
2070 | 1073741824 and maximum of 2147483647, and for negative values on the in-|
2071 | terval with minimum of -2147483648 and maximum of -1073741824; in order |
2072 | to normalize the result, the following operation must be done : |
2073 | norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). |
2074 | |
2075 | Complexity weight : 30 |
2076 | |
2077 | Inputs : |
2078 | |
2079 | L_var1 |
2080 | 32 bit long signed integer (Word32) whose value falls in the |
2081 | range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
2082 | |
2083 | Outputs : |
2084 | |
2085 | none |
2086 | |
2087 | Return Value : |
2088 | |
2089 | var_out |
2090 | 16 bit short signed integer (Word16) whose value falls in the |
2091 | range : 0x0000 0000 <= var_out <= 0x0000 001f. |
2092 |___________________________________________________________________________|
2093 */
2094
2095 Word16 norm_l (Word32 L_var1)
2096 {
2097 Word16 var_out;
2098
2099 if (L_var1 == 0)
2100 {
2101 var_out = 0;
2102 }
2103 else
2104 {
2105 if (L_var1 == (Word32) 0xffffffffL)
2106 {
2107 var_out = 31;
2108 }
2109 else
2110 {
2111 if (L_var1 < 0)
2112 {
2113 L_var1 = ~L_var1;
2114 }
2115 for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
2116 {
2117 L_var1 <<= 1;
2118 }
2119 }
2120 }
2121
2122 #if (WMOPS)
2123 counter.norm_l++;
2124 #endif
2125 return (var_out);
2126 }