Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*
34 : ===========================================================================
35 : File: ENH40.C v.2.3 - 30.Nov.2009
36 : ===========================================================================
37 :
38 : ITU-T STL BASIC OPERATORS
39 :
40 : 40-BIT ARITHMETIC OPERATORS
41 :
42 : History:
43 : 07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control
44 : operators for the ITU-T Standard Tool Library as
45 : described in Geneva, 20-30 January 2004 WP 3/16 Q10/16
46 : TD 11 document and subsequent discussions on the
47 : wp3audio@yahoogroups.com email reflector.
48 :
49 : ============================================================================
50 : */
51 :
52 :
53 : /*****************************************************************************
54 : *
55 : * Enhanced 40 bit operators :
56 : *
57 : * L40_add()
58 : * L40_sub()
59 : * L40_abs()
60 : * L40_negate()
61 : * L40_max()
62 : * L40_min()
63 : * L40_shr()
64 : * L40_shr_r()
65 : * L40_shl()
66 : * L40_shl_r()
67 : * norm_L40()
68 : * L40_mult()
69 : * L40_mac()
70 : * L40_msu()
71 : * mac_r40()
72 : * msu_r40()
73 : * Mpy_32_16_ss()
74 : * Mpy_32_32_ss()
75 : * L40_lshl()
76 : * L40_lshr()
77 : * L40_round()
78 : * L_saturate40()
79 : * L40_set()
80 : * Extract40_H()
81 : * Extract40_L()
82 : * L_Extract40()
83 : * L40_deposit_h()
84 : * L40_deposit_l()
85 : * L40_deposit32()
86 : *
87 : *****************************************************************************/
88 :
89 :
90 : /*****************************************************************************
91 : *
92 : * Include-Files
93 : *
94 : *****************************************************************************/
95 :
96 : #include <stdio.h>
97 : #include <stdlib.h>
98 : #include "stl.h"
99 : #include <assert.h>
100 :
101 : #define WMC_TOOL_SKIP
102 :
103 : #ifdef _MSC_VER
104 : #pragma warning( disable : 4310 )
105 : #endif
106 :
107 : /*****************************************************************************
108 : *
109 : * Local Functions
110 : *
111 : *****************************************************************************/
112 :
113 :
114 : /*****************************************************************************
115 : *
116 : * Constants and Globals
117 : *
118 : *****************************************************************************/
119 :
120 :
121 : /*****************************************************************************
122 : *
123 : * Functions
124 : *
125 : *****************************************************************************/
126 :
127 : /*****************************************************************************
128 : *
129 : * Function Name : L40_shl
130 : *
131 : * Purpose :
132 : *
133 : * Arithmetically shifts left L40_var1 by var2 positions.
134 : * - If var2 is negative, L40_var1 is shifted to the LSBits by (-var2)
135 : * positions with extension of the sign bit.
136 : * - If var2 is positive, L40_var1 is shifted to the MSBits by (var2)
137 : * positions.
138 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
139 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
140 : *
141 : * Complexity weight : 1
142 : *
143 : * Inputs :
144 : *
145 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
146 : * range : MIN_40 <= L40_var1 <= MAX_40.
147 : *
148 : * var2 16 bit short signed integer (Word16) whose value falls in
149 : * the range : MIN_16 <= var2 <= MAX_16.
150 : *
151 : * Outputs :
152 : *
153 : * none
154 : *
155 : * Return Value :
156 : *
157 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
158 : * the range : MIN_40 <= L40_var_out <= MAX_40.
159 : *
160 : *****************************************************************************/
161 0 : Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow )
162 : {
163 :
164 : Word40 L40_var_out;
165 : Word40 L40_constant;
166 :
167 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
168 : L40_constant = L40_set( 0xc000000000 );
169 : #else
170 0 : L40_constant = L40_set( 0xc000000000LL );
171 : #endif
172 :
173 0 : if ( var2 < 0 )
174 : {
175 0 : var2 = -var2;
176 0 : L40_var_out = L40_shr( L40_var1, var2 );
177 : }
178 :
179 : else
180 : {
181 0 : L40_var_out = L40_var1;
182 :
183 0 : for ( ; var2 > 0; var2-- )
184 : {
185 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
186 : if ( L40_var_out > 0x003fffffffff )
187 : #else
188 0 : if ( L40_var_out > 0x003fffffffffLL )
189 : #endif
190 : {
191 0 : *Overflow = 1;
192 0 : L40_var_out = MAX_40;
193 0 : break;
194 : }
195 :
196 0 : else if ( L40_var_out < L40_constant )
197 : {
198 0 : *Overflow = 1;
199 0 : L40_var_out = MIN_40;
200 0 : break;
201 : }
202 :
203 : else
204 : {
205 0 : L40_var_out = L40_var_out << 1;
206 : }
207 : }
208 : }
209 :
210 : #ifdef WMOPS
211 : multiCounter[currCounter].L40_shl++;
212 : #endif
213 :
214 : BASOP_CHECK();
215 :
216 0 : return ( L40_var_out );
217 : }
218 :
219 0 : Word40 L40_shl( Word40 L40_var1, Word16 var2 )
220 : {
221 :
222 : Word40 L40_var_out;
223 : Word40 L40_constant;
224 :
225 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
226 : L40_constant = L40_set( 0xc000000000 );
227 : #else
228 0 : L40_constant = L40_set( 0xc000000000LL );
229 : #endif
230 :
231 0 : if ( var2 < 0 )
232 : {
233 0 : var2 = -var2;
234 0 : L40_var_out = L40_shr( L40_var1, var2 );
235 : }
236 :
237 : else
238 : {
239 0 : L40_var_out = L40_var1;
240 :
241 0 : for ( ; var2 > 0; var2-- )
242 : {
243 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
244 : if ( L40_var_out > 0x003fffffffff )
245 : #else
246 0 : if ( L40_var_out > 0x003fffffffffLL )
247 : #endif
248 : {
249 0 : assert( 0 );
250 : L40_var_out = MAX_40;
251 : break;
252 : }
253 :
254 0 : else if ( L40_var_out < L40_constant )
255 : {
256 0 : assert( 0 );
257 : L40_var_out = MIN_40;
258 : break;
259 : }
260 :
261 : else
262 : {
263 0 : L40_var_out = L40_var_out << 1;
264 : }
265 : }
266 : }
267 :
268 : #ifdef WMOPS
269 : multiCounter[currCounter].L40_shl++;
270 : #endif
271 :
272 : BASOP_CHECK();
273 :
274 :
275 0 : return ( L40_var_out );
276 : }
277 :
278 : /*****************************************************************************
279 : *
280 : * Function Name : L40_shr
281 : *
282 : * Purpose :
283 : *
284 : * Arithmetically shifts right L40_var1 by var2 positions.
285 : * - If var2 is positive, L40_var1 is shifted to the LSBits by (var2)
286 : * positions with extension of the sign bit.
287 : * - If var2 is negative, L40_var1 is shifted to the MSBits by (-var2)
288 : * positions.
289 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
290 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
291 : *
292 : * Complexity weight : 1
293 : *
294 : * Inputs :
295 : *
296 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
297 : * range : MIN_40 <= L40_var1 <= MAX_40.
298 : *
299 : * var2 16 bit short signed integer (Word16) whose value falls in
300 : * the range : MIN_16 <= var2 <= MAX_16.
301 : *
302 : * Outputs :
303 : *
304 : * none
305 : *
306 : * Return Value :
307 : *
308 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
309 : * the range : MIN_40 <= L40_var_out <= MAX_40.
310 : *
311 : *****************************************************************************/
312 4617206575 : Word40 L40_shr( Word40 L40_var1, Word16 var2 )
313 : {
314 : Word40 L40_var_out;
315 :
316 4617206575 : if ( var2 < 0 )
317 : {
318 0 : var2 = -var2;
319 0 : L40_var_out = L40_shl( L40_var1, var2 );
320 : }
321 : else
322 : {
323 4617206575 : L40_var_out = L40_var1 >> var2;
324 : }
325 :
326 : #ifdef WMOPS
327 : multiCounter[currCounter].L40_shr++;
328 : #endif
329 :
330 4617206575 : return ( L40_var_out );
331 : }
332 :
333 :
334 : /*****************************************************************************
335 : *
336 : * Function Name : L40_negate
337 : *
338 : * Purpose :
339 : *
340 : * Negates L40_var1.
341 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
342 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
343 : *
344 : * Complexity weight : 1
345 : *
346 : * Inputs :
347 : *
348 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
349 : * range : MIN_40 <= L40_var1 <= MAX_40.
350 : *
351 : * Outputs :
352 : *
353 : * none
354 : *
355 : * Return Value :
356 : *
357 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
358 : * the range : MIN_40 <= L40_var_out <= MAX_40.
359 : *
360 : *****************************************************************************/
361 0 : Word40 L40_negate( Word40 L40_var1 )
362 : {
363 : Word40 L40_var_out;
364 :
365 0 : L40_var_out = L40_add( ~L40_var1, 0x01 );
366 :
367 : #ifdef WMOPS
368 : multiCounter[currCounter].L40_negate++;
369 : #endif
370 :
371 0 : return ( L40_var_out );
372 : }
373 :
374 :
375 : /*****************************************************************************
376 : *
377 : * Function Name : L40_add
378 : *
379 : * Purpose :
380 : *
381 : * Adds L40_var1 and L40_var2 and returns the 40-bit result.
382 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
383 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
384 : *
385 : * Complexity weight : 1
386 : *
387 : * Inputs :
388 : *
389 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
390 : * range : MIN_40 <= L40_var1 <= MAX_40.
391 : *
392 : * L40_var2 40 bit long signed integer (Word40) whose value falls in the
393 : * range : MIN_40 <= L40_var2 <= MAX_40.
394 : *
395 : * Outputs :
396 : *
397 : * none
398 : *
399 : * Return Value :
400 : *
401 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
402 : * the range : MIN_40 <= L40_var_out <= MAX_40.
403 : *
404 : *****************************************************************************/
405 :
406 0 : Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow )
407 : {
408 : Word40 L40_var_out;
409 :
410 0 : L40_var_out = L40_var1 + L40_var2;
411 :
412 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
413 : if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) )
414 : {
415 : *Overflow = 1;
416 : L40_var_out = MIN_40;
417 : }
418 : else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) )
419 : {
420 : *Overflow = 1;
421 : L40_var_out = MAX_40;
422 : }
423 : #else
424 0 : if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) )
425 : {
426 0 : *Overflow = 1;
427 0 : L40_var_out = MIN_40;
428 : }
429 0 : else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) )
430 : {
431 0 : *Overflow = 1;
432 0 : L40_var_out = MAX_40;
433 : }
434 : #endif
435 :
436 : #ifdef WMOPS
437 : multiCounter[currCounter].L40_add++;
438 : #endif
439 :
440 :
441 : BASOP_CHECK();
442 :
443 :
444 0 : return ( L40_var_out );
445 : }
446 :
447 4640510426 : Word40 L40_add( Word40 L40_var1, Word40 L40_var2 )
448 : {
449 : Word40 L40_var_out;
450 :
451 4640510426 : L40_var_out = L40_var1 + L40_var2;
452 :
453 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
454 : if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) )
455 : {
456 : assert( 0 );
457 : L40_var_out = MIN_40;
458 : }
459 : else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) )
460 : {
461 : assert( 0 );
462 : L40_var_out = MAX_40;
463 : }
464 : #else
465 4640510426 : if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) )
466 : {
467 0 : assert( 0 );
468 : L40_var_out = MIN_40;
469 : }
470 4640510426 : else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) )
471 : {
472 0 : assert( 0 );
473 : L40_var_out = MAX_40;
474 : }
475 : #endif
476 :
477 : #ifdef WMOPS
478 : multiCounter[currCounter].L40_add++;
479 : #endif
480 :
481 : BASOP_CHECK();
482 :
483 :
484 4640510426 : return ( L40_var_out );
485 : }
486 :
487 :
488 : /*****************************************************************************
489 : *
490 : * Function Name : L40_sub
491 : *
492 : * Purpose :
493 : *
494 : * Subtracts L40_var2 from L40_var1.
495 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
496 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
497 : *
498 : * Complexity weight : 1
499 : *
500 : * Inputs :
501 : *
502 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
503 : * range : MIN_40 <= L40_var1 <= MAX_40.
504 : *
505 : * L40_var2 40 bit long signed integer (Word40) whose value falls in the
506 : * range : MIN_40 <= L40_var2 <= MAX_40.
507 : *
508 : * Outputs :
509 : *
510 : * none
511 : *
512 : * Return Value :
513 : *
514 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
515 : * the range : MIN_40 <= L40_var_out <= MAX_40.
516 : *
517 : *****************************************************************************/
518 0 : Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow )
519 : {
520 : Word40 L40_var_out;
521 :
522 0 : L40_var_out = L40_var1 - L40_var2;
523 :
524 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
525 : if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) )
526 : {
527 : *Overflow = 1;
528 : L40_var_out = MIN_40;
529 : }
530 : else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) )
531 : {
532 : *Overflow = 1;
533 : L40_var_out = MAX_40;
534 : }
535 : #else
536 0 : if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) )
537 : {
538 0 : *Overflow = 1;
539 0 : L40_var_out = MIN_40;
540 : }
541 0 : else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) )
542 : {
543 0 : *Overflow = 1;
544 0 : L40_var_out = MAX_40;
545 : }
546 : #endif
547 :
548 : #ifdef WMOPS
549 : multiCounter[currCounter].L40_sub++;
550 : #endif
551 :
552 : BASOP_CHECK();
553 :
554 :
555 0 : return ( L40_var_out );
556 : }
557 :
558 0 : Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 )
559 : {
560 : Word40 L40_var_out;
561 :
562 0 : L40_var_out = L40_var1 - L40_var2;
563 :
564 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
565 : if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) )
566 : {
567 : assert( 0 );
568 : L40_var_out = MIN_40;
569 : }
570 : else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) )
571 : {
572 : assert( 0 );
573 : L40_var_out = MAX_40;
574 : }
575 : #else
576 0 : if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) )
577 : {
578 0 : assert( 0 );
579 : L40_var_out = MIN_40;
580 : }
581 0 : else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) )
582 : {
583 0 : assert( 0 );
584 : L40_var_out = MAX_40;
585 : }
586 : #endif
587 :
588 : #ifdef WMOPS
589 : multiCounter[currCounter].L40_sub++;
590 : #endif
591 :
592 : BASOP_CHECK();
593 :
594 :
595 0 : return ( L40_var_out );
596 : }
597 :
598 : /*****************************************************************************
599 : *
600 : * Function Name : L40_abs
601 : *
602 : * Purpose :
603 : *
604 : * Returns the absolute value of L40_var1.
605 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
606 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
607 : *
608 : * Complexity weight : 1
609 : *
610 : * Inputs :
611 : *
612 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
613 : * range : MIN_40 <= L40_var1 <= MAX_40.
614 : *
615 : * Outputs :
616 : *
617 : * none
618 : *
619 : * Return Value :
620 : *
621 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
622 : * the range : 0x00 0000 0000 <= L40_var_out <= MAX_40.
623 : *
624 : *****************************************************************************/
625 0 : Word40 L40_abs( Word40 L40_var1 )
626 : {
627 : Word40 L40_var_out;
628 :
629 0 : if ( L40_var1 < 0 )
630 : {
631 0 : L40_var_out = L40_negate( L40_var1 );
632 : }
633 : else
634 : {
635 0 : L40_var_out = L40_var1;
636 : }
637 :
638 : #ifdef WMOPS
639 : multiCounter[currCounter].L40_abs++;
640 : #endif
641 :
642 0 : return ( L40_var_out );
643 : }
644 :
645 :
646 : /*****************************************************************************
647 : *
648 : * Function Name : L40_max
649 : *
650 : * Purpose :
651 : *
652 : * Compares L40_var1 and L40_var2 and returns the maximum value.
653 : *
654 : *
655 : * Complexity weight : 1
656 : *
657 : * Inputs :
658 : *
659 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
660 : * range : MIN_40 <= L40_var1 <= MAX_40.
661 : *
662 : * L40_var2 40 bit long signed integer (Word40) whose value falls in the
663 : * range : MIN_40 <= L40_var2 <= MAX_40.
664 : *
665 : * Outputs :
666 : *
667 : * none
668 : *
669 : * Return Value :
670 : *
671 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
672 : * the range : MIN_40 <= L40_var_out <= MAX_40.
673 : *
674 : *****************************************************************************/
675 0 : Word40 L40_max( Word40 L40_var1, Word40 L40_var2 )
676 : {
677 : Word40 L40_var_out;
678 :
679 0 : if ( L40_var1 < L40_var2 )
680 0 : L40_var_out = L40_var2;
681 : else
682 0 : L40_var_out = L40_var1;
683 :
684 : #ifdef WMOPS
685 : multiCounter[currCounter].L40_max++;
686 : #endif
687 :
688 0 : return ( L40_var_out );
689 : }
690 :
691 :
692 : /*****************************************************************************
693 : *
694 : * Function Name : L40_min
695 : *
696 : * Purpose :
697 : *
698 : * Compares L40_var1 and L40_var2 and returns the minimum value.
699 : *
700 : *
701 : * Complexity weight : 1
702 : *
703 : * Inputs :
704 : *
705 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
706 : * range : MIN_40 <= L40_var1 <= MAX_40.
707 : *
708 : * L40_var2 40 bit long signed integer (Word40) whose value falls in the
709 : * range : MIN_40 <= L40_var2 <= MAX_40.
710 : *
711 : * Outputs :
712 : *
713 : * none
714 : *
715 : * Return Value :
716 : *
717 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
718 : * the range : MIN_40 <= L40_var_out <= MAX_40.
719 : *
720 : *****************************************************************************/
721 0 : Word40 L40_min( Word40 L40_var1, Word40 L40_var2 )
722 : {
723 : Word40 L40_var_out;
724 :
725 0 : if ( L40_var1 < L40_var2 )
726 0 : L40_var_out = L40_var1;
727 : else
728 0 : L40_var_out = L40_var2;
729 :
730 : #ifdef WMOPS
731 : multiCounter[currCounter].L40_min++;
732 : #endif
733 :
734 0 : return ( L40_var_out );
735 : }
736 :
737 :
738 : /*****************************************************************************
739 : *
740 : * Function Name : L_saturate40
741 : *
742 : * Purpose :
743 : *
744 : * If L40_var1 is greater than MAX_32, returns MAX_32.
745 : * If L40_var1 is lower than MIN_32, returns MIN_32.
746 : * If not, returns L_Extract40( L40_var1).
747 : *
748 : * Complexity weight : 1
749 : *
750 : * Inputs :
751 : *
752 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
753 : * range : MIN_40 <= L40_var1 <= MAX_40.
754 : *
755 : * Outputs :
756 : *
757 : * none
758 : *
759 : * Return Value :
760 : *
761 : * L_var_out 32 bit long signed integer (Word32) whose value falls in
762 : * the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
763 : *
764 : *****************************************************************************/
765 :
766 0 : Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow )
767 : {
768 : Word32 L_var_out;
769 :
770 0 : Word40 UNDER_L40_var2 = ( Word40 ) ~( ( ( (Word40) 1 ) << 31 ) - (Word40) 1 );
771 0 : Word40 OVER_L40_var2 = (Word40) ( ( ( (Word40) 1 ) << 31 ) - (Word40) 1 );
772 :
773 0 : if ( L40_var1 < UNDER_L40_var2 )
774 : {
775 0 : L40_var1 = UNDER_L40_var2;
776 0 : *Overflow = 1;
777 : }
778 :
779 0 : if ( L40_var1 > OVER_L40_var2 )
780 : {
781 0 : L40_var1 = OVER_L40_var2;
782 0 : *Overflow = 1;
783 : }
784 :
785 0 : L_var_out = L_Extract40( L40_var1 );
786 :
787 : #ifdef WMOPS
788 : multiCounter[currCounter].L_saturate40++;
789 : #endif
790 :
791 : BASOP_CHECK();
792 :
793 :
794 0 : return ( L_var_out );
795 : }
796 :
797 0 : Word32 L_saturate40( Word40 L40_var1 )
798 : {
799 : Word32 L_var_out;
800 :
801 0 : Word40 UNDER_L40_var2 = ( Word40 ) ~( ( ( (Word40) 1 ) << 31 ) - (Word40) 1 );
802 0 : Word40 OVER_L40_var2 = (Word40) ( ( ( (Word40) 1 ) << 31 ) - (Word40) 1 );
803 :
804 0 : if ( L40_var1 < UNDER_L40_var2 )
805 : {
806 0 : L40_var1 = UNDER_L40_var2;
807 0 : assert( 0 );
808 : }
809 :
810 0 : if ( L40_var1 > OVER_L40_var2 )
811 : {
812 0 : L40_var1 = OVER_L40_var2;
813 0 : assert( 0 );
814 : }
815 :
816 0 : L_var_out = L_Extract40( L40_var1 );
817 :
818 : #ifdef WMOPS
819 : multiCounter[currCounter].L_saturate40++;
820 : #endif
821 :
822 : BASOP_CHECK();
823 :
824 :
825 0 : return ( L_var_out );
826 : }
827 :
828 : /*****************************************************************************
829 : *
830 : * Function Name : Mpy_32_16_ss
831 : *
832 : * Purpose :
833 : *
834 : * Multiplies the 2 signed values L_var1 and var2 with saturation control
835 : * on 48-bit. The operation is performed in fractional mode :
836 : * - L_var1 is supposed to be in 1Q31 format.
837 : * - var2 is supposed to be in 1Q15 format.
838 : * - The result is produced in 1Q47 format : L_varout_h points to the
839 : * 32 MSBits while varout_l points to the 16 LSBits.
840 : *
841 : * Complexity weight : 2
842 : *
843 : * Inputs :
844 : *
845 : * L_var1 32 bit long signed integer (Word32) whose value falls in
846 : * the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
847 : *
848 : * var2 16 bit short signed integer (Word16) whose value falls in
849 : * the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
850 : *
851 : * Outputs :
852 : *
853 : * *L_varout_h 32 bit long signed integer (Word32) whose value falls in
854 : * the range : 0x8000 0000 <= L_varout_h <= 0x7fff ffff.
855 : *
856 : * *varout_l 16 bit short unsigned integer (UWord16) whose value falls in
857 : * the range : 0x0000 0000 <= varout_l <= 0x0000 ffff.
858 : *
859 : * Return Value :
860 : *
861 : * none
862 : *
863 : *****************************************************************************/
864 4570598873 : void Mpy_32_16_ss( Word32 L_var1, Word16 var2, Word32 *L_varout_h, UWord16 *varout_l )
865 : {
866 : Word16 var1_h;
867 : UWord16 uvar1_l;
868 : Word40 L40_var1;
869 :
870 4570598873 : if ( ( L_var1 == (Word32) 0x80000000 ) && ( var2 == (Word16) 0x8000 ) )
871 : {
872 0 : *L_varout_h = 0x7fffffff;
873 0 : *varout_l = (UWord16) 0xffff;
874 : }
875 : else
876 : {
877 4570598873 : uvar1_l = extract_l( L_var1 );
878 4570598873 : var1_h = extract_h( L_var1 );
879 :
880 : /* Below line can not overflow, so we can use << instead of L40_shl. */
881 4570598873 : L40_var1 = ( (Word40) ( (Word32) var2 * (Word32) uvar1_l ) ) << 1;
882 :
883 4570598873 : *varout_l = Extract40_L( L40_var1 );
884 :
885 4570598873 : L40_var1 = L40_shr( L40_var1, 16 );
886 4570598873 : L40_var1 = L40_mac( L40_var1, var2, var1_h );
887 :
888 4570598873 : *L_varout_h = L_Extract40( L40_var1 );
889 :
890 : #ifdef WMOPS
891 : multiCounter[currCounter].extract_l--;
892 : multiCounter[currCounter].extract_h--;
893 : multiCounter[currCounter].Extract40_L--;
894 : multiCounter[currCounter].L40_shr--;
895 : multiCounter[currCounter].L40_mac--;
896 : multiCounter[currCounter].L_Extract40--;
897 : #endif
898 : }
899 :
900 : #ifdef WMOPS
901 : multiCounter[currCounter].Mpy_32_16_ss++;
902 : #endif
903 :
904 4570598873 : return;
905 : }
906 :
907 :
908 : /*****************************************************************************
909 : *
910 : * Function Name : Mpy_32_32_ss
911 : *
912 : * Purpose :
913 : *
914 : * Multiplies the 2 signed values L_var1 and L_var2 with saturation control
915 : * on 64-bit. The operation is performed in fractional mode :
916 : * - L_var1 and L_var2 are supposed to be in 1Q31 format.
917 : * - The result is produced in 1Q63 format : L_varout_h points to the
918 : * 32 MSBits while L_varout_l points to the 32 LSBits.
919 : *
920 : * Complexity weight : 4
921 : *
922 : * Inputs :
923 : *
924 : * L_var1 32 bit long signed integer (Word32) whose value falls in the
925 : * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
926 : *
927 : * L_var2 32 bit long signed integer (Word32) whose value falls in the
928 : * range : 0x8000 0000 <= L_var2 <= 0x7fff ffff.
929 : *
930 : * Outputs :
931 : *
932 : * *L_varout_h 32 bit long signed integer (Word32) whose value falls in
933 : * the range : 0x8000 0000 <= L_varout_h <= 0x7fff ffff.
934 : *
935 : * *L_varout_l 32 bit short unsigned integer (UWord32) whose value falls in
936 : * the range : 0x0000 0000 <= L_varout_l <= 0xffff ffff.
937 : *
938 : *
939 : * Return Value :
940 : *
941 : * none
942 : *
943 : *****************************************************************************/
944 23303851 : void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_varout_l )
945 : {
946 : UWord16 uvar1_l, uvar2_l;
947 : Word16 var1_h, var2_h;
948 : Word40 L40_var1;
949 :
950 23303851 : if ( ( L_var1 == (Word32) 0x80000000 ) && ( L_var2 == (Word32) 0x80000000 ) )
951 : {
952 0 : *L_varout_h = 0x7fffffff;
953 0 : *L_varout_l = (UWord32) 0xffffffff;
954 : }
955 : else
956 : {
957 :
958 23303851 : uvar1_l = extract_l( L_var1 );
959 23303851 : var1_h = extract_h( L_var1 );
960 23303851 : uvar2_l = extract_l( L_var2 );
961 23303851 : var2_h = extract_h( L_var2 );
962 :
963 : /* Below line can not overflow, so we can use << instead of L40_shl. */
964 23303851 : L40_var1 = ( (Word40) ( (UWord32) uvar2_l * (UWord32) uvar1_l ) ) << 1;
965 :
966 23303851 : *L_varout_l = 0x0000ffff & L_Extract40( L40_var1 );
967 :
968 23303851 : L40_var1 = L40_shr( L40_var1, 16 );
969 23303851 : L40_var1 = L40_add( L40_var1, ( (Word40) ( (Word32) var2_h * (Word32) uvar1_l ) ) << 1 );
970 23303851 : L40_var1 = L40_add( L40_var1, ( (Word40) ( (Word32) var1_h * (Word32) uvar2_l ) ) << 1 );
971 23303851 : *L_varout_l |= ( L_Extract40( L40_var1 ) ) << 16;
972 :
973 23303851 : L40_var1 = L40_shr( L40_var1, 16 );
974 23303851 : L40_var1 = L40_mac( L40_var1, var1_h, var2_h );
975 :
976 23303851 : *L_varout_h = L_Extract40( L40_var1 );
977 :
978 : #ifdef WMOPS
979 : multiCounter[currCounter].extract_l -= 2;
980 : multiCounter[currCounter].extract_h -= 2;
981 : multiCounter[currCounter].L_Extract40 -= 3;
982 : multiCounter[currCounter].L40_shr -= 2;
983 : multiCounter[currCounter].L40_add -= 2;
984 : multiCounter[currCounter].L40_mac--;
985 : #endif
986 : }
987 :
988 : #ifdef WMOPS
989 : multiCounter[currCounter].Mpy_32_32_ss++;
990 : #endif
991 :
992 23303851 : return;
993 : }
994 :
995 :
996 : /*****************************************************************************
997 : *
998 : * Function Name : L40_lshl
999 : *
1000 : * Purpose :
1001 : *
1002 : * Logically shifts left L40_var1 by var2 positions.
1003 : * - If var2 is negative, L40_var1 is shifted to the LSBits by (-var2)
1004 : * positions with insertion of 0 at the MSBit.
1005 : * - If var2 is positive, L40_var1 is shifted to the MSBits by (var2)
1006 : * positions.
1007 : *
1008 : * Complexity weight : 1
1009 : *
1010 : * Inputs :
1011 : *
1012 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1013 : * range : MIN_40 <= L40_var1 <= MAX_40.
1014 : *
1015 : * var2 16 bit short signed integer (Word16) whose value falls in
1016 : * the range : MIN_16 <= var2 <= MAX_16.
1017 : *
1018 : * Outputs :
1019 : *
1020 : * none
1021 : *
1022 : * Return Value :
1023 : *
1024 : * L_var_out 32 bit long unsigned integer (UWord32) whose value falls in
1025 : * the range : MIN_40 <= L40_var_out <= MAX_40.
1026 : *
1027 : *****************************************************************************/
1028 0 : Word40 L40_lshl( Word40 L40_var1, Word16 var2 )
1029 : {
1030 : Word40 L40_var_out;
1031 :
1032 0 : if ( var2 <= 0 )
1033 : {
1034 0 : var2 = -var2;
1035 0 : L40_var_out = L40_lshr( L40_var1, var2 );
1036 : #ifdef WMOPS
1037 : multiCounter[currCounter].L40_lshr--;
1038 : #endif
1039 : }
1040 : else
1041 : {
1042 0 : if ( var2 >= 40 )
1043 0 : L40_var_out = 0x0000000000;
1044 : else
1045 : {
1046 0 : L40_var_out = L40_var1 << var2;
1047 : }
1048 0 : L40_var_out = L40_set( L40_var_out );
1049 : }
1050 :
1051 : #ifdef WMOPS
1052 : multiCounter[currCounter].L40_lshl++;
1053 : #endif
1054 :
1055 : BASOP_CHECK();
1056 :
1057 :
1058 0 : return ( L40_var_out );
1059 : }
1060 :
1061 :
1062 : /*****************************************************************************
1063 : *
1064 : * Function Name : L40_lshr
1065 : *
1066 : * Purpose :
1067 : *
1068 : * Logically shifts right L40_var1 by var2 positions.
1069 : * - If var2 is positive, L40_var1 is shifted to the LSBits by (var2)
1070 : * positions with insertion of 0 at the MSBit.
1071 : * - If var2 is negative, L40_var1 is shifted to the MSBits by (-var2)
1072 : * positions.
1073 : *
1074 : * Complexity weight : 1
1075 : *
1076 : * Inputs :
1077 : *
1078 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1079 : * range : MIN_40 <= L40_var1 <= MAX_40.
1080 : *
1081 : * var2 16 bit short signed integer (Word16) whose value falls in
1082 : * the range : MIN_16 <= var2 <= MAX_16.
1083 : *
1084 : * Outputs :
1085 : *
1086 : * none
1087 : *
1088 : * Return Value :
1089 : *
1090 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
1091 : * the range : MIN_40 <= L40_var_out <= MAX_40.
1092 : *
1093 : *****************************************************************************/
1094 0 : Word40 L40_lshr( Word40 L40_var1, Word16 var2 )
1095 : {
1096 : Word40 L40_var_out;
1097 :
1098 0 : if ( var2 < 0 )
1099 : {
1100 0 : var2 = -var2;
1101 0 : L40_var_out = L40_lshl( L40_var1, var2 );
1102 : #ifdef WMOPS
1103 : multiCounter[currCounter].L40_lshl--;
1104 : #endif
1105 : }
1106 : else
1107 : {
1108 0 : if ( var2 >= 40 )
1109 0 : L40_var_out = 0x0000000000;
1110 : else
1111 : {
1112 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
1113 : L40_var_out = ( L40_var1 & 0xffffffffff ) >> var2;
1114 : #else
1115 0 : L40_var_out = ( L40_var1 & 0xffffffffffLL ) >> var2;
1116 : #endif
1117 : }
1118 : }
1119 :
1120 : #ifdef WMOPS
1121 : multiCounter[currCounter].L40_lshr++;
1122 : #endif
1123 :
1124 : BASOP_CHECK();
1125 :
1126 :
1127 0 : return ( L40_var_out );
1128 : }
1129 :
1130 :
1131 : /*****************************************************************************
1132 : *
1133 : * Function Name : norm_L40
1134 : *
1135 : * Purpose :
1136 : *
1137 : * Produces the number of left shifts needed to normalize in 32 bit format
1138 : * the 40 bit variable L40_var1. This returned value can be used to scale
1139 : * L_40_var1 into the following intervals :
1140 : * - [(MAX_32+1)/2 .. MAX_32 ] for positive values.
1141 : * - [ MIN_32 .. (MIN_32/2)+1 ] for negative values.
1142 : * - [ 0 .. 0 ] for null values.
1143 : * In order to normalize the result, the following operation must be done :
1144 : * normelized_L40_var1 = L40_shl( L40_var1, norm_L40( L40_var1))
1145 : *
1146 : * Complexity weight : 1
1147 : *
1148 : * Inputs :
1149 : *
1150 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1151 : * range : MIN_40 <= L40_var1 <= MAX_40.
1152 : *
1153 : * Outputs :
1154 : *
1155 : * none
1156 : *
1157 : * Return Value :
1158 : *
1159 : * var_out 16 bit short signed integer (Word16) whose value falls in
1160 : * the range : -8 <= var_out <= 31.
1161 : *
1162 : *****************************************************************************/
1163 0 : Word16 norm_L40( Word40 L40_var1 )
1164 : {
1165 : Word16 var_out;
1166 :
1167 0 : var_out = 0;
1168 :
1169 0 : if ( L40_var1 != 0 )
1170 : {
1171 0 : while ( ( L40_var1 > (Word32) 0x80000000L ) && ( L40_var1 < (Word32) 0x7fffffffL ) )
1172 : {
1173 :
1174 0 : L40_var1 = L40_shl( L40_var1, 1 );
1175 0 : var_out++;
1176 : }
1177 :
1178 0 : while ( ( L40_var1 < (Word32) 0x80000000L ) || ( L40_var1 > (Word32) 0x7fffffffL ) )
1179 : {
1180 :
1181 0 : L40_var1 = L40_shl( L40_var1, -1 );
1182 0 : var_out--;
1183 : }
1184 : }
1185 :
1186 :
1187 0 : return ( var_out );
1188 : }
1189 :
1190 :
1191 : /*****************************************************************************
1192 : *
1193 : * Function Name : L40_shr_r
1194 : *
1195 : * Purpose :
1196 : *
1197 : * Arithmetically shifts right L40_var1 by var2 positions and rounds the
1198 : * result. It is equivalent to L40_shr( L40_var1, var2) except that if the
1199 : * last bit shifted out to the LSBit is 1, then the shifted result is
1200 : * incremented by 1.
1201 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
1202 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
1203 : *
1204 : * Complexity weight : 3
1205 : *
1206 : * Inputs :
1207 : *
1208 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1209 : * range : MIN_40 <= L40_var1 <= MAX_40.
1210 : *
1211 : * var2 16 bit short signed integer (Word16) whose value falls in
1212 : * the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
1213 : *
1214 : * Outputs :
1215 : *
1216 : * none
1217 : *
1218 : * Return Value :
1219 : *
1220 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
1221 : * the range : MIN_40 <= L40_var_out <= MAX_40.
1222 : *
1223 : *****************************************************************************/
1224 0 : Word40 L40_shr_r( Word40 L40_var1, Word16 var2 )
1225 : {
1226 : Word40 L40_var_out;
1227 :
1228 0 : if ( var2 > 39 )
1229 : {
1230 0 : L40_var_out = 0;
1231 : }
1232 : else
1233 : {
1234 0 : L40_var_out = L40_shr( L40_var1, var2 );
1235 :
1236 0 : if ( var2 > 0 )
1237 : {
1238 0 : if ( ( L40_var1 & ( (Word40) 1 << ( var2 - 1 ) ) ) != 0 )
1239 : {
1240 : /* below line can not generate overflows on 40-bit */
1241 0 : L40_var_out++;
1242 : }
1243 : }
1244 : }
1245 :
1246 : BASOP_CHECK();
1247 :
1248 :
1249 0 : return ( L40_var_out );
1250 : }
1251 :
1252 :
1253 : /*****************************************************************************
1254 : *
1255 : * Function Name : L40_shl_r
1256 : *
1257 : * Purpose :
1258 : *
1259 : * Arithmetically shifts left L40_var1 by var2 positions and rounds the
1260 : * result. It is equivalent to L40_shl( L40_var1, var2) except if var2 is
1261 : * negative. In that case, it does the same as
1262 : * L40_shr_r( L40_var1, (-var2)).
1263 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
1264 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
1265 : *
1266 : * Complexity weight : 3
1267 : *
1268 : * Inputs :
1269 : *
1270 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1271 : * range : MIN_40 <= L40_var1 <= MAX_40.
1272 : *
1273 : * var2 16 bit short signed integer (Word16) whose value falls in
1274 : * the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
1275 : *
1276 : * Outputs :
1277 : *
1278 : * none
1279 : *
1280 : * Return Value :
1281 : *
1282 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
1283 : * the range : MIN_40 <= L40_var_out <= MAX_40.
1284 : *
1285 : *****************************************************************************/
1286 0 : Word40 L40_shl_r( Word40 L40_var1, Word16 var2 )
1287 : {
1288 : Word40 L40_var_out;
1289 :
1290 0 : if ( var2 >= 0 )
1291 : {
1292 0 : L40_var_out = L40_shl( L40_var1, var2 );
1293 : }
1294 : else
1295 : {
1296 0 : var2 = -var2;
1297 0 : L40_var_out = L40_shr_r( L40_var1, var2 );
1298 : }
1299 :
1300 :
1301 0 : return ( L40_var_out );
1302 : }
1303 :
1304 :
1305 : #undef WMC_TOOL_SKIP
|