comparison libgsmefr/basic_op.h @ 347:1c514150c033

libgsmefr: first big perf opt: inline most basic_op.h functions
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 21 Apr 2024 23:17:21 +0000
parents 38326102fc43
children ed8762eea8a1
comparison
equal deleted inserted replaced
346:9a8b5c9a3b4a 347:1c514150c033
1 /*___________________________________________________________________________ 1 /*
2 | | 2 * This version of basic_op.h for GSM-EFR codec has been created at
3 | Constants and Globals | 3 * Themyscira Wireless with the aim of performance improvement.
4 |___________________________________________________________________________| 4 * The original version contained only function declarations,
5 */ 5 * resulting in a function call for every elementary operation;
6 * the present version implements most of these operations as inline
7 * functions.
8 *
9 * Elimination of Overflow flag: examination of EFR code reveals that
10 * both Carry and Overflow flags are accessed outside of basicop2.c
11 * only in g_pitch.c, as part of a code sequence that uses L_macNs.
12 * Since the Overflow flag is not checked anywhere else, we can eliminate
13 * its setting from all other elementary operation functions, saving
14 * some cycles and code size.
15 *
16 * Non-portability: we assume real target machines, not hypothetical
17 * ones. Specifically, we assume that >> does an arithmetic right shift
18 * (sign bit fill).
19 */
20
21 /* for the few functions that still use them */
6 extern __thread Flag Overflow; 22 extern __thread Flag Overflow;
7 extern __thread Flag Carry; 23 extern __thread Flag Carry;
8 24
9 #define MAX_32 (Word32)0x7fffffffL 25 #define MAX_32 (Word32)0x7fffffff
10 #define MIN_32 (Word32)0x80000000L 26 #define MIN_32 (Word32)0x80000000
11 27
12 #define MAX_16 (Word16)0x7fff 28 #define MAX_16 (Word16)0x7fff
13 #define MIN_16 (Word16)0x8000 29 #define MIN_16 (Word16)0x8000
14 30
15 /*___________________________________________________________________________ 31 /* likely and unlikely conditional paths */
16 | | 32
17 | Prototypes for basic arithmetic operators | 33 #define likely(x) __builtin_expect(!!(x), 1)
18 |___________________________________________________________________________| 34 #define unlikely(x) __builtin_expect(!!(x), 0)
19 */ 35
20 36 /* Word16 operations */
21 Word16 add (Word16 var1, Word16 var2); /* Short add, 1 */ 37
22 Word16 sub (Word16 var1, Word16 var2); /* Short sub, 1 */ 38 /*___________________________________________________________________________
23 Word16 abs_s (Word16 var1); /* Short abs, 1 */ 39 | |
24 Word16 shl (Word16 var1, Word16 var2); /* Short shift left, 1 */ 40 | Function Name : add |
25 Word16 shr (Word16 var1, Word16 var2); /* Short shift right, 1 */ 41 | |
26 Word16 mult (Word16 var1, Word16 var2); /* Short mult, 1 */ 42 | Purpose : |
27 Word32 L_mult (Word16 var1, Word16 var2); /* Long mult, 1 */ 43 | |
28 Word16 negate (Word16 var1); /* Short negate, 1 */ 44 | Performs the addition (var1+var2) with overflow control and saturation;|
29 Word16 extract_h (Word32 L_var1); /* Extract high, 1 */ 45 | the 16 bit result is set at +32767 when overflow occurs or at -32768 |
30 Word16 extract_l (Word32 L_var1); /* Extract low, 1 */ 46 | when underflow occurs. |
31 Word16 round (Word32 L_var1); /* Round, 1 */ 47 | |
32 Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2); /* Mac, 1 */ 48 | Complexity weight : 1 |
33 Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2); /* Msu, 1 */ 49 | |
50 | Inputs : |
51 | |
52 | var1 |
53 | 16 bit short signed integer (Word16) whose value falls in the |
54 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
55 | |
56 | var2 |
57 | 16 bit short signed integer (Word16) whose value falls in the |
58 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
59 | |
60 | Outputs : |
61 | |
62 | none |
63 | |
64 | Return Value : |
65 | |
66 | var_out |
67 | 16 bit short signed integer (Word16) whose value falls in the |
68 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
69 |___________________________________________________________________________|
70 */
71
72 static inline Word16 add (Word16 var1, Word16 var2)
73 {
74 Word32 L_sum;
75
76 L_sum = (Word32) var1 + var2;
77 if (unlikely(L_sum > MAX_16))
78 return MAX_16;
79 else if (unlikely(L_sum < MIN_16))
80 return MIN_16;
81 else
82 return L_sum;
83 }
84
85 /*___________________________________________________________________________
86 | |
87 | Function Name : sub |
88 | |
89 | Purpose : |
90 | |
91 | Performs the subtraction (var1+var2) with overflow control and satu- |
92 | ration; the 16 bit result is set at +32767 when overflow occurs or at |
93 | -32768 when underflow occurs. |
94 | |
95 | Complexity weight : 1 |
96 | |
97 | Inputs : |
98 | |
99 | var1 |
100 | 16 bit short signed integer (Word16) whose value falls in the |
101 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
102 | |
103 | var2 |
104 | 16 bit short signed integer (Word16) whose value falls in the |
105 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
106 | |
107 | Outputs : |
108 | |
109 | none |
110 | |
111 | Return Value : |
112 | |
113 | var_out |
114 | 16 bit short signed integer (Word16) whose value falls in the |
115 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
116 |___________________________________________________________________________|
117 */
118
119 static inline Word16 sub (Word16 var1, Word16 var2)
120 {
121 Word32 L_diff;
122
123 L_diff = (Word32) var1 - var2;
124 if (unlikely(L_diff > MAX_16))
125 return MAX_16;
126 else if (unlikely(L_diff < MIN_16))
127 return MIN_16;
128 else
129 return L_diff;
130 }
131
132 /*___________________________________________________________________________
133 | |
134 | Function Name : abs_s |
135 | |
136 | Purpose : |
137 | |
138 | Absolute value of var1; abs_s(-32768) = 32767. |
139 | |
140 | Complexity weight : 1 |
141 | |
142 | Inputs : |
143 | |
144 | var1 |
145 | 16 bit short signed integer (Word16) whose value falls in the |
146 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
147 | |
148 | Outputs : |
149 | |
150 | none |
151 | |
152 | Return Value : |
153 | |
154 | var_out |
155 | 16 bit short signed integer (Word16) whose value falls in the |
156 | range : 0x0000 0000 <= var_out <= 0x0000 7fff. |
157 |___________________________________________________________________________|
158 */
159
160 static inline Word16 abs_s (Word16 var1)
161 {
162 Word16 var_out;
163
164 if (unlikely(var1 == (Word16) 0X8000))
165 {
166 var_out = MAX_16;
167 }
168 else
169 {
170 if (var1 < 0)
171 {
172 var_out = -var1;
173 }
174 else
175 {
176 var_out = var1;
177 }
178 }
179 return (var_out);
180 }
181
182 /*___________________________________________________________________________
183 | |
184 | Function Name : shl |
185 | |
186 | Purpose : |
187 | |
188 | Arithmetically shift the 16 bit input var1 left var2 positions.Zero fill|
189 | the var2 LSB of the result. If var2 is negative, arithmetically shift |
190 | var1 right by -var2 with sign extension. Saturate the result in case of |
191 | underflows or overflows. |
192 | |
193 | Complexity weight : 1 |
194 | |
195 | Inputs : |
196 | |
197 | var1 |
198 | 16 bit short signed integer (Word16) whose value falls in the |
199 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
200 | |
201 | var2 |
202 | 16 bit short signed integer (Word16) whose value falls in the |
203 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
204 | |
205 | Outputs : |
206 | |
207 | none |
208 | |
209 | Return Value : |
210 | |
211 | var_out |
212 | 16 bit short signed integer (Word16) whose value falls in the |
213 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
214 |___________________________________________________________________________|
215 */
216
217 static inline Word16 shl (Word16 var1, Word16 var2)
218 {
219 Word32 result;
220
221 if (var2 < 0) {
222 var2 = -var2;
223 if (unlikely(var2 >= 15))
224 return (var1 < 0) ? -1 : 0;
225 else
226 return var1 >> var2;
227 } else {
228 result = (Word32) var1 << var2;
229 if (var1 > 0) {
230 if (unlikely((var2 >= 15) || (result & 0xFFFF8000)))
231 return MAX_16;
232 else
233 return (Word16) result;
234 } else if (var1 < 0) {
235 if (unlikely((var2 >= 16) || ((result & 0xFFFF8000) != 0xFFFF8000)))
236 return MIN_16;
237 else
238 return (Word16) result;
239 } else
240 return 0;
241 }
242 }
243
244 /*___________________________________________________________________________
245 | |
246 | Function Name : shr |
247 | |
248 | Purpose : |
249 | |
250 | Arithmetically shift the 16 bit input var1 right var2 positions with |
251 | sign extension. If var2 is negative, arithmetically shift var1 left by |
252 | -var2 with sign extension. Saturate the result in case of underflows or |
253 | overflows. |
254 | |
255 | Complexity weight : 1 |
256 | |
257 | Inputs : |
258 | |
259 | var1 |
260 | 16 bit short signed integer (Word16) whose value falls in the |
261 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
262 | |
263 | var2 |
264 | 16 bit short signed integer (Word16) whose value falls in the |
265 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
266 | |
267 | Outputs : |
268 | |
269 | none |
270 | |
271 | Return Value : |
272 | |
273 | var_out |
274 | 16 bit short signed integer (Word16) whose value falls in the |
275 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
276 |___________________________________________________________________________|
277 */
278
279 static inline Word16 shr (Word16 var1, Word16 var2)
280 {
281 Word32 result;
282
283 if (var2 < 0) {
284 var2 = -var2;
285 result = (Word32) var1 << var2;
286 if (var1 > 0) {
287 if (unlikely((var2 >= 15) || (result & 0xFFFF8000)))
288 return MAX_16;
289 else
290 return (Word16) result;
291 } else if (var1 < 0) {
292 if (unlikely((var2 >= 16) || ((result & 0xFFFF8000) != 0xFFFF8000)))
293 return MIN_16;
294 else
295 return (Word16) result;
296 } else
297 return 0;
298 } else {
299 if (unlikely(var2 >= 15))
300 return (var1 < 0) ? -1 : 0;
301 else
302 return var1 >> var2;
303 }
304 }
305
306 /*___________________________________________________________________________
307 | |
308 | Function Name : mult |
309 | |
310 | Purpose : |
311 | |
312 | Performs the multiplication of var1 by var2 and gives a 16 bit result |
313 | which is scaled i.e.: |
314 | mult(var1,var2) = extract_l(L_shr((var1 times var2),15)) and |
315 | mult(-32768,-32768) = 32767. |
316 | |
317 | Complexity weight : 1 |
318 | |
319 | Inputs : |
320 | |
321 | var1 |
322 | 16 bit short signed integer (Word16) whose value falls in the |
323 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
324 | |
325 | var2 |
326 | 16 bit short signed integer (Word16) whose value falls in the |
327 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
328 | |
329 | Outputs : |
330 | |
331 | none |
332 | |
333 | Return Value : |
334 | |
335 | var_out |
336 | 16 bit short signed integer (Word16) whose value falls in the |
337 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
338 |___________________________________________________________________________|
339 */
340
341 static inline Word16 mult (Word16 var1, Word16 var2)
342 {
343 if (unlikely(var1 == MIN_16 && var2 == MIN_16))
344 return MAX_16;
345 else
346 return ((Word32) var1 * var2) >> 15;
347 }
348
349 /*___________________________________________________________________________
350 | |
351 | Function Name : negate |
352 | |
353 | Purpose : |
354 | |
355 | Negate var1 with saturation, saturate in the case where input is -32768:|
356 | negate(var1) = sub(0,var1). |
357 | |
358 | Complexity weight : 1 |
359 | |
360 | Inputs : |
361 | |
362 | var1 |
363 | 16 bit short signed integer (Word16) whose value falls in the |
364 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
365 | |
366 | Outputs : |
367 | |
368 | none |
369 | |
370 | Return Value : |
371 | |
372 | var_out |
373 | 16 bit short signed integer (Word16) whose value falls in the |
374 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
375 |___________________________________________________________________________|
376 */
377
378 static inline Word16 negate (Word16 var1)
379 {
380 Word16 var_out;
381
382 var_out = (var1 == MIN_16) ? MAX_16 : -var1;
383 return (var_out);
384 }
385
386 /*___________________________________________________________________________
387 | |
388 | Function Name : extract_h |
389 | |
390 | Purpose : |
391 | |
392 | Return the 16 MSB of L_var1. |
393 | |
394 | Complexity weight : 1 |
395 | |
396 | Inputs : |
397 | |
398 | L_var1 |
399 | 32 bit long signed integer (Word32 ) whose value falls in the |
400 | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
401 | |
402 | Outputs : |
403 | |
404 | none |
405 | |
406 | Return Value : |
407 | |
408 | var_out |
409 | 16 bit short signed integer (Word16) whose value falls in the |
410 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
411 |___________________________________________________________________________|
412 */
413
414 static inline Word16 extract_h (Word32 L_var1)
415 {
416 Word16 var_out;
417
418 var_out = (Word16) (L_var1 >> 16);
419 return (var_out);
420 }
421
422 /*___________________________________________________________________________
423 | |
424 | Function Name : extract_l |
425 | |
426 | Purpose : |
427 | |
428 | Return the 16 LSB of L_var1. |
429 | |
430 | Complexity weight : 1 |
431 | |
432 | Inputs : |
433 | |
434 | L_var1 |
435 | 32 bit long signed integer (Word32 ) whose value falls in the |
436 | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
437 | |
438 | Outputs : |
439 | |
440 | none |
441 | |
442 | Return Value : |
443 | |
444 | var_out |
445 | 16 bit short signed integer (Word16) whose value falls in the |
446 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
447 |___________________________________________________________________________|
448 */
449
450 static inline Word16 extract_l (Word32 L_var1)
451 {
452 Word16 var_out;
453
454 var_out = (Word16) L_var1;
455 return (var_out);
456 }
457
458 /*___________________________________________________________________________
459 | |
460 | Function Name : round |
461 | |
462 | Purpose : |
463 | |
464 | Round the lower 16 bits of the 32 bit input number into the MS 16 bits |
465 | with saturation. Shift the resulting bits right by 16 and return the 16 |
466 | bit number: |
467 | round(L_var1) = extract_h(L_add(L_var1,32768)) |
468 | |
469 | Complexity weight : 1 |
470 | |
471 | Inputs : |
472 | |
473 | L_var1 |
474 | 32 bit long signed integer (Word32 ) whose value falls in the |
475 | range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. |
476 | |
477 | Outputs : |
478 | |
479 | none |
480 | |
481 | Return Value : |
482 | |
483 | var_out |
484 | 16 bit short signed integer (Word16) whose value falls in the |
485 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
486 |___________________________________________________________________________|
487 */
488
489 static inline Word16 round (Word32 L_var1)
490 {
491 if (unlikely(L_var1 >= 0x7fff8000))
492 return MAX_16;
493 else
494 return (L_var1 + 0x8000) >> 16;
495 }
496
497 /* Word32 operations */
498
499 /*___________________________________________________________________________
500 | |
501 | Function Name : L_add |
502 | |
503 | Purpose : |
504 | |
505 | 32 bits addition of the two 32 bits variables (L_var1+L_var2) with |
506 | overflow control and saturation; the result is set at +2147483647 when |
507 | overflow occurs or at -2147483648 when underflow occurs. |
508 | |
509 | Complexity weight : 2 |
510 | |
511 | Inputs : |
512 | |
513 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
514 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
515 | |
516 | L_var2 32 bit long signed integer (Word32) whose value falls in the |
517 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
518 | |
519 | Outputs : |
520 | |
521 | none |
522 | |
523 | Return Value : |
524 | |
525 | L_var_out |
526 | 32 bit long signed integer (Word32) whose value falls in the |
527 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
528 |___________________________________________________________________________|
529 */
530
531 static inline Word32 L_add (Word32 L_var1, Word32 L_var2)
532 {
533 Word32 L_var_out;
534
535 L_var_out = L_var1 + L_var2;
536
537 if (((L_var1 ^ L_var2) & MIN_32) == 0)
538 {
539 if ((L_var_out ^ L_var1) & MIN_32)
540 {
541 L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
542 }
543 }
544 return (L_var_out);
545 }
546
547 /*___________________________________________________________________________
548 | |
549 | Function Name : L_sub |
550 | |
551 | Purpose : |
552 | |
553 | 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with |
554 | overflow control and saturation; the result is set at +2147483647 when |
555 | overflow occurs or at -2147483648 when underflow occurs. |
556 | |
557 | Complexity weight : 2 |
558 | |
559 | Inputs : |
560 | |
561 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
562 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
563 | |
564 | L_var2 32 bit long signed integer (Word32) whose value falls in the |
565 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
566 | |
567 | Outputs : |
568 | |
569 | none |
570 | |
571 | Return Value : |
572 | |
573 | L_var_out |
574 | 32 bit long signed integer (Word32) whose value falls in the |
575 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
576 |___________________________________________________________________________|
577 */
578
579 static inline Word32 L_sub (Word32 L_var1, Word32 L_var2)
580 {
581 Word32 L_var_out;
582
583 L_var_out = L_var1 - L_var2;
584
585 if (((L_var1 ^ L_var2) & MIN_32) != 0)
586 {
587 if ((L_var_out ^ L_var1) & MIN_32)
588 {
589 L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
590 }
591 }
592 return (L_var_out);
593 }
594
595 /*___________________________________________________________________________
596 | |
597 | Function Name : L_mult |
598 | |
599 | Purpose : |
600 | |
601 | L_mult is the 32 bit result of the multiplication of var1 times var2 |
602 | with one shift left i.e.: |
603 | L_mult(var1,var2) = L_shl((var1 times var2),1) and |
604 | L_mult(-32768,-32768) = 2147483647. |
605 | |
606 | Complexity weight : 1 |
607 | |
608 | Inputs : |
609 | |
610 | var1 |
611 | 16 bit short signed integer (Word16) whose value falls in the |
612 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
613 | |
614 | var2 |
615 | 16 bit short signed integer (Word16) whose value falls in the |
616 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
617 | |
618 | Outputs : |
619 | |
620 | none |
621 | |
622 | Return Value : |
623 | |
624 | L_var_out |
625 | 32 bit long signed integer (Word32) whose value falls in the |
626 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
627 |___________________________________________________________________________|
628 */
629
630 static inline Word32 L_mult (Word16 var1, Word16 var2)
631 {
632 if (unlikely(var1 == MIN_16 && var2 == MIN_16)) {
633 Overflow = 1;
634 return MAX_32;
635 } else
636 return ((Word32) var1 * var2) << 1;
637 }
638
639 /*___________________________________________________________________________
640 | |
641 | Function Name : L_mac |
642 | |
643 | Purpose : |
644 | |
645 | Multiply var1 by var2 and shift the result left by 1. Add the 32 bit |
646 | result to L_var3 with saturation, return a 32 bit result: |
647 | L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)). |
648 | |
649 | Complexity weight : 1 |
650 | |
651 | Inputs : |
652 | |
653 | L_var3 32 bit long signed integer (Word32) whose value falls in the |
654 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
655 | |
656 | var1 |
657 | 16 bit short signed integer (Word16) whose value falls in the |
658 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
659 | |
660 | var2 |
661 | 16 bit short signed integer (Word16) whose value falls in the |
662 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
663 | |
664 | Outputs : |
665 | |
666 | none |
667 | |
668 | Return Value : |
669 | |
670 | L_var_out |
671 | 32 bit long signed integer (Word32) whose value falls in the |
672 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
673 |___________________________________________________________________________|
674 */
675
676 static inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
677 {
678 Word32 L_var_out;
679 Word32 L_product;
680
681 L_product = L_mult (var1, var2);
682 L_var_out = L_add (L_var3, L_product);
683 return (L_var_out);
684 }
685
686 /*___________________________________________________________________________
687 | |
688 | Function Name : L_msu |
689 | |
690 | Purpose : |
691 | |
692 | Multiply var1 by var2 and shift the result left by 1. Subtract the 32 |
693 | bit result to L_var3 with saturation, return a 32 bit result: |
694 | L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)). |
695 | |
696 | Complexity weight : 1 |
697 | |
698 | Inputs : |
699 | |
700 | L_var3 32 bit long signed integer (Word32) whose value falls in the |
701 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
702 | |
703 | var1 |
704 | 16 bit short signed integer (Word16) whose value falls in the |
705 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
706 | |
707 | var2 |
708 | 16 bit short signed integer (Word16) whose value falls in the |
709 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
710 | |
711 | Outputs : |
712 | |
713 | none |
714 | |
715 | Return Value : |
716 | |
717 | L_var_out |
718 | 32 bit long signed integer (Word32) whose value falls in the |
719 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
720 |___________________________________________________________________________|
721 */
722
723 static inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
724 {
725 Word32 L_var_out;
726 Word32 L_product;
727
728 L_product = L_mult (var1, var2);
729 L_var_out = L_sub (L_var3, L_product);
730 return (L_var_out);
731 }
732
733 /*___________________________________________________________________________
734 | |
735 | Function Name : L_negate |
736 | |
737 | Purpose : |
738 | |
739 | Negate the 32 bit variable L_var1 with saturation; saturate in the case |
740 | where input is -2147483648 (0x8000 0000). |
741 | |
742 | Complexity weight : 2 |
743 | |
744 | Inputs : |
745 | |
746 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
747 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
748 | |
749 | Outputs : |
750 | |
751 | none |
752 | |
753 | Return Value : |
754 | |
755 | L_var_out |
756 | 32 bit long signed integer (Word32) whose value falls in the |
757 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
758 |___________________________________________________________________________|
759 */
760
761 static inline Word32 L_negate (Word32 L_var1)
762 {
763 Word32 L_var_out;
764
765 L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1;
766 return (L_var_out);
767 }
768
769 /*___________________________________________________________________________
770 | |
771 | Function Name : L_shl |
772 | |
773 | Purpose : |
774 | |
775 | Arithmetically shift the 32 bit input L_var1 left var2 positions. Zero |
776 | fill the var2 LSB of the result. If var2 is negative, arithmetically |
777 | shift L_var1 right by -var2 with sign extension. Saturate the result in |
778 | case of underflows or overflows. |
779 | |
780 | Complexity weight : 2 |
781 | |
782 | Inputs : |
783 | |
784 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
785 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
786 | |
787 | var2 |
788 | 16 bit short signed integer (Word16) whose value falls in the |
789 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
790 | |
791 | Outputs : |
792 | |
793 | none |
794 | |
795 | Return Value : |
796 | |
797 | L_var_out |
798 | 32 bit long signed integer (Word32) whose value falls in the |
799 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
800 |___________________________________________________________________________|
801 */
802
803 static inline Word32 L_shl (Word32 L_var1, Word16 var2)
804 {
805 Word32 L_var_out;
806
807 if (var2 < 0) {
808 var2 = -var2;
809 if (unlikely(var2 >= 31))
810 L_var_out = (L_var1 < 0) ? -1 : 0;
811 else
812 L_var_out = L_var1 >> var2;
813 } else {
814 L_var_out = L_var1 << var2;
815 if (unlikely(L_var_out >> var2 != L_var1))
816 L_var_out = (L_var1 >> 31) ^ MAX_32;
817 }
818 return (L_var_out);
819 }
820
821 /*___________________________________________________________________________
822 | |
823 | Function Name : L_shr |
824 | |
825 | Purpose : |
826 | |
827 | Arithmetically shift the 32 bit input L_var1 right var2 positions with |
828 | sign extension. If var2 is negative, arithmetically shift L_var1 left |
829 | by -var2 and zero fill the -var2 LSB of the result. Saturate the result |
830 | in case of underflows or overflows. |
831 | |
832 | Complexity weight : 2 |
833 | |
834 | Inputs : |
835 | |
836 | L_var1 32 bit long signed integer (Word32) whose value falls in the |
837 | range : 0x8000 0000 <= L_var3 <= 0x7fff ffff. |
838 | |
839 | var2 |
840 | 16 bit short signed integer (Word16) whose value falls in the |
841 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
842 | |
843 | Outputs : |
844 | |
845 | none |
846 | |
847 | Return Value : |
848 | |
849 | L_var_out |
850 | 32 bit long signed integer (Word32) whose value falls in the |
851 | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |
852 |___________________________________________________________________________|
853 */
854
855 static inline Word32 L_shr (Word32 L_var1, Word16 var2)
856 {
857 Word32 L_var_out;
858
859 if (var2 < 0) {
860 var2 = -var2;
861 L_var_out = L_var1 << var2;
862 if (unlikely(L_var_out >> var2 != L_var1))
863 L_var_out = (L_var1 >> 31) ^ MAX_32;
864 } else {
865 if (unlikely(var2 >= 31))
866 L_var_out = (L_var1 < 0) ? -1 : 0;
867 else
868 L_var_out = L_var1 >> var2;
869 }
870 return (L_var_out);
871 }
872
873 /*___________________________________________________________________________
874 | |
875 | Function Name : L_deposit_h |
876 | |
877 | Purpose : |
878 | |
879 | Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The |
880 | 16 LS bits of the output are zeroed. |
881 | |
882 | Complexity weight : 2 |
883 | |
884 | Inputs : |
885 | |
886 | var1 |
887 | 16 bit short signed integer (Word16) whose value falls in the |
888 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
889 | |
890 | Outputs : |
891 | |
892 | none |
893 | |
894 | Return Value : |
895 | |
896 | L_var_out |
897 | 32 bit long signed integer (Word32) whose value falls in the |
898 | range : 0x8000 0000 <= var_out <= 0x7fff 0000. |
899 |___________________________________________________________________________|
900 */
901
902 static inline Word32 L_deposit_h (Word16 var1)
903 {
904 Word32 L_var_out;
905
906 L_var_out = (Word32) var1 << 16;
907 return (L_var_out);
908 }
909
910 /*___________________________________________________________________________
911 | |
912 | Function Name : L_deposit_l |
913 | |
914 | Purpose : |
915 | |
916 | Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The |
917 | 16 MS bits of the output are sign extended. |
918 | |
919 | Complexity weight : 2 |
920 | |
921 | Inputs : |
922 | |
923 | var1 |
924 | 16 bit short signed integer (Word16) whose value falls in the |
925 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
926 | |
927 | Outputs : |
928 | |
929 | none |
930 | |
931 | Return Value : |
932 | |
933 | L_var_out |
934 | 32 bit long signed integer (Word32) whose value falls in the |
935 | range : 0xFFFF 8000 <= var_out <= 0x0000 7fff. |
936 |___________________________________________________________________________|
937 */
938
939 static inline Word32 L_deposit_l (Word16 var1)
940 {
941 Word32 L_var_out;
942
943 L_var_out = (Word32) var1;
944 return (L_var_out);
945 }
946
947 /*___________________________________________________________________________
948 | |
949 | Function Name : L_abs |
950 | |
951 | Purpose : |
952 | |
953 | Absolute value of L_var1; Saturate in case where the input is |
954 | -214783648 |
955 | |
956 | Complexity weight : 3 |
957 | |
958 | Inputs : |
959 | |
960 | L_var1 |
961 | 32 bit long signed integer (Word32) whose value falls in the |
962 | range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
963 | |
964 | Outputs : |
965 | |
966 | none |
967 | |
968 | Return Value : |
969 | |
970 | L_var_out |
971 | 32 bit long signed integer (Word32) whose value falls in the |
972 | range : 0x0000 0000 <= var_out <= 0x7fff ffff. |
973 |___________________________________________________________________________|
974 */
975
976 static inline Word32 L_abs (Word32 L_var1)
977 {
978 Word32 L_var_out;
979
980 if (L_var1 == MIN_32)
981 {
982 L_var_out = MAX_32;
983 }
984 else
985 {
986 if (L_var1 < 0)
987 {
988 L_var_out = -L_var1;
989 }
990 else
991 {
992 L_var_out = L_var1;
993 }
994 }
995
996 return (L_var_out);
997 }
998
999 /* additional ops */
1000
1001 /*___________________________________________________________________________
1002 | |
1003 | Function Name : mult_r |
1004 | |
1005 | Purpose : |
1006 | |
1007 | Same as mult with rounding, i.e.: |
1008 | mult_r(var1,var2) = extract_l(L_shr(((var1 * var2) + 16384),15)) and |
1009 | mult_r(-32768,-32768) = 32767. |
1010 | |
1011 | Complexity weight : 2 |
1012 | |
1013 | Inputs : |
1014 | |
1015 | var1 |
1016 | 16 bit short signed integer (Word16) whose value falls in the |
1017 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1018 | |
1019 | var2 |
1020 | 16 bit short signed integer (Word16) whose value falls in the |
1021 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1022 | |
1023 | Outputs : |
1024 | |
1025 | none |
1026 | |
1027 | Return Value : |
1028 | |
1029 | var_out |
1030 | 16 bit short signed integer (Word16) whose value falls in the |
1031 | range : 0xffff 8000 <= var_out <= 0x0000 7fff. |
1032 |___________________________________________________________________________|
1033 */
1034
1035 static inline Word16 mult_r (Word16 var1, Word16 var2)
1036 {
1037 Word16 var_out;
1038 Word32 L_product_arr;
1039
1040 L_product_arr = (Word32) var1 *(Word32) var2; /* product */
1041 L_product_arr += (Word32) 0x00004000L; /* round */
1042 L_product_arr &= (Word32) 0xffff8000L;
1043 L_product_arr >>= 15; /* shift */
1044
1045 if (unlikely(L_product_arr > MAX_16))
1046 return MAX_16;
1047 else if (unlikely(L_product_arr < MIN_16))
1048 return MIN_16;
1049 else
1050 return L_product_arr;
1051 }
1052
1053 /*___________________________________________________________________________
1054 | |
1055 | Function Name : norm_s |
1056 | |
1057 | Purpose : |
1058 | |
1059 | Produces the number of left shift needed to normalize the 16 bit varia- |
1060 | ble var1 for positive values on the interval with minimum of 16384 and |
1061 | maximum of 32767, and for negative values on the interval with minimum |
1062 | of -32768 and maximum of -16384; in order to normalize the result, the |
1063 | following operation must be done : |
1064 | norm_var1 = shl(var1,norm_s(var1)). |
1065 | |
1066 | Complexity weight : 15 |
1067 | |
1068 | Inputs : |
1069 | |
1070 | var1 |
1071 | 16 bit short signed integer (Word16) whose value falls in the |
1072 | range : 0xffff 8000 <= var1 <= 0x0000 7fff. |
1073 | |
1074 | Outputs : |
1075 | |
1076 | none |
1077 | |
1078 | Return Value : |
1079 | |
1080 | var_out |
1081 | 16 bit short signed integer (Word16) whose value falls in the |
1082 | range : 0x0000 0000 <= var_out <= 0x0000 000f. |
1083 |___________________________________________________________________________|
1084 */
1085
1086 static inline Word16 norm_s (Word16 var1)
1087 {
1088 Word16 var_out;
1089
1090 if (var1 == 0)
1091 {
1092 var_out = 0;
1093 }
1094 else
1095 {
1096 if (var1 == (Word16) 0xffff)
1097 {
1098 var_out = 15;
1099 }
1100 else
1101 {
1102 if (var1 < 0)
1103 {
1104 var1 = ~var1;
1105 }
1106 for (var_out = 0; var1 < 0x4000; var_out++)
1107 {
1108 var1 <<= 1;
1109 }
1110 }
1111 }
1112
1113 return (var_out);
1114 }
1115
1116 /*___________________________________________________________________________
1117 | |
1118 | Function Name : norm_l |
1119 | |
1120 | Purpose : |
1121 | |
1122 | Produces the number of left shifts needed to normalize the 32 bit varia-|
1123 | ble L_var1 for positive values on the interval with minimum of |
1124 | 1073741824 and maximum of 2147483647, and for negative values on the in-|
1125 | terval with minimum of -2147483648 and maximum of -1073741824; in order |
1126 | to normalize the result, the following operation must be done : |
1127 | norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). |
1128 | |
1129 | Complexity weight : 30 |
1130 | |
1131 | Inputs : |
1132 | |
1133 | L_var1 |
1134 | 32 bit long signed integer (Word32) whose value falls in the |
1135 | range : 0x8000 0000 <= var1 <= 0x7fff ffff. |
1136 | |
1137 | Outputs : |
1138 | |
1139 | none |
1140 | |
1141 | Return Value : |
1142 | |
1143 | var_out |
1144 | 16 bit short signed integer (Word16) whose value falls in the |
1145 | range : 0x0000 0000 <= var_out <= 0x0000 001f. |
1146 |___________________________________________________________________________|
1147 */
1148
1149 static inline Word16 norm_l (Word32 L_var1)
1150 {
1151 Word16 var_out;
1152
1153 if (L_var1 == 0)
1154 {
1155 var_out = 0;
1156 }
1157 else
1158 {
1159 if (L_var1 == (Word32) 0xffffffffL)
1160 {
1161 var_out = 31;
1162 }
1163 else
1164 {
1165 if (L_var1 < 0)
1166 {
1167 L_var1 = ~L_var1;
1168 }
1169 for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
1170 {
1171 L_var1 <<= 1;
1172 }
1173 }
1174 }
1175
1176 return (var_out);
1177 }
1178
1179 /* ETSI functions that aren't inlined */
1180
34 Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2); /* Mac without 1181 Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2); /* Mac without
35 sat, 1 */ 1182 sat, 1 */
36 Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2); /* Msu without 1183 Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2); /* Msu without
37 sat, 1 */ 1184 sat, 1 */
38 Word32 L_add (Word32 L_var1, Word32 L_var2); /* Long add, 2 */
39 Word32 L_sub (Word32 L_var1, Word32 L_var2); /* Long sub, 2 */
40 Word32 L_add_c (Word32 L_var1, Word32 L_var2); /* Long add with c, 2 */ 1185 Word32 L_add_c (Word32 L_var1, Word32 L_var2); /* Long add with c, 2 */
41 Word32 L_sub_c (Word32 L_var1, Word32 L_var2); /* Long sub with c, 2 */ 1186 Word32 L_sub_c (Word32 L_var1, Word32 L_var2); /* Long sub with c, 2 */
42 Word32 L_negate (Word32 L_var1); /* Long negate, 2 */
43 Word16 mult_r (Word16 var1, Word16 var2); /* Mult with round, 2 */
44 Word32 L_shl (Word32 L_var1, Word16 var2); /* Long shift left, 2 */
45 Word32 L_shr (Word32 L_var1, Word16 var2); /* Long shift right, 2*/
46 Word16 shr_r (Word16 var1, Word16 var2); /* Shift right with 1187 Word16 shr_r (Word16 var1, Word16 var2); /* Shift right with
47 round, 2 */ 1188 round, 2 */
48 Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); /* Mac with 1189 Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2); /* Mac with
49 rounding,2 */ 1190 rounding,2 */
50 Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); /* Msu with 1191 Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2); /* Msu with
51 rounding,2 */ 1192 rounding,2 */
52 Word32 L_deposit_h (Word16 var1); /* 16 bit var1 -> MSB, 2 */
53 Word32 L_deposit_l (Word16 var1); /* 16 bit var1 -> LSB, 2 */
54
55 Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with 1193 Word32 L_shr_r (Word32 L_var1, Word16 var2); /* Long shift right with
56 round, 3 */ 1194 round, 3 */
57 Word32 L_abs (Word32 L_var1); /* Long abs, 3 */
58 Word32 L_sat (Word32 L_var1); /* Long saturation, 4 */ 1195 Word32 L_sat (Word32 L_var1); /* Long saturation, 4 */
59 Word16 norm_s (Word16 var1); /* Short norm, 15 */
60 Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */ 1196 Word16 div_s (Word16 var1, Word16 var2); /* Short division, 18 */
61 Word16 norm_l (Word32 L_var1); /* Long norm, 30 */
62