comparison mathhalf.c @ 0:9008dbc8ca74

import original C code from GSM 06.06
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 14 Jun 2024 23:27:16 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:9008dbc8ca74
1 /***************************************************************************
2 *
3 * File Name: mathhalf.c
4 *
5 * Purpose: Contains functions which implement the primitive
6 * arithmetic operations.
7 *
8 * The functions in this file are listed below. Some of them are
9 * defined in terms of other basic operations. One of the
10 * routines, saturate() is static. This is not a basic
11 * operation, and is not referenced outside the scope of this
12 * file.
13 *
14 *
15 * abs_s()
16 * add()
17 * divide_s()
18 * extract_h()
19 * extract_l()
20 * L_abs()
21 * L_add()
22 * L_deposit_h()
23 * L_deposit_l()
24 * L_mac()
25 * L_msu()
26 * L_mult()
27 * L_negate()
28 * L_shift_r()
29 * L_shl()
30 * L_shr()
31 * L_sub()
32 * mac_r()
33 * msu_r()
34 * mult()
35 * mult_r()
36 * negate()
37 * norm_l()
38 * norm_s()
39 * round()
40 * saturate()
41 * shift_r()
42 * shl()
43 * shr()
44 * sub()
45 *
46 **************************************************************************/
47
48 /*_________________________________________________________________________
49 | |
50 | Include Files |
51 |_________________________________________________________________________|
52 */
53
54 #include "typedefs.h"
55 #include "mathhalf.h"
56
57 /***************************************************************************
58 *
59 * FUNCTION NAME: saturate
60 *
61 * PURPOSE:
62 *
63 * Limit the 32 bit input to the range of a 16 bit word.
64 *
65 *
66 * INPUTS:
67 *
68 * L_var1
69 * 32 bit long signed integer (Longword) whose value
70 * falls in the range
71 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
72 *
73 * OUTPUTS:
74 *
75 * none
76 *
77 * RETURN VALUE:
78 *
79 * swOut
80 * 16 bit short signed integer (Shortword) whose value
81 * falls in the range
82 * 0xffff 8000 <= swOut <= 0x0000 7fff.
83 *
84 * KEYWORDS: saturation, limiting, limit, saturate, 16 bits
85 *
86 *************************************************************************/
87
88 static Shortword saturate(Longword L_var1)
89 {
90 Shortword swOut;
91
92 if (L_var1 > SW_MAX)
93 {
94 swOut = SW_MAX;
95 }
96 else if (L_var1 < SW_MIN)
97 {
98 swOut = SW_MIN;
99 }
100 else
101 swOut = (Shortword) L_var1; /* automatic type conversion */
102 return (swOut);
103 }
104
105 /***************************************************************************
106 *
107 * FUNCTION NAME: abs_s
108 *
109 * PURPOSE:
110 *
111 * Take the absolute value of the 16 bit input. An input of
112 * -0x8000 results in a return value of 0x7fff.
113 *
114 * INPUTS:
115 *
116 * var1
117 * 16 bit short signed integer (Shortword) whose value
118 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
119 *
120 * OUTPUTS:
121 *
122 * none
123 *
124 * RETURN VALUE:
125 *
126 * swOut
127 * 16 bit short signed integer (Shortword) whose value
128 * falls in the range
129 * 0x0000 0000 <= swOut <= 0x0000 7fff.
130 *
131 * IMPLEMENTATION:
132 *
133 * Take the absolute value of the 16 bit input. An input of
134 * -0x8000 results in a return value of 0x7fff.
135 *
136 * KEYWORDS: absolute value, abs
137 *
138 *************************************************************************/
139
140 Shortword abs_s(Shortword var1)
141 {
142 Shortword swOut;
143
144 if (var1 == SW_MIN)
145 {
146 swOut = SW_MAX;
147 }
148 else
149 {
150 if (var1 < 0)
151 swOut = -var1;
152 else
153 swOut = var1;
154 }
155 return (swOut);
156 }
157
158 /***************************************************************************
159 *
160 * FUNCTION NAME: add
161 *
162 * PURPOSE:
163 *
164 * Perform the addition of the two 16 bit input variable with
165 * saturation.
166 *
167 * INPUTS:
168 *
169 * var1
170 * 16 bit short signed integer (Shortword) whose value
171 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
172 * var2
173 * 16 bit short signed integer (Shortword) whose value
174 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
175 *
176 * OUTPUTS:
177 *
178 * none
179 *
180 * RETURN VALUE:
181 *
182 * swOut
183 * 16 bit short signed integer (Shortword) whose value
184 * falls in the range
185 * 0xffff 8000 <= swOut <= 0x0000 7fff.
186 *
187 * IMPLEMENTATION:
188 *
189 * Perform the addition of the two 16 bit input variable with
190 * saturation.
191 *
192 * swOut = var1 + var2
193 *
194 * swOut is set to 0x7fff if the operation results in an
195 * overflow. swOut is set to 0x8000 if the operation results
196 * in an underflow.
197 *
198 * KEYWORDS: add, addition
199 *
200 *************************************************************************/
201
202 Shortword add(Shortword var1, Shortword var2)
203 {
204 Longword L_sum;
205 Shortword swOut;
206
207 L_sum = (Longword) var1 + var2;
208 swOut = saturate(L_sum);
209 return (swOut);
210 }
211
212 /***************************************************************************
213 *
214 * FUNCTION NAME: divide_s
215 *
216 * PURPOSE:
217 *
218 * Divide var1 by var2. Note that both must be positive, and
219 * var1 >= var2. The output is set to 0 if invalid input is
220 * provided.
221 *
222 * INPUTS:
223 *
224 * var1
225 * 16 bit short signed integer (Shortword) whose value
226 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
227 * var2
228 * 16 bit short signed integer (Shortword) whose value
229 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
230 *
231 * OUTPUTS:
232 *
233 * none
234 *
235 * RETURN VALUE:
236 *
237 * swOut
238 * 16 bit short signed integer (Shortword) whose value
239 * falls in the range
240 * 0xffff 8000 <= swOut <= 0x0000 7fff.
241 *
242 * IMPLEMENTATION:
243 *
244 * In the case where var1==var2 the function returns 0x7fff. The output
245 * is undefined for invalid inputs. This implementation returns zero
246 * and issues a warning via stdio if invalid input is presented.
247 *
248 * KEYWORDS: divide
249 *
250 *************************************************************************/
251
252 Shortword divide_s(Shortword var1, Shortword var2)
253 {
254 Longword L_div;
255 Shortword swOut;
256
257 if (var1 < 0 || var2 < 0 || var1 > var2)
258 {
259 /* undefined output for invalid input into divide_s */
260 return (0);
261 }
262
263 if (var1 == var2)
264 return (0x7fff);
265
266 L_div = ((0x00008000L * (Longword) var1) / (Longword) var2);
267 swOut = saturate(L_div);
268 return (swOut);
269 }
270
271 /***************************************************************************
272 *
273 * FUNCTION NAME: extract_h
274 *
275 * PURPOSE:
276 *
277 * Extract the 16 MS bits of a 32 bit Longword. Return the 16 bit
278 * number as a Shortword. This is used as a "truncation" of a fractional
279 * number.
280 *
281 * INPUTS:
282 *
283 * L_var1
284 * 32 bit long signed integer (Longword) whose value
285 * falls in the range
286 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
287 *
288 * OUTPUTS:
289 *
290 * none
291 *
292 * RETURN VALUE:
293 *
294 * swOut
295 * 16 bit short signed integer (Shortword) whose value
296 * falls in the range
297 * 0xffff 8000 <= swOut <= 0x0000 7fff.
298 *
299 * IMPLEMENTATION:
300 *
301 * KEYWORDS: assign, truncate
302 *
303 *************************************************************************/
304
305 Shortword extract_h(Longword L_var1)
306 {
307 Shortword var2;
308
309 var2 = (Shortword) (0x0000ffffL & (L_var1 >> 16));
310 return (var2);
311 }
312
313 /***************************************************************************
314 *
315 * FUNCTION NAME: extract_l
316 *
317 * PURPOSE:
318 *
319 * Extract the 16 LS bits of a 32 bit Longword. Return the 16 bit
320 * number as a Shortword. The upper portion of the input Longword
321 * has no impact whatsoever on the output.
322 *
323 * INPUTS:
324 *
325 * L_var1
326 * 32 bit long signed integer (Longword) whose value
327 * falls in the range
328 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
329 *
330 * OUTPUTS:
331 *
332 * none
333 *
334 * RETURN VALUE:
335 *
336 * swOut
337 * 16 bit short signed integer (Shortword) whose value
338 * falls in the range
339 * 0xffff 8000 <= swOut <= 0x0000 7fff.
340 *
341 *
342 * KEYWORDS: extract, assign
343 *
344 *************************************************************************/
345
346 Shortword extract_l(Longword L_var1)
347 {
348 Shortword var2;
349
350 var2 = (Shortword) (0x0000ffffL & L_var1);
351 return (var2);
352 }
353
354 /***************************************************************************
355 *
356 * FUNCTION NAME: L_abs
357 *
358 * PURPOSE:
359 *
360 * Take the absolute value of the 32 bit input. An input of
361 * -0x8000 0000 results in a return value of 0x7fff ffff.
362 *
363 * INPUTS:
364 *
365 * L_var1
366 * 32 bit long signed integer (Longword) whose value
367 * falls in the range
368 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
369 *
370 * OUTPUTS:
371 *
372 * none
373 *
374 * RETURN VALUE:
375 *
376 * L_Out
377 * 32 bit long signed integer (Longword) whose value
378 * falls in the range
379 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
380 *
381 *
382 *
383 * KEYWORDS: absolute value, abs
384 *
385 *************************************************************************/
386 Longword L_abs(Longword L_var1)
387 {
388 Longword L_Out;
389
390 if (L_var1 == LW_MIN)
391 {
392 L_Out = LW_MAX;
393 }
394 else
395 {
396 if (L_var1 < 0)
397 L_Out = -L_var1;
398 else
399 L_Out = L_var1;
400 }
401 return (L_Out);
402 }
403
404 /***************************************************************************
405 *
406 * FUNCTION NAME: L_add
407 *
408 * PURPOSE:
409 *
410 * Perform the addition of the two 32 bit input variables with
411 * saturation.
412 *
413 * INPUTS:
414 *
415 * L_var1
416 * 32 bit long signed integer (Longword) whose value
417 * falls in the range
418 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
419 * L_var2
420 * 32 bit long signed integer (Longword) whose value
421 * falls in the range
422 * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
423 *
424 * OUTPUTS:
425 *
426 * none
427 *
428 * RETURN VALUE:
429 *
430 * L_Out
431 * 32 bit long signed integer (Longword) whose value
432 * falls in the range
433 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
434 *
435 * IMPLEMENTATION:
436 *
437 * Perform the addition of the two 32 bit input variables with
438 * saturation.
439 *
440 * L_Out = L_var1 + L_var2
441 *
442 * L_Out is set to 0x7fff ffff if the operation results in an
443 * overflow. L_Out is set to 0x8000 0000 if the operation
444 * results in an underflow.
445 *
446 * KEYWORDS: add, addition
447 *
448 *************************************************************************/
449 Longword L_add(Longword L_var1, Longword L_var2)
450 {
451
452 Longword L_Sum,
453 L_SumLow,
454 L_SumHigh;
455
456 L_Sum = L_var1 + L_var2;
457
458 if ((L_var1 > 0 && L_var2 > 0) || (L_var1 < 0 && L_var2 < 0))
459 {
460
461 /* an overflow is possible */
462
463 L_SumLow = (L_var1 & 0xffff) + (L_var2 & 0xffff);
464 L_SumHigh = ((L_var1 >> 16) & 0xffff) + ((L_var2 >> 16) & 0xffff);
465 if (L_SumLow & 0x10000)
466 {
467 /* carry into high word is set */
468 L_SumHigh += 1;
469 }
470
471 /* update sum only if there is an overflow or underflow */
472 /*------------------------------------------------------*/
473
474 if ((0x10000 & L_SumHigh) && !(0x8000 & L_SumHigh))
475 L_Sum = LW_MIN; /* underflow */
476 else if (!(0x10000 & L_SumHigh) && (0x8000 & L_SumHigh))
477 L_Sum = LW_MAX; /* overflow */
478 }
479
480 return (L_Sum);
481
482 }
483
484 /***************************************************************************
485 *
486 * FUNCTION NAME: L_deposit_h
487 *
488 * PURPOSE:
489 *
490 * Put the 16 bit input into the 16 MSB's of the output Longword. The
491 * LS 16 bits are zeroed.
492 *
493 * INPUTS:
494 *
495 * var1
496 * 16 bit short signed integer (Shortword) whose value
497 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
498 *
499 * OUTPUTS:
500 *
501 * none
502 *
503 * RETURN VALUE:
504 *
505 * L_Out
506 * 32 bit long signed integer (Longword) whose value
507 * falls in the range
508 * 0x8000 0000 <= L_var1 <= 0x7fff 0000.
509 *
510 *
511 * KEYWORDS: deposit, assign, fractional assign
512 *
513 *************************************************************************/
514
515 Longword L_deposit_h(Shortword var1)
516 {
517 Longword L_var2;
518
519 L_var2 = (Longword) var1 << 16;
520 return (L_var2);
521 }
522
523 /***************************************************************************
524 *
525 * FUNCTION NAME: L_deposit_l
526 *
527 * PURPOSE:
528 *
529 * Put the 16 bit input into the 16 LSB's of the output Longword with
530 * sign extension i.e. the top 16 bits are set to either 0 or 0xffff.
531 *
532 * INPUTS:
533 *
534 * var1
535 * 16 bit short signed integer (Shortword) whose value
536 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
537 *
538 * OUTPUTS:
539 *
540 * none
541 *
542 * RETURN VALUE:
543 *
544 * L_Out
545 * 32 bit long signed integer (Longword) whose value
546 * falls in the range
547 * 0xffff 8000 <= L_var1 <= 0x0000 7fff.
548 *
549 * KEYWORDS: deposit, assign
550 *
551 *************************************************************************/
552
553 Longword L_deposit_l(Shortword var1)
554 {
555 Longword L_Out;
556
557 L_Out = var1;
558 return (L_Out);
559 }
560
561 /***************************************************************************
562 *
563 * FUNCTION NAME: L_mac
564 *
565 * PURPOSE:
566 *
567 * Multiply accumulate. Fractionally multiply two 16 bit
568 * numbers together with saturation. Add that result to the
569 * 32 bit input with saturation. Return the 32 bit result.
570 *
571 * INPUTS:
572 *
573 * var1
574 * 16 bit short signed integer (Shortword) whose value
575 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
576 * var2
577 * 16 bit short signed integer (Shortword) whose value
578 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
579 * L_var3
580 * 32 bit long signed integer (Longword) whose value
581 * falls in the range
582 * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
583 *
584 * OUTPUTS:
585 *
586 * none
587 *
588 * RETURN VALUE:
589 *
590 * L_Out
591 * 32 bit long signed integer (Longword) whose value
592 * falls in the range
593 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
594 *
595 * IMPLEMENTATION:
596 *
597 * Fractionally multiply two 16 bit numbers together with
598 * saturation. The only numbers which will cause saturation on
599 * the multiply are 0x8000 * 0x8000.
600 *
601 * Add that result to the 32 bit input with saturation.
602 * Return the 32 bit result.
603 *
604 * Please note that this is not a true multiply accumulate as
605 * most processors would implement it. The 0x8000*0x8000
606 * causes and overflow for this instruction. On most
607 * processors this would cause an overflow only if the 32 bit
608 * input added to it were positive or zero.
609 *
610 * KEYWORDS: mac, multiply accumulate
611 *
612 *************************************************************************/
613
614 Longword L_mac(Longword L_var3, Shortword var1, Shortword var2)
615 {
616 return (L_add(L_var3, L_mult(var1, var2)));
617 }
618
619 /***************************************************************************
620 *
621 * FUNCTION NAME: L_msu
622 *
623 * PURPOSE:
624 *
625 * Multiply and subtract. Fractionally multiply two 16 bit
626 * numbers together with saturation. Subtract that result from
627 * the 32 bit input with saturation. Return the 32 bit result.
628 *
629 * INPUTS:
630 *
631 * var1
632 * 16 bit short signed integer (Shortword) whose value
633 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
634 * var2
635 * 16 bit short signed integer (Shortword) whose value
636 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
637 * L_var3
638 * 32 bit long signed integer (Longword) whose value
639 * falls in the range
640 * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
641 *
642 * OUTPUTS:
643 *
644 * none
645 *
646 * RETURN VALUE:
647 *
648 * L_Out
649 * 32 bit long signed integer (Longword) whose value
650 * falls in the range
651 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
652 *
653 * IMPLEMENTATION:
654 *
655 * Fractionally multiply two 16 bit numbers together with
656 * saturation. The only numbers which will cause saturation on
657 * the multiply are 0x8000 * 0x8000.
658 *
659 * Subtract that result from the 32 bit input with saturation.
660 * Return the 32 bit result.
661 *
662 * Please note that this is not a true multiply accumulate as
663 * most processors would implement it. The 0x8000*0x8000
664 * causes and overflow for this instruction. On most
665 * processors this would cause an overflow only if the 32 bit
666 * input added to it were negative or zero.
667 *
668 * KEYWORDS: mac, multiply accumulate, msu
669 *
670 *************************************************************************/
671
672 Longword L_msu(Longword L_var3, Shortword var1, Shortword var2)
673 {
674 return (L_sub(L_var3, L_mult(var1, var2)));
675 }
676
677 /***************************************************************************
678 *
679 * FUNCTION NAME: L_mult
680 *
681 * PURPOSE:
682 *
683 * Perform a fractional multipy of the two 16 bit input numbers
684 * with saturation. Output a 32 bit number.
685 *
686 * INPUTS:
687 *
688 * var1
689 * 16 bit short signed integer (Shortword) whose value
690 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
691 * var2
692 * 16 bit short signed integer (Shortword) whose value
693 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
694 *
695 * OUTPUTS:
696 *
697 * none
698 *
699 * RETURN VALUE:
700 *
701 * L_Out
702 * 32 bit long signed integer (Longword) whose value
703 * falls in the range
704 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
705 *
706 * IMPLEMENTATION:
707 *
708 * Multiply the two the two 16 bit input numbers. If the
709 * result is within this range, left shift the result by one
710 * and output the 32 bit number. The only possible overflow
711 * occurs when var1==var2==-0x8000. In this case output
712 * 0x7fff ffff.
713 *
714 * KEYWORDS: multiply, mult, mpy
715 *
716 *************************************************************************/
717
718 Longword L_mult(Shortword var1, Shortword var2)
719 {
720 Longword L_product;
721
722 if (var1 == SW_MIN && var2 == SW_MIN)
723 L_product = LW_MAX; /* overflow */
724 else
725 {
726 L_product = (Longword) var1 *var2; /* integer multiply */
727
728 L_product = L_product << 1;
729 }
730 return (L_product);
731 }
732
733 /***************************************************************************
734 *
735 * FUNCTION NAME: L_negate
736 *
737 * PURPOSE:
738 *
739 * Negate the 32 bit input. 0x8000 0000's negated value is
740 * 0x7fff ffff.
741 *
742 * INPUTS:
743 *
744 * L_var1
745 * 32 bit long signed integer (Longword) whose value
746 * falls in the range
747 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
748 *
749 * OUTPUTS:
750 *
751 * none
752 *
753 * RETURN VALUE:
754 *
755 * L_Out
756 * 32 bit long signed integer (Longword) whose value
757 * falls in the range
758 * 0x8000 0001 <= L_var1 <= 0x7fff ffff.
759 *
760 * KEYWORDS: negate, negative
761 *
762 *************************************************************************/
763
764 Longword L_negate(Longword L_var1)
765 {
766 Longword L_Out;
767
768 if (L_var1 == LW_MIN)
769 L_Out = LW_MAX;
770 else
771 L_Out = -L_var1;
772 return (L_Out);
773 }
774
775 /***************************************************************************
776 *
777 * FUNCTION NAME: L_shift_r
778 *
779 * PURPOSE:
780 *
781 * Shift and round. Perform a shift right. After shifting, use
782 * the last bit shifted out of the LSB to round the result up
783 * or down.
784 *
785 * INPUTS:
786 *
787 * L_var1
788 * 32 bit long signed integer (Longword) whose value
789 * falls in the range
790 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
791 * var2
792 * 16 bit short signed integer (Shortword) whose value
793 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
794 *
795 * OUTPUTS:
796 *
797 * none
798 *
799 * RETURN VALUE:
800 *
801 * L_var1
802 * 32 bit long signed integer (Longword) whose value
803 * falls in the range
804 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
805 *
806 *
807 * IMPLEMENTATION:
808 *
809 * Shift and round. Perform a shift right. After shifting, use
810 * the last bit shifted out of the LSB to round the result up
811 * or down. This is just like shift_r above except that the
812 * input/output is 32 bits as opposed to 16.
813 *
814 * if var2 is positve perform a arithmetic left shift
815 * with saturation (see L_shl() above).
816 *
817 * If var2 is zero simply return L_var1.
818 *
819 * If var2 is negative perform a arithmetic right shift (L_shr)
820 * of L_var1 by (-var2)+1. Add the LS bit of the result to
821 * L_var1 shifted right (L_shr) by -var2.
822 *
823 * Note that there is no constraint on var2, so if var2 is
824 * -0xffff 8000 then -var2 is 0x0000 8000, not 0x0000 7fff.
825 * This is the reason the L_shl function is used.
826 *
827 *
828 * KEYWORDS:
829 *
830 *************************************************************************/
831
832 Longword L_shift_r(Longword L_var1, Shortword var2)
833 {
834 Longword L_Out,
835 L_rnd;
836
837 if (var2 < -31)
838 {
839 L_Out = 0;
840 }
841 else if (var2 < 0)
842 {
843 /* right shift */
844 L_rnd = L_shl(L_var1, var2 + 1) & 0x1;
845 L_Out = L_add(L_shl(L_var1, var2), L_rnd);
846 }
847 else
848 L_Out = L_shl(L_var1, var2);
849
850 return (L_Out);
851 }
852
853 /***************************************************************************
854 *
855 * FUNCTION NAME: L_shl
856 *
857 * PURPOSE:
858 *
859 * Arithmetic shift left (or right).
860 * Arithmetically shift the input left by var2. If var2 is
861 * negative then an arithmetic shift right (L_shr) of L_var1 by
862 * -var2 is performed.
863 *
864 * INPUTS:
865 *
866 * var2
867 * 16 bit short signed integer (Shortword) whose value
868 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
869 * L_var1
870 * 32 bit long signed integer (Longword) whose value
871 * falls in the range
872 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
873 * OUTPUTS:
874 *
875 * none
876 *
877 * RETURN VALUE:
878 *
879 * L_Out
880 * 32 bit long signed integer (Longword) whose value
881 * falls in the range
882 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
883 *
884 *
885 * IMPLEMENTATION:
886 *
887 * Arithmetically shift the 32 bit input left by var2. This
888 * operation maintains the sign of the input number. If var2 is
889 * negative then an arithmetic shift right (L_shr) of L_var1 by
890 * -var2 is performed. See description of L_shr for details.
891 *
892 * Equivalent to the Full-Rate GSM ">> n" operation. Note that
893 * ANSI-C does not guarantee operation of the C ">>" or "<<"
894 * operator for negative numbers.
895 *
896 * KEYWORDS: shift, arithmetic shift left,
897 *
898 *************************************************************************/
899
900 Longword L_shl(Longword L_var1, Shortword var2)
901 {
902
903 Longword L_Mask,
904 L_Out;
905 int i,
906 iOverflow = 0;
907
908 if (var2 == 0 || L_var1 == 0)
909 {
910 L_Out = L_var1;
911 }
912 else if (var2 < 0)
913 {
914 if (var2 <= -31)
915 {
916 if (L_var1 > 0)
917 L_Out = 0;
918 else
919 L_Out = 0xffffffffL;
920 }
921 else
922 L_Out = L_shr(L_var1, -var2);
923 }
924 else
925 {
926
927 if (var2 >= 31)
928 iOverflow = 1;
929
930 else
931 {
932
933 if (L_var1 < 0)
934 L_Mask = LW_SIGN; /* sign bit mask */
935 else
936 L_Mask = 0x0;
937 L_Out = L_var1;
938 for (i = 0; i < var2 && !iOverflow; i++)
939 {
940 /* check the sign bit */
941 L_Out = (L_Out & 0x7fffffffL) << 1;
942 if ((L_Mask ^ L_Out) & LW_SIGN)
943 iOverflow = 1;
944 }
945 }
946
947 if (iOverflow)
948 {
949 /* saturate */
950 if (L_var1 > 0)
951 L_Out = LW_MAX;
952 else
953 L_Out = LW_MIN;
954 }
955 }
956
957 return (L_Out);
958 }
959
960 /***************************************************************************
961 *
962 * FUNCTION NAME: L_shr
963 *
964 * PURPOSE:
965 *
966 * Arithmetic shift right (or left).
967 * Arithmetically shift the input right by var2. If var2 is
968 * negative then an arithmetic shift left (shl) of var1 by
969 * -var2 is performed.
970 *
971 * INPUTS:
972 *
973 * var2
974 * 16 bit short signed integer (Shortword) whose value
975 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
976 * L_var1
977 * 32 bit long signed integer (Longword) whose value
978 * falls in the range
979 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
980 * OUTPUTS:
981 *
982 * none
983 *
984 * RETURN VALUE:
985 *
986 * L_Out
987 * 32 bit long signed integer (Longword) whose value
988 * falls in the range
989 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
990 *
991 *
992 * IMPLEMENTATION:
993 *
994 * Arithmetically shift the input right by var2. This
995 * operation maintains the sign of the input number. If var2 is
996 * negative then an arithmetic shift left (shl) of L_var1 by
997 * -var2 is performed. See description of L_shl for details.
998 *
999 * The input is a 32 bit number, as is the output.
1000 *
1001 * Equivalent to the Full-Rate GSM ">> n" operation. Note that
1002 * ANSI-C does not guarantee operation of the C ">>" or "<<"
1003 * operator for negative numbers.
1004 *
1005 * KEYWORDS: shift, arithmetic shift right,
1006 *
1007 *************************************************************************/
1008
1009 Longword L_shr(Longword L_var1, Shortword var2)
1010 {
1011
1012 Longword L_Mask,
1013 L_Out;
1014
1015 if (var2 == 0 || L_var1 == 0)
1016 {
1017 L_Out = L_var1;
1018 }
1019 else if (var2 < 0)
1020 {
1021 /* perform a left shift */
1022 /*----------------------*/
1023 if (var2 <= -31)
1024 {
1025 /* saturate */
1026 if (L_var1 > 0)
1027 L_Out = LW_MAX;
1028 else
1029 L_Out = LW_MIN;
1030 }
1031 else
1032 L_Out = L_shl(L_var1, -var2);
1033 }
1034 else
1035 {
1036
1037 if (var2 >= 31)
1038 {
1039 if (L_var1 > 0)
1040 L_Out = 0;
1041 else
1042 L_Out = 0xffffffffL;
1043 }
1044 else
1045 {
1046 L_Mask = 0;
1047
1048 if (L_var1 < 0)
1049 {
1050 L_Mask = ~L_Mask << (32 - var2);
1051 }
1052
1053 L_var1 >>= var2;
1054 L_Out = L_Mask | L_var1;
1055 }
1056 }
1057 return (L_Out);
1058 }
1059
1060 /***************************************************************************
1061 *
1062 * FUNCTION NAME: L_sub
1063 *
1064 * PURPOSE:
1065 *
1066 * Perform the subtraction of the two 32 bit input variables with
1067 * saturation.
1068 *
1069 * INPUTS:
1070 *
1071 * L_var1
1072 * 32 bit long signed integer (Longword) whose value
1073 * falls in the range
1074 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
1075 * L_var2
1076 * 32 bit long signed integer (Longword) whose value
1077 * falls in the range
1078 * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
1079 *
1080 * OUTPUTS:
1081 *
1082 * none
1083 *
1084 * RETURN VALUE:
1085 *
1086 * L_Out
1087 * 32 bit long signed integer (Longword) whose value
1088 * falls in the range
1089 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
1090 *
1091 * IMPLEMENTATION:
1092 *
1093 * Perform the subtraction of the two 32 bit input variables with
1094 * saturation.
1095 *
1096 * L_Out = L_var1 - L_var2
1097 *
1098 * L_Out is set to 0x7fff ffff if the operation results in an
1099 * overflow. L_Out is set to 0x8000 0000 if the operation
1100 * results in an underflow.
1101 *
1102 * KEYWORDS: sub, subtraction
1103 *
1104 *************************************************************************/
1105 Longword L_sub(Longword L_var1, Longword L_var2)
1106 {
1107 Longword L_Sum;
1108
1109 /* check for overflow */
1110 if ((L_var1 > 0 && L_var2 < 0) || (L_var1 < 0 && L_var2 > 0))
1111 {
1112 if (L_var2 == LW_MIN)
1113 {
1114 L_Sum = L_add(L_var1, LW_MAX);
1115 L_Sum = L_add(L_Sum, 1);
1116 }
1117 else
1118 L_Sum = L_add(L_var1, -L_var2);
1119 }
1120 else
1121 { /* no overflow possible */
1122 L_Sum = L_var1 - L_var2;
1123 }
1124 return (L_Sum);
1125 }
1126
1127 /***************************************************************************
1128 *
1129 * FUNCTION NAME:mac_r
1130 *
1131 * PURPOSE:
1132 *
1133 * Multiply accumulate and round. Fractionally multiply two 16
1134 * bit numbers together with saturation. Add that result to
1135 * the 32 bit input with saturation. Finally round the result
1136 * into a 16 bit number.
1137 *
1138 *
1139 * INPUTS:
1140 *
1141 * var1
1142 * 16 bit short signed integer (Shortword) whose value
1143 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1144 * var2
1145 * 16 bit short signed integer (Shortword) whose value
1146 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
1147 * L_var3
1148 * 32 bit long signed integer (Longword) whose value
1149 * falls in the range
1150 * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
1151 *
1152 * OUTPUTS:
1153 *
1154 * none
1155 *
1156 * RETURN VALUE:
1157 *
1158 * swOut
1159 * 16 bit short signed integer (Shortword) whose value
1160 * falls in the range
1161 * 0xffff 8000 <= swOut <= 0x0000 7fff.
1162 *
1163 * IMPLEMENTATION:
1164 *
1165 * Fractionally multiply two 16 bit numbers together with
1166 * saturation. The only numbers which will cause saturation on
1167 * the multiply are 0x8000 * 0x8000.
1168 *
1169 * Add that result to the 32 bit input with saturation.
1170 * Round the 32 bit result by adding 0x0000 8000 to the input.
1171 * The result may overflow due to the add. If so, the result
1172 * is saturated. The 32 bit rounded number is then shifted
1173 * down 16 bits and returned as a Shortword.
1174 *
1175 * Please note that this is not a true multiply accumulate as
1176 * most processors would implement it. The 0x8000*0x8000
1177 * causes and overflow for this instruction. On most
1178 * processors this would cause an overflow only if the 32 bit
1179 * input added to it were positive or zero.
1180 *
1181 * KEYWORDS: mac, multiply accumulate, macr
1182 *
1183 *************************************************************************/
1184
1185 Shortword mac_r(Longword L_var3, Shortword var1, Shortword var2)
1186 {
1187 return (round(L_add(L_var3, L_mult(var1, var2))));
1188 }
1189
1190 /***************************************************************************
1191 *
1192 * FUNCTION NAME: msu_r
1193 *
1194 * PURPOSE:
1195 *
1196 * Multiply subtract and round. Fractionally multiply two 16
1197 * bit numbers together with saturation. Subtract that result from
1198 * the 32 bit input with saturation. Finally round the result
1199 * into a 16 bit number.
1200 *
1201 *
1202 * INPUTS:
1203 *
1204 * var1
1205 * 16 bit short signed integer (Shortword) whose value
1206 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1207 * var2
1208 * 16 bit short signed integer (Shortword) whose value
1209 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
1210 * L_var3
1211 * 32 bit long signed integer (Longword) whose value
1212 * falls in the range
1213 * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
1214 *
1215 * OUTPUTS:
1216 *
1217 * none
1218 *
1219 * RETURN VALUE:
1220 *
1221 * swOut
1222 * 16 bit short signed integer (Shortword) whose value
1223 * falls in the range
1224 * 0xffff 8000 <= swOut <= 0x0000 7fff.
1225 *
1226 * IMPLEMENTATION:
1227 *
1228 * Fractionally multiply two 16 bit numbers together with
1229 * saturation. The only numbers which will cause saturation on
1230 * the multiply are 0x8000 * 0x8000.
1231 *
1232 * Subtract that result from the 32 bit input with saturation.
1233 * Round the 32 bit result by adding 0x0000 8000 to the input.
1234 * The result may overflow due to the add. If so, the result
1235 * is saturated. The 32 bit rounded number is then shifted
1236 * down 16 bits and returned as a Shortword.
1237 *
1238 * Please note that this is not a true multiply accumulate as
1239 * most processors would implement it. The 0x8000*0x8000
1240 * causes and overflow for this instruction. On most
1241 * processors this would cause an overflow only if the 32 bit
1242 * input added to it were positive or zero.
1243 *
1244 * KEYWORDS: mac, multiply accumulate, macr
1245 *
1246 *************************************************************************/
1247
1248 Shortword msu_r(Longword L_var3, Shortword var1, Shortword var2)
1249 {
1250 return (round(L_sub(L_var3, L_mult(var1, var2))));
1251 }
1252
1253 /***************************************************************************
1254 *
1255 * FUNCTION NAME: mult
1256 *
1257 * PURPOSE:
1258 *
1259 * Perform a fractional multipy of the two 16 bit input numbers
1260 * with saturation and truncation.
1261 *
1262 * INPUTS:
1263 *
1264 * var1
1265 * 16 bit short signed integer (Shortword) whose value
1266 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1267 * var2
1268 * 16 bit short signed integer (Shortword) whose value
1269 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
1270 *
1271 * OUTPUTS:
1272 *
1273 * none
1274 *
1275 * RETURN VALUE:
1276 *
1277 * swOut
1278 * 16 bit short signed integer (Shortword) whose value
1279 * falls in the range
1280 * 0xffff 8000 <= swOut <= 0x0000 7fff.
1281 *
1282 * IMPLEMENTATION:
1283 *
1284 * Perform a fractional multipy of the two 16 bit input
1285 * numbers. If var1 == var2 == -0x8000, output 0x7fff.
1286 * Otherwise output var1*var2 >> 15. The output is a
1287 * 16 bit number.
1288 *
1289 * KEYWORDS: mult, mulitply, mpy
1290 *
1291 *************************************************************************/
1292
1293 Shortword mult(Shortword var1, Shortword var2)
1294 {
1295 Longword L_product;
1296 Shortword swOut;
1297
1298 L_product = L_mult(var1, var2);
1299 swOut = extract_h(L_product);
1300 return (swOut);
1301 }
1302
1303 /***************************************************************************
1304 *
1305 * FUNCTION NAME: mult_r
1306 *
1307 * PURPOSE:
1308 *
1309 * Perform a fractional multipy and round of the two 16 bit
1310 * input numbers with saturation.
1311 *
1312 * INPUTS:
1313 *
1314 * var1
1315 * 16 bit short signed integer (Shortword) whose value
1316 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1317 * var2
1318 * 16 bit short signed integer (Shortword) whose value
1319 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
1320 *
1321 * OUTPUTS:
1322 *
1323 * none
1324 *
1325 * RETURN VALUE:
1326 *
1327 * swOut
1328 * 16 bit short signed integer (Shortword) whose value
1329 * falls in the range
1330 * 0xffff 8000 <= swOut <= 0x0000 7fff.
1331 *
1332 * IMPLEMENTATION:
1333 *
1334 * This routine is defined as the concatenation of the multiply
1335 * operation and the round operation.
1336 *
1337 * The fractional multiply (L_mult) produces a saturated 32 bit
1338 * output. This is followed by a an add of 0x0000 8000 to the
1339 * 32 bit result. The result may overflow due to the add. If
1340 * so, the result is saturated. The 32 bit rounded number is
1341 * then shifted down 16 bits and returned as a Shortword.
1342 *
1343 *
1344 * KEYWORDS: multiply and round, round, mult_r, mpyr
1345 *
1346 *************************************************************************/
1347
1348
1349 Shortword mult_r(Shortword var1, Shortword var2)
1350 {
1351 Shortword swOut;
1352
1353 swOut = round(L_mult(var1, var2));
1354 return (swOut);
1355 }
1356
1357 /***************************************************************************
1358 *
1359 * FUNCTION NAME: negate
1360 *
1361 * PURPOSE:
1362 *
1363 * Negate the 16 bit input. 0x8000's negated value is 0x7fff.
1364 *
1365 * INPUTS:
1366 *
1367 * var1
1368 * 16 bit short signed integer (Shortword) whose value
1369 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1370 *
1371 * OUTPUTS:
1372 *
1373 * none
1374 *
1375 * RETURN VALUE:
1376 *
1377 * swOut
1378 * 16 bit short signed integer (Shortword) whose value
1379 * falls in the range
1380 * 0xffff 8001 <= swOut <= 0x0000 7fff.
1381 *
1382 * KEYWORDS: negate, negative, invert
1383 *
1384 *************************************************************************/
1385
1386 Shortword negate(Shortword var1)
1387 {
1388 Shortword swOut;
1389
1390 if (var1 == SW_MIN)
1391 swOut = SW_MAX;
1392 else
1393 swOut = -var1;
1394 return (swOut);
1395 }
1396
1397 /***************************************************************************
1398 *
1399 * FUNCTION NAME: norm_l
1400 *
1401 * PURPOSE:
1402 *
1403 * Get normalize shift count:
1404 *
1405 * A 32 bit number is input (possiblly unnormalized). Output
1406 * the positive (or zero) shift count required to normalize the
1407 * input.
1408 *
1409 * INPUTS:
1410 *
1411 * L_var1
1412 * 32 bit long signed integer (Longword) whose value
1413 * falls in the range
1414 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
1415 *
1416 * OUTPUTS:
1417 *
1418 * none
1419 *
1420 * RETURN VALUE:
1421 *
1422 * swOut
1423 * 16 bit short signed integer (Shortword) whose value
1424 * falls in the range
1425 * 0 <= swOut <= 31
1426 *
1427 *
1428 *
1429 * IMPLEMENTATION:
1430 *
1431 * Get normalize shift count:
1432 *
1433 * A 32 bit number is input (possiblly unnormalized). Output
1434 * the positive (or zero) shift count required to normalize the
1435 * input.
1436 *
1437 * If zero in input, return 0 as the shift count.
1438 *
1439 * For non-zero numbers, count the number of left shift
1440 * required to get the number to fall into the range:
1441 *
1442 * 0x4000 0000 >= normlzd number >= 0x7fff ffff (positive number)
1443 * or
1444 * 0x8000 0000 <= normlzd number < 0xc000 0000 (negative number)
1445 *
1446 * Return the number of shifts.
1447 *
1448 * This instruction corresponds exactly to the Full-Rate "norm"
1449 * instruction.
1450 *
1451 * KEYWORDS: norm, normalization
1452 *
1453 *************************************************************************/
1454
1455 Shortword norm_l(Longword L_var1)
1456 {
1457
1458 Shortword swShiftCnt;
1459
1460 if (L_var1 != 0)
1461 {
1462 if (!(L_var1 & LW_SIGN))
1463 {
1464
1465 /* positive input */
1466 for (swShiftCnt = 0; !(L_var1 <= LW_MAX && L_var1 >= 0x40000000L);
1467 swShiftCnt++)
1468 {
1469 L_var1 = L_var1 << 1;
1470 }
1471
1472 }
1473 else
1474 {
1475 /* negative input */
1476 for (swShiftCnt = 0;
1477 !(L_var1 >= LW_MIN && L_var1 < (Longword) 0xc0000000L);
1478 swShiftCnt++)
1479 {
1480 L_var1 = L_var1 << 1;
1481 }
1482 }
1483 }
1484 else
1485 {
1486 swShiftCnt = 0;
1487 }
1488 return (swShiftCnt);
1489 }
1490
1491 /***************************************************************************
1492 *
1493 * FUNCTION NAME: norm_s
1494 *
1495 * PURPOSE:
1496 *
1497 * Get normalize shift count:
1498 *
1499 * A 16 bit number is input (possiblly unnormalized). Output
1500 * the positive (or zero) shift count required to normalize the
1501 * input.
1502 *
1503 * INPUTS:
1504 *
1505 * var1
1506 * 16 bit short signed integer (Shortword) whose value
1507 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1508 *
1509 * OUTPUTS:
1510 *
1511 * none
1512 *
1513 * RETURN VALUE:
1514 * swOut
1515 * 16 bit short signed integer (Shortword) whose value
1516 * falls in the range
1517 * 0 <= swOut <= 15
1518 *
1519 *
1520 *
1521 * IMPLEMENTATION:
1522 *
1523 * Get normalize shift count:
1524 *
1525 * A 16 bit number is input (possiblly unnormalized). Output
1526 * the positive (or zero) shift count required to normalize the
1527 * input.
1528 *
1529 * If zero in input, return 0 as the shift count.
1530 *
1531 * For non-zero numbers, count the number of left shift
1532 * required to get the number to fall into the range:
1533 *
1534 * 0x4000 >= normlzd number >= 0x7fff (positive number)
1535 * or
1536 * 0x8000 <= normlzd number < 0xc000 (negative number)
1537 *
1538 * Return the number of shifts.
1539 *
1540 * This instruction corresponds exactly to the Full-Rate "norm"
1541 * instruction.
1542 *
1543 * KEYWORDS: norm, normalization
1544 *
1545 *************************************************************************/
1546
1547 Shortword norm_s(Shortword var1)
1548 {
1549
1550 short swShiftCnt;
1551 Longword L_var1;
1552
1553 L_var1 = L_deposit_h(var1);
1554 swShiftCnt = norm_l(L_var1);
1555 return (swShiftCnt);
1556 }
1557
1558 /***************************************************************************
1559 *
1560 * FUNCTION NAME: round
1561 *
1562 * PURPOSE:
1563 *
1564 * Round the 32 bit Longword into a 16 bit shortword with saturation.
1565 *
1566 * INPUTS:
1567 *
1568 * L_var1
1569 * 32 bit long signed integer (Longword) whose value
1570 * falls in the range
1571 * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
1572 * OUTPUTS:
1573 *
1574 * none
1575 *
1576 * RETURN VALUE:
1577 *
1578 * swOut
1579 * 16 bit short signed integer (Shortword) whose value
1580 * falls in the range
1581 * 0xffff 8000 <= swOut <= 0x0000 7fff.
1582 *
1583 * IMPLEMENTATION:
1584 *
1585 * Perform a two's complement round on the input Longword with
1586 * saturation.
1587 *
1588 * This is equivalent to adding 0x0000 8000 to the input. The
1589 * result may overflow due to the add. If so, the result is
1590 * saturated. The 32 bit rounded number is then shifted down
1591 * 16 bits and returned as a Shortword.
1592 *
1593 *
1594 * KEYWORDS: round
1595 *
1596 *************************************************************************/
1597
1598 Shortword round(Longword L_var1)
1599 {
1600 Longword L_Prod;
1601
1602 L_Prod = L_add(L_var1, 0x00008000L); /* round MSP */
1603 return (extract_h(L_Prod));
1604 }
1605
1606 /***************************************************************************
1607 *
1608 * FUNCTION NAME: shift_r
1609 *
1610 * PURPOSE:
1611 *
1612 * Shift and round. Perform a shift right. After shifting, use
1613 * the last bit shifted out of the LSB to round the result up
1614 * or down.
1615 *
1616 * INPUTS:
1617 *
1618 * var1
1619 * 16 bit short signed integer (Shortword) whose value
1620 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1621 * var2
1622 * 16 bit short signed integer (Shortword) whose value
1623 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
1624 *
1625 * OUTPUTS:
1626 *
1627 * none
1628 *
1629 * RETURN VALUE:
1630 *
1631 * swOut
1632 * 16 bit short signed integer (Shortword) whose value
1633 * falls in the range
1634 * 0xffff 8000 <= swOut <= 0x0000 7fff.
1635 *
1636 *
1637 * IMPLEMENTATION:
1638 *
1639 * Shift and round. Perform a shift right. After shifting, use
1640 * the last bit shifted out of the LSB to round the result up
1641 * or down.
1642 *
1643 * If var2 is positive perform a arithmetic left shift
1644 * with saturation (see shl() above).
1645 *
1646 * If var2 is zero simply return var1.
1647 *
1648 * If var2 is negative perform a arithmetic right shift (shr)
1649 * of var1 by (-var2)+1. Add the LS bit of the result to var1
1650 * shifted right (shr) by -var2.
1651 *
1652 * Note that there is no constraint on var2, so if var2 is
1653 * -0xffff 8000 then -var2 is 0x0000 8000, not 0x0000 7fff.
1654 * This is the reason the shl function is used.
1655 *
1656 *
1657 * KEYWORDS:
1658 *
1659 *************************************************************************/
1660
1661 Shortword shift_r(Shortword var1, Shortword var2)
1662 {
1663 Shortword swOut,
1664 swRnd;
1665
1666 if (var2 >= 0)
1667 swOut = shl(var1, var2);
1668 else
1669 {
1670
1671 /* right shift */
1672
1673 if (var2 < -15)
1674 {
1675
1676 swOut = 0;
1677
1678 }
1679 else
1680 {
1681
1682 swRnd = shl(var1, var2 + 1) & 0x1;
1683 swOut = add(shl(var1, var2), swRnd);
1684
1685 }
1686 }
1687 return (swOut);
1688 }
1689
1690 /***************************************************************************
1691 *
1692 * FUNCTION NAME: shl
1693 *
1694 * PURPOSE:
1695 *
1696 * Arithmetically shift the input left by var2.
1697 *
1698 *
1699 * INPUTS:
1700 *
1701 * var1
1702 * 16 bit short signed integer (Shortword) whose value
1703 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1704 * var2
1705 * 16 bit short signed integer (Shortword) whose value
1706 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
1707 *
1708 * OUTPUTS:
1709 *
1710 * none
1711 *
1712 * RETURN VALUE:
1713 *
1714 * swOut
1715 * 16 bit short signed integer (Shortword) whose value
1716 * falls in the range
1717 * 0xffff 8000 <= swOut <= 0x0000 7fff.
1718 *
1719 * IMPLEMENTATION:
1720 *
1721 * If Arithmetically shift the input left by var2. If var2 is
1722 * negative then an arithmetic shift right (shr) of var1 by
1723 * -var2 is performed. See description of shr for details.
1724 * When an arithmetic shift left is performed the var2 LS bits
1725 * are zero filled.
1726 *
1727 * The only exception is if the left shift causes an overflow
1728 * or underflow. In this case the LS bits are not modified.
1729 * The number returned is 0x8000 in the case of an underflow or
1730 * 0x7fff in the case of an overflow.
1731 *
1732 * The shl is equivalent to the Full-Rate GSM "<< n" operation.
1733 * Note that ANSI-C does not guarantee operation of the C ">>"
1734 * or "<<" operator for negative numbers - it is not specified
1735 * whether this shift is an arithmetic or logical shift.
1736 *
1737 * KEYWORDS: asl, arithmetic shift left, shift
1738 *
1739 *************************************************************************/
1740
1741 Shortword shl(Shortword var1, Shortword var2)
1742 {
1743 Shortword swOut;
1744 Longword L_Out;
1745
1746 if (var2 == 0 || var1 == 0)
1747 {
1748 swOut = var1;
1749 }
1750 else if (var2 < 0)
1751 {
1752
1753 /* perform a right shift */
1754 /*-----------------------*/
1755
1756 if (var2 <= -15)
1757 {
1758 if (var1 < 0)
1759 swOut = (Shortword) 0xffff;
1760 else
1761 swOut = 0x0;
1762 }
1763 else
1764 swOut = shr(var1, -var2);
1765
1766 }
1767 else
1768 {
1769 /* var2 > 0 */
1770 if (var2 >= 15)
1771 {
1772 /* saturate */
1773 if (var1 > 0)
1774 swOut = SW_MAX;
1775 else
1776 swOut = SW_MIN;
1777 }
1778 else
1779 {
1780
1781 L_Out = (Longword) var1 *(1 << var2);
1782
1783 swOut = (Shortword) L_Out; /* copy low portion to swOut, overflow
1784 * could have hpnd */
1785 if (swOut != L_Out)
1786 {
1787 /* overflow */
1788 if (var1 > 0)
1789 swOut = SW_MAX; /* saturate */
1790 else
1791 swOut = SW_MIN; /* saturate */
1792 }
1793 }
1794 }
1795 return (swOut);
1796 }
1797
1798 /***************************************************************************
1799 *
1800 * FUNCTION NAME: shr
1801 *
1802 * PURPOSE:
1803 *
1804 * Arithmetic shift right (or left).
1805 * Arithmetically shift the input right by var2. If var2 is
1806 * negative then an arithmetic shift left (shl) of var1 by
1807 * -var2 is performed.
1808 *
1809 * INPUTS:
1810 *
1811 * var1
1812 * 16 bit short signed integer (Shortword) whose value
1813 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1814 * var2
1815 * 16 bit short signed integer (Shortword) whose value
1816 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
1817 *
1818 * OUTPUTS:
1819 *
1820 * none
1821 *
1822 * RETURN VALUE:
1823 *
1824 * swOut
1825 * 16 bit short signed integer (Shortword) whose value
1826 * falls in the range
1827 * 0xffff 8000 <= swOut <= 0x0000 7fff.
1828 *
1829 * IMPLEMENTATION:
1830 *
1831 * Arithmetically shift the input right by var2. This
1832 * operation maintains the sign of the input number. If var2 is
1833 * negative then an arithmetic shift left (shl) of var1 by
1834 * -var2 is performed. See description of shl for details.
1835 *
1836 * Equivalent to the Full-Rate GSM ">> n" operation. Note that
1837 * ANSI-C does not guarantee operation of the C ">>" or "<<"
1838 * operator for negative numbers.
1839 *
1840 * KEYWORDS: shift, arithmetic shift right,
1841 *
1842 *************************************************************************/
1843
1844 Shortword shr(Shortword var1, Shortword var2)
1845 {
1846
1847 Shortword swMask,
1848 swOut;
1849
1850 if (var2 == 0 || var1 == 0)
1851 swOut = var1;
1852
1853 else if (var2 < 0)
1854 {
1855 /* perform an arithmetic left shift */
1856 /*----------------------------------*/
1857 if (var2 <= -15)
1858 {
1859 /* saturate */
1860 if (var1 > 0)
1861 swOut = SW_MAX;
1862 else
1863 swOut = SW_MIN;
1864 }
1865 else
1866 swOut = shl(var1, -var2);
1867 }
1868
1869 else
1870 {
1871
1872 /* positive shift count */
1873 /*----------------------*/
1874
1875 if (var2 >= 15)
1876 {
1877 if (var1 < 0)
1878 swOut = (Shortword) 0xffff;
1879 else
1880 swOut = 0x0;
1881 }
1882 else
1883 {
1884 /* take care of sign extension */
1885 /*-----------------------------*/
1886
1887 swMask = 0;
1888 if (var1 < 0)
1889 {
1890 swMask = ~swMask << (16 - var2);
1891 }
1892
1893 var1 >>= var2;
1894 swOut = swMask | var1;
1895
1896 }
1897 }
1898 return (swOut);
1899 }
1900
1901 /***************************************************************************
1902 *
1903 * FUNCTION NAME: sub
1904 *
1905 * PURPOSE:
1906 *
1907 * Perform the subtraction of the two 16 bit input variable with
1908 * saturation.
1909 *
1910 * INPUTS:
1911 *
1912 * var1
1913 * 16 bit short signed integer (Shortword) whose value
1914 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
1915 * var2
1916 * 16 bit short signed integer (Shortword) whose value
1917 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
1918 *
1919 * OUTPUTS:
1920 *
1921 * none
1922 *
1923 * RETURN VALUE:
1924 *
1925 * swOut
1926 * 16 bit short signed integer (Shortword) whose value
1927 * falls in the range
1928 * 0xffff 8000 <= swOut <= 0x0000 7fff.
1929 *
1930 * IMPLEMENTATION:
1931 *
1932 * Perform the subtraction of the two 16 bit input variable with
1933 * saturation.
1934 *
1935 * swOut = var1 - var2
1936 *
1937 * swOut is set to 0x7fff if the operation results in an
1938 * overflow. swOut is set to 0x8000 if the operation results
1939 * in an underflow.
1940 *
1941 * KEYWORDS: sub, subtraction
1942 *
1943 *************************************************************************/
1944 Shortword sub(Shortword var1, Shortword var2)
1945 {
1946 Longword L_diff;
1947 Shortword swOut;
1948
1949 L_diff = (Longword) var1 - var2;
1950 swOut = saturate(L_diff);
1951
1952 return (swOut);
1953 }