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 : #ifdef BASOP_NOGLOB
100 : #include <assert.h>
101 : #endif /* BASOP_NOGLOB */
102 :
103 : #define WMC_TOOL_SKIP
104 :
105 : #ifdef _MSC_VER
106 : #pragma warning( disable : 4310 )
107 : #endif
108 :
109 : /*****************************************************************************
110 : *
111 : * Local Functions
112 : *
113 : *****************************************************************************/
114 :
115 :
116 : /*****************************************************************************
117 : *
118 : * Constants and Globals
119 : *
120 : *****************************************************************************/
121 :
122 :
123 : /*****************************************************************************
124 : *
125 : * Functions
126 : *
127 : *****************************************************************************/
128 :
129 : /*****************************************************************************
130 : *
131 : * Function Name : L40_shl
132 : *
133 : * Purpose :
134 : *
135 : * Arithmetically shifts left L40_var1 by var2 positions.
136 : * - If var2 is negative, L40_var1 is shifted to the LSBits by (-var2)
137 : * positions with extension of the sign bit.
138 : * - If var2 is positive, L40_var1 is shifted to the MSBits by (var2)
139 : * positions.
140 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
141 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
142 : *
143 : * Complexity weight : 1
144 : *
145 : * Inputs :
146 : *
147 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
148 : * range : MIN_40 <= L40_var1 <= MAX_40.
149 : *
150 : * var2 16 bit short signed integer (Word16) whose value falls in
151 : * the range : MIN_16 <= var2 <= MAX_16.
152 : *
153 : * Outputs :
154 : *
155 : * none
156 : *
157 : * Return Value :
158 : *
159 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
160 : * the range : MIN_40 <= L40_var_out <= MAX_40.
161 : *
162 : *****************************************************************************/
163 : #ifndef BASOP_NOGLOB
164 : Word40 L40_shl( Word40 L40_var1, Word16 var2 )
165 : #else /* BASOP_NOGLOB */
166 0 : Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow )
167 : #endif /* BASOP_NOGLOB */
168 : {
169 :
170 : Word40 L40_var_out;
171 : Word40 L40_constant;
172 :
173 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
174 : L40_constant = L40_set( 0xc000000000 );
175 : #else
176 0 : L40_constant = L40_set( 0xc000000000LL );
177 : #endif
178 :
179 0 : if ( var2 < 0 )
180 : {
181 0 : var2 = -var2;
182 0 : L40_var_out = L40_shr( L40_var1, var2 );
183 : }
184 :
185 : else
186 : {
187 0 : L40_var_out = L40_var1;
188 :
189 0 : for ( ; var2 > 0; var2-- )
190 : {
191 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
192 : if ( L40_var_out > 0x003fffffffff )
193 : #else
194 0 : if ( L40_var_out > 0x003fffffffffLL )
195 : #endif
196 : {
197 : #ifndef BASOP_NOGLOB
198 : Overflow = 1;
199 : exit( 1 );
200 : /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */
201 : #else /* BASOP_NOGLOB */
202 0 : *Overflow = 1;
203 0 : L40_var_out = MAX_40;
204 : #endif /* BASOP_NOGLOB */
205 0 : break;
206 : }
207 :
208 0 : else if ( L40_var_out < L40_constant )
209 : {
210 : #ifndef BASOP_NOGLOB
211 : Overflow = 1;
212 : exit( 2 );
213 : /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */
214 : #else /* BASOP_NOGLOB */
215 0 : *Overflow = 1;
216 0 : L40_var_out = MIN_40;
217 : #endif /* BASOP_NOGLOB */
218 0 : break;
219 : }
220 :
221 : else
222 : {
223 0 : L40_var_out = L40_var_out << 1;
224 : }
225 : }
226 : }
227 :
228 : #ifdef WMOPS
229 : multiCounter[currCounter].L40_shl++;
230 : #endif
231 :
232 : BASOP_CHECK();
233 :
234 0 : return ( L40_var_out );
235 : }
236 :
237 : #ifdef BASOP_NOGLOB
238 0 : Word40 L40_shl( Word40 L40_var1, Word16 var2 )
239 : {
240 :
241 : Word40 L40_var_out;
242 : Word40 L40_constant;
243 :
244 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
245 : L40_constant = L40_set( 0xc000000000 );
246 : #else
247 0 : L40_constant = L40_set( 0xc000000000LL );
248 : #endif
249 :
250 0 : if ( var2 < 0 )
251 : {
252 0 : var2 = -var2;
253 0 : L40_var_out = L40_shr( L40_var1, var2 );
254 : }
255 :
256 : else
257 : {
258 0 : L40_var_out = L40_var1;
259 :
260 0 : for ( ; var2 > 0; var2-- )
261 : {
262 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
263 : if ( L40_var_out > 0x003fffffffff )
264 : #else
265 0 : if ( L40_var_out > 0x003fffffffffLL )
266 : #endif
267 : {
268 0 : assert( 0 );
269 : L40_var_out = MAX_40;
270 : break;
271 : }
272 :
273 0 : else if ( L40_var_out < L40_constant )
274 : {
275 0 : assert( 0 );
276 : L40_var_out = MIN_40;
277 : break;
278 : }
279 :
280 : else
281 : {
282 0 : L40_var_out = L40_var_out << 1;
283 : }
284 : }
285 : }
286 :
287 : #ifdef WMOPS
288 : multiCounter[currCounter].L40_shl++;
289 : #endif
290 :
291 : BASOP_CHECK();
292 :
293 :
294 0 : return ( L40_var_out );
295 : }
296 : #endif /* BASOP_NOGLOB */
297 :
298 : /*****************************************************************************
299 : *
300 : * Function Name : L40_shr
301 : *
302 : * Purpose :
303 : *
304 : * Arithmetically shifts right L40_var1 by var2 positions.
305 : * - If var2 is positive, L40_var1 is shifted to the LSBits by (var2)
306 : * positions with extension of the sign bit.
307 : * - If var2 is negative, L40_var1 is shifted to the MSBits by (-var2)
308 : * positions.
309 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
310 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
311 : *
312 : * Complexity weight : 1
313 : *
314 : * Inputs :
315 : *
316 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
317 : * range : MIN_40 <= L40_var1 <= MAX_40.
318 : *
319 : * var2 16 bit short signed integer (Word16) whose value falls in
320 : * the range : MIN_16 <= var2 <= MAX_16.
321 : *
322 : * Outputs :
323 : *
324 : * none
325 : *
326 : * Return Value :
327 : *
328 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
329 : * the range : MIN_40 <= L40_var_out <= MAX_40.
330 : *
331 : *****************************************************************************/
332 243776882 : Word40 L40_shr( Word40 L40_var1, Word16 var2 )
333 : {
334 : Word40 L40_var_out;
335 :
336 243776882 : if ( var2 < 0 )
337 : {
338 0 : var2 = -var2;
339 0 : L40_var_out = L40_shl( L40_var1, var2 );
340 : }
341 : else
342 : {
343 243776882 : L40_var_out = L40_var1 >> var2;
344 : }
345 :
346 : #ifdef WMOPS
347 : multiCounter[currCounter].L40_shr++;
348 : #endif
349 :
350 243776882 : return ( L40_var_out );
351 : }
352 :
353 :
354 : /*****************************************************************************
355 : *
356 : * Function Name : L40_negate
357 : *
358 : * Purpose :
359 : *
360 : * Negates L40_var1.
361 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
362 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
363 : *
364 : * Complexity weight : 1
365 : *
366 : * Inputs :
367 : *
368 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
369 : * range : MIN_40 <= L40_var1 <= MAX_40.
370 : *
371 : * Outputs :
372 : *
373 : * none
374 : *
375 : * Return Value :
376 : *
377 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
378 : * the range : MIN_40 <= L40_var_out <= MAX_40.
379 : *
380 : *****************************************************************************/
381 0 : Word40 L40_negate( Word40 L40_var1 )
382 : {
383 : Word40 L40_var_out;
384 :
385 0 : L40_var_out = L40_add( ~L40_var1, 0x01 );
386 :
387 : #ifdef WMOPS
388 : multiCounter[currCounter].L40_negate++;
389 : #endif
390 :
391 0 : return ( L40_var_out );
392 : }
393 :
394 :
395 : /*****************************************************************************
396 : *
397 : * Function Name : L40_add
398 : *
399 : * Purpose :
400 : *
401 : * Adds L40_var1 and L40_var2 and returns the 40-bit result.
402 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
403 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
404 : *
405 : * Complexity weight : 1
406 : *
407 : * Inputs :
408 : *
409 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
410 : * range : MIN_40 <= L40_var1 <= MAX_40.
411 : *
412 : * L40_var2 40 bit long signed integer (Word40) whose value falls in the
413 : * range : MIN_40 <= L40_var2 <= MAX_40.
414 : *
415 : * Outputs :
416 : *
417 : * none
418 : *
419 : * Return Value :
420 : *
421 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
422 : * the range : MIN_40 <= L40_var_out <= MAX_40.
423 : *
424 : *****************************************************************************/
425 : #ifdef BASOP_NOGLOB
426 :
427 0 : Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow )
428 : {
429 : Word40 L40_var_out;
430 :
431 0 : L40_var_out = L40_var1 + L40_var2;
432 :
433 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
434 : if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) )
435 : {
436 : *Overflow = 1;
437 : L40_var_out = MIN_40;
438 : }
439 : else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) )
440 : {
441 : *Overflow = 1;
442 : L40_var_out = MAX_40;
443 : }
444 : #else
445 0 : if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) )
446 : {
447 0 : *Overflow = 1;
448 0 : L40_var_out = MIN_40;
449 : }
450 0 : else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) )
451 : {
452 0 : *Overflow = 1;
453 0 : L40_var_out = MAX_40;
454 : }
455 : #endif
456 :
457 : #ifdef WMOPS
458 : multiCounter[currCounter].L40_add++;
459 : #endif
460 :
461 :
462 : BASOP_CHECK();
463 :
464 :
465 0 : return ( L40_var_out );
466 : }
467 :
468 : #endif /* BASOP_NOGLOB */
469 246136485 : Word40 L40_add( Word40 L40_var1, Word40 L40_var2 )
470 : {
471 : Word40 L40_var_out;
472 :
473 246136485 : L40_var_out = L40_var1 + L40_var2;
474 :
475 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
476 : if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) )
477 : {
478 : #ifndef BASOP_NOGLOB
479 : Overflow = 1;
480 : exit( 2 );
481 : /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */
482 : #else /* BASOP_NOGLOB */
483 : assert( 0 );
484 : L40_var_out = MIN_40;
485 : #endif /* BASOP_NOGLOB */
486 : }
487 : else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) )
488 : {
489 : #ifndef BASOP_NOGLOB
490 : Overflow = 1;
491 : exit( 1 );
492 : /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */
493 : #else /* BASOP_NOGLOB */
494 : assert( 0 );
495 : L40_var_out = MAX_40;
496 : #endif /* BASOP_NOGLOB */
497 : }
498 : #else
499 246136485 : if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) )
500 : {
501 : #ifndef BASOP_NOGLOB
502 : Overflow = 1;
503 : exit( 2 );
504 : /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */
505 : #else /* BASOP_NOGLOB */
506 0 : assert( 0 );
507 : L40_var_out = MIN_40;
508 : #endif /* BASOP_NOGLOB */
509 : }
510 246136485 : else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) )
511 : {
512 : #ifndef BASOP_NOGLOB
513 : Overflow = 1;
514 : exit( 1 );
515 : /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */
516 : #else /* BASOP_NOGLOB */
517 0 : assert( 0 );
518 : L40_var_out = MAX_40;
519 : #endif /* BASOP_NOGLOB */
520 : }
521 : #endif
522 :
523 : #ifdef WMOPS
524 : multiCounter[currCounter].L40_add++;
525 : #endif
526 :
527 : BASOP_CHECK();
528 :
529 :
530 246136485 : return ( L40_var_out );
531 : }
532 :
533 :
534 : /*****************************************************************************
535 : *
536 : * Function Name : L40_sub
537 : *
538 : * Purpose :
539 : *
540 : * Subtracts L40_var2 from L40_var1.
541 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
542 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
543 : *
544 : * Complexity weight : 1
545 : *
546 : * Inputs :
547 : *
548 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
549 : * range : MIN_40 <= L40_var1 <= MAX_40.
550 : *
551 : * L40_var2 40 bit long signed integer (Word40) whose value falls in the
552 : * range : MIN_40 <= L40_var2 <= MAX_40.
553 : *
554 : * Outputs :
555 : *
556 : * none
557 : *
558 : * Return Value :
559 : *
560 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
561 : * the range : MIN_40 <= L40_var_out <= MAX_40.
562 : *
563 : *****************************************************************************/
564 : #ifndef BASOP_NOGLOB
565 : Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 )
566 : #else /* BASOP_NOGLOB */
567 0 : Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow )
568 : #endif /* BASOP_NOGLOB */
569 : {
570 : Word40 L40_var_out;
571 :
572 0 : L40_var_out = L40_var1 - L40_var2;
573 :
574 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
575 : if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) )
576 : {
577 : #ifndef BASOP_NOGLOB
578 : Overflow = 1;
579 : exit( 2 );
580 : /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */
581 : #else /* BASOP_NOGLOB */
582 : *Overflow = 1;
583 : L40_var_out = MIN_40;
584 : #endif /* BASOP_NOGLOB */
585 : }
586 : else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) )
587 : {
588 : #ifndef BASOP_NOGLOB
589 : Overflow = 1;
590 : exit( 1 );
591 : /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */
592 : #else /* BASOP_NOGLOB */
593 : *Overflow = 1;
594 : L40_var_out = MAX_40;
595 : #endif /* BASOP_NOGLOB */
596 : }
597 : #else
598 0 : if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) )
599 : {
600 : #ifndef BASOP_NOGLOB
601 : Overflow = 1;
602 : exit( 2 );
603 : /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */
604 : #else /* BASOP_NOGLOB */
605 0 : *Overflow = 1;
606 0 : L40_var_out = MIN_40;
607 : #endif /* BASOP_NOGLOB */
608 : }
609 0 : else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) )
610 : {
611 : #ifndef BASOP_NOGLOB
612 : Overflow = 1;
613 : exit( 1 );
614 : /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */
615 : #else /* BASOP_NOGLOB */
616 0 : *Overflow = 1;
617 0 : L40_var_out = MAX_40;
618 : #endif /* BASOP_NOGLOB */
619 : }
620 : #endif
621 :
622 : #ifdef WMOPS
623 : multiCounter[currCounter].L40_sub++;
624 : #endif
625 :
626 : BASOP_CHECK();
627 :
628 :
629 0 : return ( L40_var_out );
630 : }
631 :
632 : #ifdef BASOP_NOGLOB
633 0 : Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 )
634 : {
635 : Word40 L40_var_out;
636 :
637 0 : L40_var_out = L40_var1 - L40_var2;
638 :
639 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
640 : if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) )
641 : {
642 : assert( 0 );
643 : L40_var_out = MIN_40;
644 : }
645 : else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) )
646 : {
647 : assert( 0 );
648 : L40_var_out = MAX_40;
649 : }
650 : #else
651 0 : if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) )
652 : {
653 0 : assert( 0 );
654 : L40_var_out = MIN_40;
655 : }
656 0 : else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) )
657 : {
658 0 : assert( 0 );
659 : L40_var_out = MAX_40;
660 : }
661 : #endif
662 :
663 : #ifdef WMOPS
664 : multiCounter[currCounter].L40_sub++;
665 : #endif
666 :
667 : BASOP_CHECK();
668 :
669 :
670 0 : return ( L40_var_out );
671 : }
672 : #endif /* BASOP_NOGLOB */
673 :
674 : /*****************************************************************************
675 : *
676 : * Function Name : L40_abs
677 : *
678 : * Purpose :
679 : *
680 : * Returns the absolute value of L40_var1.
681 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
682 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
683 : *
684 : * Complexity weight : 1
685 : *
686 : * Inputs :
687 : *
688 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
689 : * range : MIN_40 <= L40_var1 <= MAX_40.
690 : *
691 : * Outputs :
692 : *
693 : * none
694 : *
695 : * Return Value :
696 : *
697 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
698 : * the range : 0x00 0000 0000 <= L40_var_out <= MAX_40.
699 : *
700 : *****************************************************************************/
701 0 : Word40 L40_abs( Word40 L40_var1 )
702 : {
703 : Word40 L40_var_out;
704 :
705 0 : if ( L40_var1 < 0 )
706 : {
707 0 : L40_var_out = L40_negate( L40_var1 );
708 : }
709 : else
710 : {
711 0 : L40_var_out = L40_var1;
712 : }
713 :
714 : #ifdef WMOPS
715 : multiCounter[currCounter].L40_abs++;
716 : #endif
717 :
718 0 : return ( L40_var_out );
719 : }
720 :
721 :
722 : /*****************************************************************************
723 : *
724 : * Function Name : L40_max
725 : *
726 : * Purpose :
727 : *
728 : * Compares L40_var1 and L40_var2 and returns the maximum value.
729 : *
730 : *
731 : * Complexity weight : 1
732 : *
733 : * Inputs :
734 : *
735 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
736 : * range : MIN_40 <= L40_var1 <= MAX_40.
737 : *
738 : * L40_var2 40 bit long signed integer (Word40) whose value falls in the
739 : * range : MIN_40 <= L40_var2 <= MAX_40.
740 : *
741 : * Outputs :
742 : *
743 : * none
744 : *
745 : * Return Value :
746 : *
747 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
748 : * the range : MIN_40 <= L40_var_out <= MAX_40.
749 : *
750 : *****************************************************************************/
751 0 : Word40 L40_max( Word40 L40_var1, Word40 L40_var2 )
752 : {
753 : Word40 L40_var_out;
754 :
755 0 : if ( L40_var1 < L40_var2 )
756 0 : L40_var_out = L40_var2;
757 : else
758 0 : L40_var_out = L40_var1;
759 :
760 : #ifdef WMOPS
761 : multiCounter[currCounter].L40_max++;
762 : #endif
763 :
764 0 : return ( L40_var_out );
765 : }
766 :
767 :
768 : /*****************************************************************************
769 : *
770 : * Function Name : L40_min
771 : *
772 : * Purpose :
773 : *
774 : * Compares L40_var1 and L40_var2 and returns the minimum value.
775 : *
776 : *
777 : * Complexity weight : 1
778 : *
779 : * Inputs :
780 : *
781 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
782 : * range : MIN_40 <= L40_var1 <= MAX_40.
783 : *
784 : * L40_var2 40 bit long signed integer (Word40) whose value falls in the
785 : * range : MIN_40 <= L40_var2 <= MAX_40.
786 : *
787 : * Outputs :
788 : *
789 : * none
790 : *
791 : * Return Value :
792 : *
793 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
794 : * the range : MIN_40 <= L40_var_out <= MAX_40.
795 : *
796 : *****************************************************************************/
797 0 : Word40 L40_min( Word40 L40_var1, Word40 L40_var2 )
798 : {
799 : Word40 L40_var_out;
800 :
801 0 : if ( L40_var1 < L40_var2 )
802 0 : L40_var_out = L40_var1;
803 : else
804 0 : L40_var_out = L40_var2;
805 :
806 : #ifdef WMOPS
807 : multiCounter[currCounter].L40_min++;
808 : #endif
809 :
810 0 : return ( L40_var_out );
811 : }
812 :
813 :
814 : /*****************************************************************************
815 : *
816 : * Function Name : L_saturate40
817 : *
818 : * Purpose :
819 : *
820 : * If L40_var1 is greater than MAX_32, returns MAX_32.
821 : * If L40_var1 is lower than MIN_32, returns MIN_32.
822 : * If not, returns L_Extract40( L40_var1).
823 : *
824 : * Complexity weight : 1
825 : *
826 : * Inputs :
827 : *
828 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
829 : * range : MIN_40 <= L40_var1 <= MAX_40.
830 : *
831 : * Outputs :
832 : *
833 : * none
834 : *
835 : * Return Value :
836 : *
837 : * L_var_out 32 bit long signed integer (Word32) whose value falls in
838 : * the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
839 : *
840 : *****************************************************************************/
841 : #ifndef BASOP_NOGLOB
842 : Word32 L_saturate40( Word40 L40_var1 )
843 : #else /* BASOP_NOGLOB */
844 :
845 0 : Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow )
846 : #endif /* BASOP_NOGLOB */
847 : {
848 : Word32 L_var_out;
849 :
850 0 : Word40 UNDER_L40_var2 = ( Word40 ) ~( ( ( (Word40) 1 ) << 31 ) - (Word40) 1 );
851 0 : Word40 OVER_L40_var2 = (Word40) ( ( ( (Word40) 1 ) << 31 ) - (Word40) 1 );
852 :
853 0 : if ( L40_var1 < UNDER_L40_var2 )
854 : {
855 0 : L40_var1 = UNDER_L40_var2;
856 : #ifndef BASOP_NOGLOB
857 : Overflow = 1;
858 : #else /* BASOP_NOGLOB */
859 0 : *Overflow = 1;
860 : #endif /* BASOP_NOGLOB */
861 : }
862 :
863 0 : if ( L40_var1 > OVER_L40_var2 )
864 : {
865 0 : L40_var1 = OVER_L40_var2;
866 : #ifndef BASOP_NOGLOB
867 : Overflow = 1;
868 : #else /* BASOP_NOGLOB */
869 0 : *Overflow = 1;
870 : #endif /* BASOP_NOGLOB */
871 : }
872 :
873 0 : L_var_out = L_Extract40( L40_var1 );
874 :
875 : #ifdef WMOPS
876 : multiCounter[currCounter].L_saturate40++;
877 : #endif
878 :
879 : BASOP_CHECK();
880 :
881 :
882 0 : return ( L_var_out );
883 : }
884 :
885 : #ifdef BASOP_NOGLOB
886 0 : Word32 L_saturate40( Word40 L40_var1 )
887 : {
888 : Word32 L_var_out;
889 :
890 0 : Word40 UNDER_L40_var2 = ( Word40 ) ~( ( ( (Word40) 1 ) << 31 ) - (Word40) 1 );
891 0 : Word40 OVER_L40_var2 = (Word40) ( ( ( (Word40) 1 ) << 31 ) - (Word40) 1 );
892 :
893 0 : if ( L40_var1 < UNDER_L40_var2 )
894 : {
895 0 : L40_var1 = UNDER_L40_var2;
896 0 : assert( 0 );
897 : }
898 :
899 0 : if ( L40_var1 > OVER_L40_var2 )
900 : {
901 0 : L40_var1 = OVER_L40_var2;
902 0 : assert( 0 );
903 : }
904 :
905 0 : L_var_out = L_Extract40( L40_var1 );
906 :
907 : #ifdef WMOPS
908 : multiCounter[currCounter].L_saturate40++;
909 : #endif
910 :
911 : BASOP_CHECK();
912 :
913 :
914 0 : return ( L_var_out );
915 : }
916 : #endif /* BASOP_NOGLOB */
917 :
918 : /*****************************************************************************
919 : *
920 : * Function Name : Mpy_32_16_ss
921 : *
922 : * Purpose :
923 : *
924 : * Multiplies the 2 signed values L_var1 and var2 with saturation control
925 : * on 48-bit. The operation is performed in fractional mode :
926 : * - L_var1 is supposed to be in 1Q31 format.
927 : * - var2 is supposed to be in 1Q15 format.
928 : * - The result is produced in 1Q47 format : L_varout_h points to the
929 : * 32 MSBits while varout_l points to the 16 LSBits.
930 : *
931 : * Complexity weight : 2
932 : *
933 : * Inputs :
934 : *
935 : * L_var1 32 bit long signed integer (Word32) whose value falls in
936 : * the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
937 : *
938 : * var2 16 bit short signed integer (Word16) whose value falls in
939 : * the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
940 : *
941 : * Outputs :
942 : *
943 : * *L_varout_h 32 bit long signed integer (Word32) whose value falls in
944 : * the range : 0x8000 0000 <= L_varout_h <= 0x7fff ffff.
945 : *
946 : * *varout_l 16 bit short unsigned integer (UWord16) whose value falls in
947 : * the range : 0x0000 0000 <= varout_l <= 0x0000 ffff.
948 : *
949 : * Return Value :
950 : *
951 : * none
952 : *
953 : *****************************************************************************/
954 239057676 : void Mpy_32_16_ss( Word32 L_var1, Word16 var2, Word32 *L_varout_h, UWord16 *varout_l )
955 : {
956 : Word16 var1_h;
957 : UWord16 uvar1_l;
958 : Word40 L40_var1;
959 :
960 239057676 : if ( ( L_var1 == (Word32) 0x80000000 ) && ( var2 == (Word16) 0x8000 ) )
961 : {
962 0 : *L_varout_h = 0x7fffffff;
963 0 : *varout_l = (UWord16) 0xffff;
964 : }
965 : else
966 : {
967 239057676 : uvar1_l = extract_l( L_var1 );
968 239057676 : var1_h = extract_h( L_var1 );
969 :
970 : /* Below line can not overflow, so we can use << instead of L40_shl. */
971 239057676 : L40_var1 = ( (Word40) ( (Word32) var2 * (Word32) uvar1_l ) ) << 1;
972 :
973 239057676 : *varout_l = Extract40_L( L40_var1 );
974 :
975 239057676 : L40_var1 = L40_shr( L40_var1, 16 );
976 239057676 : L40_var1 = L40_mac( L40_var1, var2, var1_h );
977 :
978 239057676 : *L_varout_h = L_Extract40( L40_var1 );
979 :
980 : #ifdef WMOPS
981 : multiCounter[currCounter].extract_l--;
982 : multiCounter[currCounter].extract_h--;
983 : multiCounter[currCounter].Extract40_L--;
984 : multiCounter[currCounter].L40_shr--;
985 : multiCounter[currCounter].L40_mac--;
986 : multiCounter[currCounter].L_Extract40--;
987 : #endif
988 : }
989 :
990 : #ifdef WMOPS
991 : multiCounter[currCounter].Mpy_32_16_ss++;
992 : #endif
993 :
994 239057676 : return;
995 : }
996 :
997 :
998 : /*****************************************************************************
999 : *
1000 : * Function Name : Mpy_32_32_ss
1001 : *
1002 : * Purpose :
1003 : *
1004 : * Multiplies the 2 signed values L_var1 and L_var2 with saturation control
1005 : * on 64-bit. The operation is performed in fractional mode :
1006 : * - L_var1 and L_var2 are supposed to be in 1Q31 format.
1007 : * - The result is produced in 1Q63 format : L_varout_h points to the
1008 : * 32 MSBits while L_varout_l points to the 32 LSBits.
1009 : *
1010 : * Complexity weight : 4
1011 : *
1012 : * Inputs :
1013 : *
1014 : * L_var1 32 bit long signed integer (Word32) whose value falls in the
1015 : * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
1016 : *
1017 : * L_var2 32 bit long signed integer (Word32) whose value falls in the
1018 : * range : 0x8000 0000 <= L_var2 <= 0x7fff ffff.
1019 : *
1020 : * Outputs :
1021 : *
1022 : * *L_varout_h 32 bit long signed integer (Word32) whose value falls in
1023 : * the range : 0x8000 0000 <= L_varout_h <= 0x7fff ffff.
1024 : *
1025 : * *L_varout_l 32 bit short unsigned integer (UWord32) whose value falls in
1026 : * the range : 0x0000 0000 <= L_varout_l <= 0xffff ffff.
1027 : *
1028 : *
1029 : * Return Value :
1030 : *
1031 : * none
1032 : *
1033 : *****************************************************************************/
1034 2359603 : void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_varout_l )
1035 : {
1036 : UWord16 uvar1_l, uvar2_l;
1037 : Word16 var1_h, var2_h;
1038 : Word40 L40_var1;
1039 :
1040 2359603 : if ( ( L_var1 == (Word32) 0x80000000 ) && ( L_var2 == (Word32) 0x80000000 ) )
1041 : {
1042 0 : *L_varout_h = 0x7fffffff;
1043 0 : *L_varout_l = (UWord32) 0xffffffff;
1044 : }
1045 : else
1046 : {
1047 :
1048 2359603 : uvar1_l = extract_l( L_var1 );
1049 2359603 : var1_h = extract_h( L_var1 );
1050 2359603 : uvar2_l = extract_l( L_var2 );
1051 2359603 : var2_h = extract_h( L_var2 );
1052 :
1053 : /* Below line can not overflow, so we can use << instead of L40_shl. */
1054 2359603 : L40_var1 = ( (Word40) ( (UWord32) uvar2_l * (UWord32) uvar1_l ) ) << 1;
1055 :
1056 2359603 : *L_varout_l = 0x0000ffff & L_Extract40( L40_var1 );
1057 :
1058 2359603 : L40_var1 = L40_shr( L40_var1, 16 );
1059 2359603 : L40_var1 = L40_add( L40_var1, ( (Word40) ( (Word32) var2_h * (Word32) uvar1_l ) ) << 1 );
1060 2359603 : L40_var1 = L40_add( L40_var1, ( (Word40) ( (Word32) var1_h * (Word32) uvar2_l ) ) << 1 );
1061 2359603 : *L_varout_l |= ( L_Extract40( L40_var1 ) ) << 16;
1062 :
1063 2359603 : L40_var1 = L40_shr( L40_var1, 16 );
1064 2359603 : L40_var1 = L40_mac( L40_var1, var1_h, var2_h );
1065 :
1066 2359603 : *L_varout_h = L_Extract40( L40_var1 );
1067 :
1068 : #ifdef WMOPS
1069 : multiCounter[currCounter].extract_l -= 2;
1070 : multiCounter[currCounter].extract_h -= 2;
1071 : multiCounter[currCounter].L_Extract40 -= 3;
1072 : multiCounter[currCounter].L40_shr -= 2;
1073 : multiCounter[currCounter].L40_add -= 2;
1074 : multiCounter[currCounter].L40_mac--;
1075 : #endif
1076 : }
1077 :
1078 : #ifdef WMOPS
1079 : multiCounter[currCounter].Mpy_32_32_ss++;
1080 : #endif
1081 :
1082 2359603 : return;
1083 : }
1084 :
1085 :
1086 : /*****************************************************************************
1087 : *
1088 : * Function Name : L40_lshl
1089 : *
1090 : * Purpose :
1091 : *
1092 : * Logically shifts left L40_var1 by var2 positions.
1093 : * - If var2 is negative, L40_var1 is shifted to the LSBits by (-var2)
1094 : * positions with insertion of 0 at the MSBit.
1095 : * - If var2 is positive, L40_var1 is shifted to the MSBits by (var2)
1096 : * positions.
1097 : *
1098 : * Complexity weight : 1
1099 : *
1100 : * Inputs :
1101 : *
1102 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1103 : * range : MIN_40 <= L40_var1 <= MAX_40.
1104 : *
1105 : * var2 16 bit short signed integer (Word16) whose value falls in
1106 : * the range : MIN_16 <= var2 <= MAX_16.
1107 : *
1108 : * Outputs :
1109 : *
1110 : * none
1111 : *
1112 : * Return Value :
1113 : *
1114 : * L_var_out 32 bit long unsigned integer (UWord32) whose value falls in
1115 : * the range : MIN_40 <= L40_var_out <= MAX_40.
1116 : *
1117 : *****************************************************************************/
1118 0 : Word40 L40_lshl( Word40 L40_var1, Word16 var2 )
1119 : {
1120 : Word40 L40_var_out;
1121 :
1122 0 : if ( var2 <= 0 )
1123 : {
1124 0 : var2 = -var2;
1125 0 : L40_var_out = L40_lshr( L40_var1, var2 );
1126 : #ifdef WMOPS
1127 : multiCounter[currCounter].L40_lshr--;
1128 : #endif
1129 : }
1130 : else
1131 : {
1132 0 : if ( var2 >= 40 )
1133 0 : L40_var_out = 0x0000000000;
1134 : else
1135 : {
1136 0 : L40_var_out = L40_var1 << var2;
1137 : }
1138 0 : L40_var_out = L40_set( L40_var_out );
1139 : }
1140 :
1141 : #ifdef WMOPS
1142 : multiCounter[currCounter].L40_lshl++;
1143 : #endif
1144 :
1145 : BASOP_CHECK();
1146 :
1147 :
1148 0 : return ( L40_var_out );
1149 : }
1150 :
1151 :
1152 : /*****************************************************************************
1153 : *
1154 : * Function Name : L40_lshr
1155 : *
1156 : * Purpose :
1157 : *
1158 : * Logically shifts right L40_var1 by var2 positions.
1159 : * - If var2 is positive, L40_var1 is shifted to the LSBits by (var2)
1160 : * positions with insertion of 0 at the MSBit.
1161 : * - If var2 is negative, L40_var1 is shifted to the MSBits by (-var2)
1162 : * positions.
1163 : *
1164 : * Complexity weight : 1
1165 : *
1166 : * Inputs :
1167 : *
1168 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1169 : * range : MIN_40 <= L40_var1 <= MAX_40.
1170 : *
1171 : * var2 16 bit short signed integer (Word16) whose value falls in
1172 : * the range : MIN_16 <= var2 <= MAX_16.
1173 : *
1174 : * Outputs :
1175 : *
1176 : * none
1177 : *
1178 : * Return Value :
1179 : *
1180 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
1181 : * the range : MIN_40 <= L40_var_out <= MAX_40.
1182 : *
1183 : *****************************************************************************/
1184 0 : Word40 L40_lshr( Word40 L40_var1, Word16 var2 )
1185 : {
1186 : Word40 L40_var_out;
1187 :
1188 0 : if ( var2 < 0 )
1189 : {
1190 0 : var2 = -var2;
1191 0 : L40_var_out = L40_lshl( L40_var1, var2 );
1192 : #ifdef WMOPS
1193 : multiCounter[currCounter].L40_lshl--;
1194 : #endif
1195 : }
1196 : else
1197 : {
1198 0 : if ( var2 >= 40 )
1199 0 : L40_var_out = 0x0000000000;
1200 : else
1201 : {
1202 : #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 )
1203 : L40_var_out = ( L40_var1 & 0xffffffffff ) >> var2;
1204 : #else
1205 0 : L40_var_out = ( L40_var1 & 0xffffffffffLL ) >> var2;
1206 : #endif
1207 : }
1208 : }
1209 :
1210 : #ifdef WMOPS
1211 : multiCounter[currCounter].L40_lshr++;
1212 : #endif
1213 :
1214 : BASOP_CHECK();
1215 :
1216 :
1217 0 : return ( L40_var_out );
1218 : }
1219 :
1220 :
1221 : /*****************************************************************************
1222 : *
1223 : * Function Name : norm_L40
1224 : *
1225 : * Purpose :
1226 : *
1227 : * Produces the number of left shifts needed to normalize in 32 bit format
1228 : * the 40 bit variable L40_var1. This returned value can be used to scale
1229 : * L_40_var1 into the following intervals :
1230 : * - [(MAX_32+1)/2 .. MAX_32 ] for positive values.
1231 : * - [ MIN_32 .. (MIN_32/2)+1 ] for negative values.
1232 : * - [ 0 .. 0 ] for null values.
1233 : * In order to normalize the result, the following operation must be done :
1234 : * normelized_L40_var1 = L40_shl( L40_var1, norm_L40( L40_var1))
1235 : *
1236 : * Complexity weight : 1
1237 : *
1238 : * Inputs :
1239 : *
1240 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1241 : * range : MIN_40 <= L40_var1 <= MAX_40.
1242 : *
1243 : * Outputs :
1244 : *
1245 : * none
1246 : *
1247 : * Return Value :
1248 : *
1249 : * var_out 16 bit short signed integer (Word16) whose value falls in
1250 : * the range : -8 <= var_out <= 31.
1251 : *
1252 : *****************************************************************************/
1253 0 : Word16 norm_L40( Word40 L40_var1 )
1254 : {
1255 : Word16 var_out;
1256 :
1257 0 : var_out = 0;
1258 :
1259 0 : if ( L40_var1 != 0 )
1260 : {
1261 0 : while ( ( L40_var1 > (Word32) 0x80000000L ) && ( L40_var1 < (Word32) 0x7fffffffL ) )
1262 : {
1263 :
1264 0 : L40_var1 = L40_shl( L40_var1, 1 );
1265 0 : var_out++;
1266 : }
1267 :
1268 0 : while ( ( L40_var1 < (Word32) 0x80000000L ) || ( L40_var1 > (Word32) 0x7fffffffL ) )
1269 : {
1270 :
1271 0 : L40_var1 = L40_shl( L40_var1, -1 );
1272 0 : var_out--;
1273 : }
1274 : }
1275 :
1276 :
1277 0 : return ( var_out );
1278 : }
1279 :
1280 :
1281 : /*****************************************************************************
1282 : *
1283 : * Function Name : L40_shr_r
1284 : *
1285 : * Purpose :
1286 : *
1287 : * Arithmetically shifts right L40_var1 by var2 positions and rounds the
1288 : * result. It is equivalent to L40_shr( L40_var1, var2) except that if the
1289 : * last bit shifted out to the LSBit is 1, then the shifted result is
1290 : * incremented by 1.
1291 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
1292 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
1293 : *
1294 : * Complexity weight : 3
1295 : *
1296 : * Inputs :
1297 : *
1298 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1299 : * range : MIN_40 <= L40_var1 <= MAX_40.
1300 : *
1301 : * var2 16 bit short signed integer (Word16) whose value falls in
1302 : * the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
1303 : *
1304 : * Outputs :
1305 : *
1306 : * none
1307 : *
1308 : * Return Value :
1309 : *
1310 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
1311 : * the range : MIN_40 <= L40_var_out <= MAX_40.
1312 : *
1313 : *****************************************************************************/
1314 0 : Word40 L40_shr_r( Word40 L40_var1, Word16 var2 )
1315 : {
1316 : Word40 L40_var_out;
1317 :
1318 0 : if ( var2 > 39 )
1319 : {
1320 0 : L40_var_out = 0;
1321 : }
1322 : else
1323 : {
1324 0 : L40_var_out = L40_shr( L40_var1, var2 );
1325 :
1326 0 : if ( var2 > 0 )
1327 : {
1328 0 : if ( ( L40_var1 & ( (Word40) 1 << ( var2 - 1 ) ) ) != 0 )
1329 : {
1330 : /* below line can not generate overflows on 40-bit */
1331 0 : L40_var_out++;
1332 : }
1333 : }
1334 : }
1335 :
1336 : BASOP_CHECK();
1337 :
1338 :
1339 0 : return ( L40_var_out );
1340 : }
1341 :
1342 :
1343 : /*****************************************************************************
1344 : *
1345 : * Function Name : L40_shl_r
1346 : *
1347 : * Purpose :
1348 : *
1349 : * Arithmetically shifts left L40_var1 by var2 positions and rounds the
1350 : * result. It is equivalent to L40_shl( L40_var1, var2) except if var2 is
1351 : * negative. In that case, it does the same as
1352 : * L40_shr_r( L40_var1, (-var2)).
1353 : * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit.
1354 : * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit.
1355 : *
1356 : * Complexity weight : 3
1357 : *
1358 : * Inputs :
1359 : *
1360 : * L40_var1 40 bit long signed integer (Word40) whose value falls in the
1361 : * range : MIN_40 <= L40_var1 <= MAX_40.
1362 : *
1363 : * var2 16 bit short signed integer (Word16) whose value falls in
1364 : * the range : 0xffff 8000 <= var2 <= 0x0000 7fff.
1365 : *
1366 : * Outputs :
1367 : *
1368 : * none
1369 : *
1370 : * Return Value :
1371 : *
1372 : * L40_var_out 40 bit long signed integer (Word40) whose value falls in
1373 : * the range : MIN_40 <= L40_var_out <= MAX_40.
1374 : *
1375 : *****************************************************************************/
1376 0 : Word40 L40_shl_r( Word40 L40_var1, Word16 var2 )
1377 : {
1378 : Word40 L40_var_out;
1379 :
1380 0 : if ( var2 >= 0 )
1381 : {
1382 0 : L40_var_out = L40_shl( L40_var1, var2 );
1383 : }
1384 : else
1385 : {
1386 0 : var2 = -var2;
1387 0 : L40_var_out = L40_shr_r( L40_var1, var2 );
1388 : }
1389 :
1390 :
1391 0 : return ( L40_var_out );
1392 : }
1393 :
1394 :
1395 : #undef WMC_TOOL_SKIP
|