basic_op.h revision fa9597bc0007f6a1d6704f047e7d94bb195c8a68
1/*
2 ** Copyright 2003-2010, VisualOn, Inc.
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 **     http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16/*******************************************************************************
17	File:		basicop2.h
18
19	Content:	Constants , Globals and Basic arithmetic operators.
20
21*******************************************************************************/
22
23#ifndef __BASIC_OP_H
24#define __BASIC_OP_H
25
26#include "typedef.h"
27
28#define MAX_32 (Word32)0x7fffffffL
29#define MIN_32 (Word32)0x80000000L
30
31#define MAX_16 (Word16)0x7fff
32#define MIN_16 (Word16)0x8000
33#define ABS(a)	((a) >= 0) ? (a) : (-(a))
34
35/* Short abs,           1   */
36#define abs_s(x)       ((Word16)(((x) != MIN_16) ? (((x) >= 0) ? (x) : (-(x))) : MAX_16))
37
38/* 16 bit var1 -> MSB,     2 */
39#define L_deposit_h(x) (((Word32)(x)) << 16)
40
41
42/* 16 bit var1 -> LSB,     2 */
43#define L_deposit_l(x) ((Word32)(x))
44
45
46/* Long abs,              3  */
47#define L_abs(x) (((x) != MIN_32) ? (((x) >= 0) ? (x) : (-(x))) : MAX_32)
48
49
50/* Short negate,        1   */
51#define negate(var1) ((Word16)(((var1) == MIN_16) ? MAX_16 : (-(var1))))
52
53
54/* Long negate,     2 */
55#define L_negate(L_var1) (((L_var1) == (MIN_32)) ? (MAX_32) : (-(L_var1)))
56
57
58#define MULHIGH(A,B) (int)(((Word64)(A)*(Word64)(B)) >> 32)
59#define fixmul(a, b) (int)((((Word64)(a)*(Word64)(b)) >> 32) << 1)
60
61
62#if  (SATRUATE_IS_INLINE)
63__inline Word16 saturate(Word32 L_var1);
64#else
65Word16 saturate(Word32 L_var1);
66#endif
67
68/* Short shift left,    1   */
69#if (SHL_IS_INLINE)
70__inline Word16 shl (Word16 var1, Word16 var2);
71#else
72Word16 shl (Word16 var1, Word16 var2);
73#endif
74
75/* Short shift right,   1   */
76#if (SHR_IS_INLINE)
77__inline Word16 shr (Word16 var1, Word16 var2);
78#else
79Word16 shr (Word16 var1, Word16 var2);
80#endif
81
82#if (L_MULT_IS_INLINE)
83__inline Word32 L_mult(Word16 var1, Word16 var2);
84#else
85Word32 L_mult(Word16 var1, Word16 var2);
86#endif
87
88/* Msu,  1  */
89#if (L_MSU_IS_INLINE)
90__inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);
91#else
92Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);
93#endif
94
95/* Long sub,        2 */
96#if (L_SUB_IS_INLINE)
97__inline Word32 L_sub(Word32 L_var1, Word32 L_var2);
98#else
99Word32 L_sub(Word32 L_var1, Word32 L_var2);
100#endif
101
102/* Long shift left, 2 */
103#if (L_SHL_IS_INLINE)
104__inline Word32 L_shl (Word32 L_var1, Word16 var2);
105#else
106Word32 L_shl (Word32 L_var1, Word16 var2);
107#endif
108
109/* Long shift right, 2*/
110#if (L_SHR_IS_INLINE)
111__inline Word32 L_shr (Word32 L_var1, Word16 var2);
112#else
113Word32 L_shr (Word32 L_var1, Word16 var2);
114#endif
115
116/* Short add,           1   */
117#if (ADD_IS_INLINE)
118__inline Word16 add (Word16 var1, Word16 var2);
119#else
120Word16 add (Word16 var1, Word16 var2);
121#endif
122
123/* Short sub,           1   */
124#if (SUB_IS_INLINE)
125__inline Word16 sub(Word16 var1, Word16 var2);
126#else
127Word16 sub(Word16 var1, Word16 var2);
128#endif
129
130/* Short division,       18  */
131#if (DIV_S_IS_INLINE)
132__inline Word16 div_s (Word16 var1, Word16 var2);
133#else
134Word16 div_s (Word16 var1, Word16 var2);
135#endif
136
137/* Short mult,          1   */
138#if (MULT_IS_INLINE)
139__inline Word16 mult (Word16 var1, Word16 var2);
140#else
141Word16 mult (Word16 var1, Word16 var2);
142#endif
143
144/* Short norm,           15  */
145#if (NORM_S_IS_INLINE)
146__inline Word16 norm_s (Word16 var1);
147#else
148Word16 norm_s (Word16 var1);
149#endif
150
151/* Long norm,            30  */
152#if (NORM_L_IS_INLINE)
153__inline Word16 norm_l (Word32 L_var1);
154#else
155Word16 norm_l (Word32 L_var1);
156#endif
157
158/* Round,               1   */
159#if (ROUND_IS_INLINE)
160__inline Word16 round16(Word32 L_var1);
161#else
162Word16 round16(Word32 L_var1);
163#endif
164
165/* Mac,  1  */
166#if (L_MAC_IS_INLINE)
167__inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);
168#else
169Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);
170#endif
171
172#if (L_ADD_IS_INLINE)
173__inline Word32 L_add (Word32 L_var1, Word32 L_var2);
174#else
175Word32 L_add (Word32 L_var1, Word32 L_var2);
176#endif
177
178/* Extract high,        1   */
179#if (EXTRACT_H_IS_INLINE)
180__inline Word16 extract_h (Word32 L_var1);
181#else
182Word16 extract_h (Word32 L_var1);
183#endif
184
185/* Extract low,         1   */
186#if (EXTRACT_L_IS_INLINE)
187__inline Word16 extract_l(Word32 L_var1);
188#else
189Word16 extract_l(Word32 L_var1);
190#endif
191
192/* Mult with round, 2 */
193#if (MULT_R_IS_INLINE)
194__inline Word16 mult_r(Word16 var1, Word16 var2);
195#else
196Word16 mult_r(Word16 var1, Word16 var2);
197#endif
198
199/* Shift right with round, 2           */
200#if (SHR_R_IS_INLINE)
201__inline Word16 shr_r (Word16 var1, Word16 var2);
202#else
203Word16 shr_r (Word16 var1, Word16 var2);
204#endif
205
206/* Mac with rounding,2 */
207#if (MAC_R_IS_INLINE)
208__inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2);
209#else
210Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2);
211#endif
212
213/* Msu with rounding,2 */
214#if (MSU_R_IS_INLINE)
215__inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2);
216#else
217Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2);
218#endif
219
220/* Long shift right with round,  3             */
221#if (L_SHR_R_IS_INLINE)
222__inline Word32 L_shr_r (Word32 L_var1, Word16 var2);
223#else
224Word32 L_shr_r (Word32 L_var1, Word16 var2);
225#endif
226
227#if ARMV4_INASM
228__inline Word32 ASM_L_shr(Word32 L_var1, Word16 var2)
229{
230	return L_var1 >> var2;
231}
232
233__inline Word32 ASM_L_shl(Word32 L_var1, Word16 var2)
234{
235	Word32 result;
236	asm (
237		"MOV	%[result], %[L_var1], ASL %[var2] \n"
238		"TEQ	%[L_var1], %[result], ASR %[var2]\n"
239		"EORNE  %[result], %[mask], %[L_var1], ASR #31\n"
240		:[result]"=&r"(result)
241		:[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fffffff)
242		);
243	return result;
244}
245
246__inline Word32 ASM_shr(Word32 L_var1, Word16 var2)
247{
248	Word32 result;
249	asm (
250		"CMP	%[var2], #15\n"
251		"MOVLT	%[result], %[L_var1], ASR %[var2]\n"
252		"MOVGE	%[result], %[L_var1], ASR #15\n"
253		:[result]"=r"(result)
254		:[L_var1]"r"(L_var1), [var2]"r"(var2)
255		);
256	return result;
257}
258
259__inline Word32 ASM_shl(Word32 L_var1, Word16 var2)
260{
261#if ARMV6_SAT
262	Word32 result;
263	asm (
264		"CMP	%[var2], #16\n"
265		"MOVLT  %[result], %[L_var1], ASL %[var2]\n"
266		"MOVGE  %[result], %[L_var1], ASL #16\n"
267		"SSAT   %[result], #16, %[result]\n"
268		:[result]"=r"(result)
269		:[L_var1]"r"(L_var1), [var2]"r"(var2)
270		);
271	return result;
272#else
273	Word32 result;
274	Word32 tmp;
275	asm (
276		"CMP	%[var2], #16\n"
277		"MOVLT  %[result], %[L_var1], ASL %[var2]\n"
278		"MOVGE  %[result], %[L_var1], ASL #16\n"
279        "MOV    %[tmp], %[result], ASR #15\n"
280        "TEQ    %[tmp], %[result], ASR #31 \n"
281        "EORNE  %[result], %[mask], %[result],ASR #31"
282		:[result]"=&r"(result), [tmp]"=&r"(tmp)
283		:[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fff)
284		);
285	return result;
286#endif
287}
288#endif
289
290/*___________________________________________________________________________
291 |                                                                           |
292 |   definitions for inline basic arithmetic operators                       |
293 |___________________________________________________________________________|
294*/
295#if (SATRUATE_IS_INLINE)
296__inline Word16 saturate(Word32 L_var1)
297{
298#if ARMV6_SAT
299    Word16 result;
300	asm (
301		"SSAT %[result], #16, %[L_var1]"
302		: [result]"=r"(result)
303		: [L_var1]"r"(L_var1)
304		);
305	return result;
306#elif ARMV5TE_SAT
307	Word16 result;
308	Word32 tmp;
309	asm volatile (
310		"MOV	%[tmp], %[L_var1],ASR#15\n"
311		"TEQ	%[tmp], %[L_var1],ASR#31\n"
312		"EORNE	%[result], %[mask],%[L_var1],ASR#31\n"
313		"MOVEQ	%[result], %[L_var1]\n"
314		:[result]"=&r"(result), [tmp]"=&r"(tmp)
315		:[L_var1]"r"(L_var1), [mask]"r"(0x7fff)
316	);
317
318	return result;
319#else
320    Word16 var_out;
321
322    //var_out = (L_var1 > (Word32)0X00007fffL) ? (MAX_16) : ((L_var1 < (Word32)0xffff8000L) ? (MIN_16) : ((Word16)L_var1));
323
324    if (L_var1 > 0X00007fffL)
325    {
326        var_out = MAX_16;
327    }
328    else if (L_var1 < (Word32) 0xffff8000L)
329    {
330        var_out = MIN_16;
331    }
332    else
333    {
334        var_out = extract_l(L_var1);
335    }
336
337    return (var_out);
338#endif
339}
340#endif
341
342/* Short shift left,    1   */
343#if (SHL_IS_INLINE)
344__inline Word16 shl (Word16 var1, Word16 var2)
345{
346#if ARMV5TE_SHL
347	if(var2>=0)
348	{
349		return ASM_shl( var1, var2);
350	}
351	else
352	{
353		return ASM_shr( var1, -var2);
354	}
355#else
356    Word16 var_out;
357    Word32 result;
358
359    if (var2 < 0)
360    {
361        var_out = shr (var1, (Word16)-var2);
362    }
363    else
364    {
365        result = (Word32) var1 *((Word32) 1 << var2);
366
367        if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
368        {
369            var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
370        }
371        else
372        {
373            var_out = extract_l(result);
374        }
375    }
376    return (var_out);
377#endif
378}
379#endif
380
381/* Short shift right,   1   */
382#if (SHR_IS_INLINE)
383__inline Word16 shr (Word16 var1, Word16 var2)
384{
385#if ARMV5TE_SHR
386	if(var2>=0)
387	{
388		return  ASM_shr( var1, var2);
389	}
390	else
391	{
392		return  ASM_shl( var1, -var2);
393	}
394#else
395    Word16 var_out;
396
397    if (var2 < 0)
398    {
399        var_out = shl (var1, (Word16)-var2);
400    }
401    else
402    {
403        if (var2 >= 15)
404        {
405            var_out = (Word16)((var1 < 0) ? -1 : 0);
406        }
407        else
408        {
409            if (var1 < 0)
410            {
411                var_out = (Word16)(~((~var1) >> var2));
412            }
413            else
414            {
415                var_out = (Word16)(var1 >> var2);
416            }
417        }
418    }
419
420    return (var_out);
421#endif
422}
423#endif
424
425
426#if (L_MULT_IS_INLINE)
427__inline Word32 L_mult(Word16 var1, Word16 var2)
428{
429#if ARMV5TE_L_MULT
430	Word32 result;
431	asm (
432		"SMULBB %[result], %[var1], %[var2] \n"
433		"QADD %[result], %[result], %[result] \n"
434		:[result]"=r"(result)
435		:[var1]"r"(var1), [var2]"r"(var2)
436		);
437	return result;
438#else
439    Word32 L_var_out;
440
441    L_var_out = (Word32) var1 *(Word32) var2;
442
443    if (L_var_out != (Word32) 0x40000000L)
444    {
445        L_var_out <<= 1;
446    }
447    else
448    {
449        L_var_out = MAX_32;
450    }
451    return (L_var_out);
452#endif
453}
454#endif
455
456#if (L_MSU_IS_INLINE)
457__inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
458{
459#if ARMV5TE_L_MSU
460	Word32 result;
461	asm (
462		"SMULBB %[result], %[var1], %[var2] \n"
463		"QADD %[result], %[result], %[result] \n"
464		"QSUB %[result], %[L_var3], %[result]\n"
465		:[result]"=&r"(result)
466		:[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
467		);
468	return result;
469#else
470    Word32 L_var_out;
471    Word32 L_product;
472
473    L_product = L_mult(var1, var2);
474    L_var_out = L_sub(L_var3, L_product);
475    return (L_var_out);
476#endif
477}
478#endif
479
480#if (L_SUB_IS_INLINE)
481__inline Word32 L_sub(Word32 L_var1, Word32 L_var2)
482{
483#if ARMV5TE_L_SUB
484	Word32 result;
485	asm (
486		"QSUB %[result], %[L_var1], %[L_var2]\n"
487		:[result]"=r"(result)
488		:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
489		);
490	return result;
491#else
492    Word32 L_var_out;
493
494    L_var_out = L_var1 - L_var2;
495
496    if (((L_var1 ^ L_var2) & MIN_32) != 0)
497    {
498        if ((L_var_out ^ L_var1) & MIN_32)
499        {
500            L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
501        }
502    }
503
504    return (L_var_out);
505#endif
506}
507#endif
508
509#if (L_SHL_IS_INLINE)
510__inline Word32 L_shl(Word32 L_var1, Word16 var2)
511{
512#if ARMV5TE_L_SHL
513    if(var2>=0)
514    {
515        return  ASM_L_shl( L_var1, var2);
516    }
517    else
518    {
519        return  ASM_L_shr( L_var1, -var2);
520    }
521#else
522    Word32 L_var_out = 0L;
523
524    if (var2 <= 0)
525    {
526        L_var1 = L_shr(L_var1, (Word16)-var2);
527    }
528    else
529    {
530        for (; var2 > 0; var2--)
531        {
532            if (L_var1 > (Word32) 0X3fffffffL)
533            {
534                return MAX_32;
535            }
536            else
537            {
538                if (L_var1 < (Word32) 0xc0000000L)
539                {
540                    return MIN_32;
541                }
542            }
543            L_var1 <<= 1;
544            L_var_out = L_var1;
545        }
546    }
547    return (L_var1);
548#endif
549}
550#endif
551
552#if (L_SHR_IS_INLINE)
553__inline Word32 L_shr (Word32 L_var1, Word16 var2)
554{
555#if ARMV5TE_L_SHR
556	if(var2>=0)
557	{
558		return ASM_L_shr( L_var1, var2);
559	}
560	else
561	{
562		return ASM_L_shl( L_var1, -var2);
563	}
564#else
565    Word32 L_var_out;
566
567    if (var2 < 0)
568    {
569        L_var_out = L_shl (L_var1, (Word16)-var2);
570    }
571    else
572    {
573        if (var2 >= 31)
574        {
575            L_var_out = (L_var1 < 0L) ? -1 : 0;
576        }
577        else
578        {
579            if (L_var1 < 0)
580            {
581                L_var_out = ~((~L_var1) >> var2);
582            }
583            else
584            {
585                L_var_out = L_var1 >> var2;
586            }
587        }
588    }
589    return (L_var_out);
590#endif
591}
592#endif
593
594/* Short add,           1   */
595#if (ADD_IS_INLINE)
596__inline Word16 add (Word16 var1, Word16 var2)
597{
598#if ARMV5TE_ADD
599	Word32 result;
600	Word32 tmp;
601	asm (
602		"ADD  %[result], %[var1], %[var2] \n"
603		"MOV  %[tmp], %[result], ASR #15 \n"
604		"TEQ  %[tmp], %[result], ASR #31 \n"
605		"EORNE %[result], %[mask], %[result], ASR #31"
606		:[result]"=&r"(result), [tmp]"=&r"(tmp)
607		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
608		);
609	return result;
610#else
611    Word16 var_out;
612    Word32 L_sum;
613
614    L_sum = (Word32) var1 + var2;
615    var_out = saturate(L_sum);
616
617    return (var_out);
618#endif
619}
620#endif
621
622/* Short sub,           1   */
623#if (SUB_IS_INLINE)
624__inline Word16 sub(Word16 var1, Word16 var2)
625{
626#if ARMV5TE_SUB
627	Word32 result;
628	Word32 tmp;
629	asm (
630		"SUB   %[result], %[var1], %[var2] \n"
631		"MOV   %[tmp], %[var1], ASR #15 \n"
632		"TEQ   %[tmp], %[var1], ASR #31 \n"
633		"EORNE %[result], %[mask], %[result], ASR #31 \n"
634		:[result]"=&r"(result), [tmp]"=&r"(tmp)
635		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
636		);
637	return result;
638#else
639    Word16 var_out;
640    Word32 L_diff;
641
642    L_diff = (Word32) var1 - var2;
643    var_out = saturate(L_diff);
644
645    return (var_out);
646#endif
647}
648#endif
649
650/* Short division,       18  */
651#if (DIV_S_IS_INLINE)
652__inline Word16 div_s (Word16 var1, Word16 var2)
653{
654    Word16 var_out = 0;
655    Word16 iteration;
656    Word32 L_num;
657    Word32 L_denom;
658
659    var_out = MAX_16;
660    if (var1!= var2)//var1!= var2
661    {
662    	var_out = 0;
663    	L_num = (Word32) var1;
664
665    	L_denom = (Word32) var2;
666
667		//return (L_num<<15)/var2;
668
669    	for (iteration = 0; iteration < 15; iteration++)
670    	{
671    		var_out <<= 1;
672    		L_num <<= 1;
673
674    		if (L_num >= L_denom)
675    		{
676    			L_num -= L_denom;
677    			var_out++;
678    		}
679    	}
680    }
681    return (var_out);
682}
683#endif
684
685/* Short mult,          1   */
686#if (MULT_IS_INLINE)
687__inline Word16 mult (Word16 var1, Word16 var2)
688{
689#if ARMV5TE_MULT && ARMV6_SAT
690	Word32 result;
691	asm (
692		"SMULBB %[result], %[var1], %[var2] \n"
693		"SSAT   %[result], #16, %[result], ASR #15 \n"
694		:[result]"=r"(result)
695		:[var1]"r"(var1), [var2]"r"(var2)
696		);
697	return result;
698#elif ARMV5TE_MULT
699	Word32 result, tmp;
700	asm (
701		"SMULBB %[tmp], %[var1], %[var2] \n"
702		"MOV	%[result], %[tmp], ASR #15\n"
703		"MOV	%[tmp], %[result], ASR #15\n"
704		"TEQ	%[tmp], %[result], ASR #31\n"
705		"EORNE  %[result], %[mask], %[result], ASR #31 \n"
706		:[result]"=&r"(result), [tmp]"=&r"(tmp)
707		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
708		);
709	return result;
710#else
711    Word16 var_out;
712    Word32 L_product;
713
714    L_product = (Word32) var1 *(Word32) var2;
715    L_product = (L_product & (Word32) 0xffff8000L) >> 15;
716    if (L_product & (Word32) 0x00010000L)
717        L_product = L_product | (Word32) 0xffff0000L;
718    var_out = saturate(L_product);
719
720    return (var_out);
721#endif
722}
723#endif
724
725
726/* Short norm,           15  */
727#if (NORM_S_IS_INLINE)
728__inline Word16 norm_s (Word16 var1)
729{
730#if ARMV5TE_NORM_S
731	Word16 result;
732	Word32 tmp;
733	asm (
734		"RSBS  %[tmp], %[var1], #0 \n"
735		"CLZLT %[result], %[var1]\n"
736		"CLZGT %[result], %[tmp]\n"
737		"SUBNE %[result], %[result], #17\n"
738		"MOVEQ %[result], #0\n"
739		"CMP   %[var1], #-1\n"
740		"MOVEQ %[result], #15\n"
741		:[result]"=&r"(result), [tmp]"=&r"(tmp)
742		:[var1]"r"(var1)
743		);
744	return result;
745#else
746    Word16 var_out;
747
748    if (var1 == 0)
749    {
750        var_out = 0;
751    }
752    else
753    {
754        if (var1 == -1)
755        {
756            var_out = 15;
757        }
758        else
759        {
760            if (var1 < 0)
761            {
762                var1 = (Word16)~var1;
763            }
764            for (var_out = 0; var1 < 0x4000; var_out++)
765            {
766                var1 <<= 1;
767            }
768        }
769    }
770    return (var_out);
771#endif
772}
773#endif
774
775/* Long norm,            30  */
776#if (NORM_L_IS_INLINE)
777__inline Word16 norm_l (Word32 L_var1)
778{
779#if ARMV5TE_NORM_L
780	Word16 result;
781	asm volatile(
782		"CMP    %[L_var1], #0\n"
783		"CLZNE  %[result], %[L_var1]\n"
784		"SUBNE  %[result], %[result], #1\n"
785		"MOVEQ  %[result], #0\n"
786		:[result]"=r"(result)
787		:[L_var1]"r"(L_var1)
788		);
789	return result;
790#else
791    //Word16 var_out;
792
793    //if (L_var1 == 0)
794    //{
795    //    var_out = 0;
796    //}
797    //else
798    //{
799    //    if (L_var1 == (Word32) 0xffffffffL)
800    //    {
801    //        var_out = 31;
802    //    }
803    //    else
804    //    {
805    //        if (L_var1 < 0)
806    //        {
807    //            L_var1 = ~L_var1;
808    //        }
809    //        for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
810    //        {
811    //            L_var1 <<= 1;
812    //        }
813    //    }
814    //}
815    //return (var_out);
816  Word16 a16;
817  Word16 r = 0 ;
818
819
820  if ( L_var1 < 0 ) {
821    L_var1 = ~L_var1;
822  }
823
824  if (0 == (L_var1 & 0x7fff8000)) {
825    a16 = extract_l(L_var1);
826    r += 16;
827
828    if (0 == (a16 & 0x7f80)) {
829      r += 8;
830
831      if (0 == (a16 & 0x0078)) {
832        r += 4;
833
834        if (0 == (a16 & 0x0006)) {
835          r += 2;
836
837          if (0 == (a16 & 0x0001)) {
838            r += 1;
839          }
840        }
841        else {
842
843          if (0 == (a16 & 0x0004)) {
844            r += 1;
845          }
846        }
847      }
848      else {
849
850        if (0 == (a16 & 0x0060)) {
851          r += 2;
852
853          if (0 == (a16 & 0x0010)) {
854            r += 1;
855          }
856        }
857        else {
858
859          if (0 == (a16 & 0x0040)) {
860            r += 1;
861          }
862        }
863      }
864    }
865    else {
866
867      if (0 == (a16 & 0x7800)) {
868        r += 4;
869
870        if (0 == (a16 & 0x0600)) {
871          r += 2;
872
873          if (0 == (a16 & 0x0100)) {
874            r += 1;
875          }
876        }
877        else {
878
879          if (0 == (a16 & 0x0400)) {
880            r += 1;
881          }
882        }
883      }
884      else {
885
886        if (0 == (a16 & 0x6000)) {
887          r += 2;
888
889          if (0 == (a16 & 0x1000)) {
890            r += 1;
891          }
892        }
893        else {
894
895          if (0 == (a16 & 0x4000)) {
896            r += 1;
897          }
898        }
899      }
900    }
901  }
902  else {
903    a16 = extract_h(L_var1);
904
905    if (0 == (a16 & 0x7f80)) {
906      r += 8;
907
908      if (0 == (a16 & 0x0078)) {
909        r += 4 ;
910
911        if (0 == (a16 & 0x0006)) {
912          r += 2;
913
914          if (0 == (a16 & 0x0001)) {
915            r += 1;
916          }
917        }
918        else {
919
920          if (0 == (a16 & 0x0004)) {
921            r += 1;
922          }
923        }
924      }
925      else {
926
927        if (0 == (a16 & 0x0060)) {
928          r += 2;
929
930          if (0 == (a16 & 0x0010)) {
931            r += 1;
932          }
933        }
934        else {
935
936          if (0 == (a16 & 0x0040)) {
937            r += 1;
938          }
939        }
940      }
941    }
942    else {
943
944      if (0 == (a16 & 0x7800)) {
945        r += 4;
946
947        if (0 == (a16 & 0x0600)) {
948          r += 2;
949
950          if (0 == (a16 & 0x0100)) {
951            r += 1;
952          }
953        }
954        else {
955
956          if (0 == (a16 & 0x0400)) {
957            r += 1;
958          }
959        }
960      }
961      else {
962
963        if (0 == (a16 & 0x6000)) {
964          r += 2;
965
966          if (0 == (a16 & 0x1000)) {
967            r += 1;
968          }
969        }
970        else {
971
972          if (0 == (a16 & 0x4000)) {
973            return 1;
974          }
975        }
976      }
977    }
978  }
979
980  return r ;
981#endif
982}
983#endif
984
985/* Round,               1   */
986#if (ROUND_IS_INLINE)
987__inline Word16 round16(Word32 L_var1)
988{
989#if ARMV5TE_ROUND
990	Word16 result;
991	asm (
992		"QADD  %[result], %[L_var1], %[bias]\n"
993		"MOV   %[result], %[result], ASR #16 \n"
994		:[result]"=r"(result)
995		:[L_var1]"r"(L_var1), [bias]"r"(0x8000)
996		);
997	return result;
998#else
999    Word16 var_out;
1000    Word32 L_rounded;
1001
1002    L_rounded = L_add (L_var1, (Word32) 0x00008000L);
1003    var_out = extract_h (L_rounded);
1004    return (var_out);
1005#endif
1006}
1007#endif
1008
1009/* Mac,  1  */
1010#if (L_MAC_IS_INLINE)
1011__inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
1012{
1013#if ARMV5TE_L_MAC
1014	Word32 result;
1015	asm (
1016		"SMULBB %[result], %[var1], %[var2]\n"
1017		"QADD	%[result], %[result], %[result]\n"
1018		"QADD   %[result], %[result], %[L_var3]\n"
1019		:[result]"=&r"(result)
1020		: [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
1021		);
1022	return result;
1023#else
1024    Word32 L_var_out;
1025    Word32 L_product;
1026
1027    L_product = L_mult(var1, var2);
1028    L_var_out = L_add (L_var3, L_product);
1029    return (L_var_out);
1030#endif
1031}
1032#endif
1033
1034#if (L_ADD_IS_INLINE)
1035__inline Word32 L_add (Word32 L_var1, Word32 L_var2)
1036{
1037#if ARMV5TE_L_ADD
1038	Word32 result;
1039	asm (
1040		"QADD %[result], %[L_var1], %[L_var2]\n"
1041		:[result]"=r"(result)
1042		:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
1043		);
1044	return result;
1045#else
1046    Word32 L_var_out;
1047
1048    L_var_out = L_var1 + L_var2;
1049    if (((L_var1 ^ L_var2) & MIN_32) == 0)
1050    {
1051        if ((L_var_out ^ L_var1) & MIN_32)
1052        {
1053            L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
1054        }
1055    }
1056    return (L_var_out);
1057#endif
1058}
1059#endif
1060
1061
1062
1063#if (MULT_R_IS_INLINE)
1064__inline Word16 mult_r (Word16 var1, Word16 var2)
1065{
1066    Word16 var_out;
1067    Word32 L_product_arr;
1068
1069    L_product_arr = (Word32)var1 *(Word32)var2;       /* product */
1070    L_product_arr += (Word32)0x00004000L;      /* round */
1071    L_product_arr >>= 15;       /* shift */
1072
1073    var_out = saturate(L_product_arr);
1074
1075    return (var_out);
1076}
1077#endif
1078
1079#if (SHR_R_IS_INLINE)
1080__inline Word16 shr_r (Word16 var1, Word16 var2)
1081{
1082    Word16 var_out;
1083
1084    if (var2 > 15)
1085    {
1086        var_out = 0;
1087    }
1088    else
1089    {
1090        var_out = shr(var1, var2);
1091
1092        if (var2 > 0)
1093        {
1094            if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
1095            {
1096                var_out++;
1097            }
1098        }
1099    }
1100
1101    return (var_out);
1102}
1103#endif
1104
1105#if (MAC_R_IS_INLINE)
1106__inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
1107{
1108    Word16 var_out;
1109
1110    L_var3 = L_mac (L_var3, var1, var2);
1111    var_out = (Word16)((L_var3 + 0x8000L) >> 16);
1112
1113    return (var_out);
1114}
1115#endif
1116
1117#if (MSU_R_IS_INLINE)
1118__inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
1119{
1120    Word16 var_out;
1121
1122    L_var3 = L_msu (L_var3, var1, var2);
1123    var_out = (Word16)((L_var3 + 0x8000L) >> 16);
1124
1125    return (var_out);
1126}
1127#endif
1128
1129#if (L_SHR_R_IS_INLINE)
1130__inline Word32 L_shr_r (Word32 L_var1, Word16 var2)
1131{
1132    Word32 L_var_out;
1133
1134    if (var2 > 31)
1135    {
1136        L_var_out = 0;
1137    }
1138    else
1139    {
1140        L_var_out = L_shr(L_var1, var2);
1141
1142        if (var2 > 0)
1143        {
1144            if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
1145            {
1146                L_var_out++;
1147            }
1148        }
1149    }
1150
1151    return (L_var_out);
1152}
1153#endif
1154
1155#if (EXTRACT_H_IS_INLINE)
1156__inline Word16 extract_h (Word32 L_var1)
1157{
1158    Word16 var_out;
1159
1160    var_out = (Word16) (L_var1 >> 16);
1161
1162    return (var_out);
1163}
1164#endif
1165
1166#if (EXTRACT_L_IS_INLINE)
1167__inline Word16 extract_l(Word32 L_var1)
1168{
1169	return (Word16) L_var1;
1170}
1171#endif
1172
1173#endif
1174