FreeCalypso > hg > gsm-codec-lib
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 |