basic_op.h revision 9da751147af3222258093d9f41cabf0ea1391c04
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	Word32 result;
231	asm (
232		"MOV %[result], %[L_var1], ASR %[var2] \n"
233		:[result]"=r"(result)
234		:[L_var1]"r"(L_var1), [var2]"r"(var2)
235		);
236	return result;
237}
238
239__inline Word32 ASM_L_shl(Word32 L_var1, Word16 var2)
240{
241	Word32 result;
242	asm (
243		"MOV	%[result], %[L_var1], ASL %[var2] \n"
244		"TEQ	%[L_var1], %[result], ASR %[var2]\n"
245		"EORNE  %[result], %[mask], %[L_var1], ASR #31\n"
246		:[result]"=&r"(result)
247		:[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fffffff)
248		);
249	return result;
250}
251
252__inline Word32 ASM_shr(Word32 L_var1, Word16 var2)
253{
254	Word32 result;
255	asm (
256		"CMP	%[var2], #15\n"
257		"MOVLT	%[result], %[L_var1], ASR %[var2]\n"
258		"MOVGE	%[result], %[L_var1], ASR #15\n"
259		:[result]"=r"(result)
260		:[L_var1]"r"(L_var1), [var2]"r"(var2)
261		);
262	return result;
263}
264
265__inline Word32 ASM_shl(Word32 L_var1, Word16 var2)
266{
267	Word32 result;
268	Word32 tmp;
269	asm (
270		"CMP	%[var2], #16\n"
271		"MOVLT  %[result], %[L_var1], ASL %[var2]\n"
272		"MOVGE  %[result], %[L_var1], ASL #16\n"
273        "MOV    %[tmp], %[result], ASR #15\n"
274        "TEQ    %[tmp], %[result], ASR #31 \n"
275        "EORNE  %[result], %[mask], %[result],ASR #31"
276		:[result]"=&r"(result), [tmp]"=&r"(tmp)
277		:[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fff)
278		);
279	return result;
280}
281#endif
282
283/*___________________________________________________________________________
284 |                                                                           |
285 |   definitions for inline basic arithmetic operators                       |
286 |___________________________________________________________________________|
287*/
288#if (SATRUATE_IS_INLINE)
289__inline Word16 saturate(Word32 L_var1)
290{
291#if ARMV5TE_SAT
292	Word16 result;
293	Word32 tmp;
294	asm volatile (
295		"MOV	%[tmp], %[L_var1],ASR#15\n"
296		"TEQ	%[tmp], %[L_var1],ASR#31\n"
297		"EORNE	%[result], %[mask],%[L_var1],ASR#31\n"
298		"MOVEQ	%[result], %[L_var1]\n"
299		:[result]"=&r"(result), [tmp]"=&r"(tmp)
300		:[L_var1]"r"(L_var1), [mask]"r"(0x7fff)
301	);
302
303	return result;
304#else
305    Word16 var_out;
306
307    //var_out = (L_var1 > (Word32)0X00007fffL) ? (MAX_16) : ((L_var1 < (Word32)0xffff8000L) ? (MIN_16) : ((Word16)L_var1));
308
309    if (L_var1 > 0X00007fffL)
310    {
311        var_out = MAX_16;
312    }
313    else if (L_var1 < (Word32) 0xffff8000L)
314    {
315        var_out = MIN_16;
316    }
317    else
318    {
319        var_out = extract_l(L_var1);
320    }
321
322    return (var_out);
323#endif
324}
325#endif
326
327/* Short shift left,    1   */
328#if (SHL_IS_INLINE)
329__inline Word16 shl (Word16 var1, Word16 var2)
330{
331#if ARMV5TE_SHL
332	if(var2>=0)
333	{
334		return ASM_shl( var1, var2);
335	}
336	else
337	{
338		return ASM_shr( var1, -var2);
339	}
340#else
341    Word16 var_out;
342    Word32 result;
343
344    if (var2 < 0)
345    {
346        var_out = shr (var1, (Word16)-var2);
347    }
348    else
349    {
350        result = (Word32) var1 *((Word32) 1 << var2);
351
352        if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
353        {
354            var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
355        }
356        else
357        {
358            var_out = extract_l(result);
359        }
360    }
361    return (var_out);
362#endif
363}
364#endif
365
366/* Short shift right,   1   */
367#if (SHR_IS_INLINE)
368__inline Word16 shr (Word16 var1, Word16 var2)
369{
370#if ARMV5TE_SHR
371	if(var2>=0)
372	{
373		return  ASM_shr( var1, var2);
374	}
375	else
376	{
377		return  ASM_shl( var1, -var2);
378	}
379#else
380    Word16 var_out;
381
382    if (var2 < 0)
383    {
384        var_out = shl (var1, (Word16)-var2);
385    }
386    else
387    {
388        if (var2 >= 15)
389        {
390            var_out = (Word16)((var1 < 0) ? -1 : 0);
391        }
392        else
393        {
394            if (var1 < 0)
395            {
396                var_out = (Word16)(~((~var1) >> var2));
397            }
398            else
399            {
400                var_out = (Word16)(var1 >> var2);
401            }
402        }
403    }
404
405    return (var_out);
406#endif
407}
408#endif
409
410
411#if (L_MULT_IS_INLINE)
412__inline Word32 L_mult(Word16 var1, Word16 var2)
413{
414#if ARMV5TE_L_MULT
415	Word32 result;
416	asm (
417		"SMULBB %[result], %[var1], %[var2] \n"
418		"QADD %[result], %[result], %[result] \n"
419		:[result]"=r"(result)
420		:[var1]"r"(var1), [var2]"r"(var2)
421		);
422	return result;
423#else
424    Word32 L_var_out;
425
426    L_var_out = (Word32) var1 *(Word32) var2;
427
428    if (L_var_out != (Word32) 0x40000000L)
429    {
430        L_var_out <<= 1;
431    }
432    else
433    {
434        L_var_out = MAX_32;
435    }
436    return (L_var_out);
437#endif
438}
439#endif
440
441#if (L_MSU_IS_INLINE)
442__inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
443{
444#if ARMV5TE_L_MSU
445	Word32 result;
446	asm (
447		"SMULBB %[result], %[var1], %[var2] \n"
448		"QADD %[result], %[result], %[result] \n"
449		"QSUB %[result], %[L_var3], %[result]\n"
450		:[result]"=&r"(result)
451		:[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
452		);
453	return result;
454#else
455    Word32 L_var_out;
456    Word32 L_product;
457
458    L_product = L_mult(var1, var2);
459    L_var_out = L_sub(L_var3, L_product);
460    return (L_var_out);
461#endif
462}
463#endif
464
465#if (L_SUB_IS_INLINE)
466__inline Word32 L_sub(Word32 L_var1, Word32 L_var2)
467{
468#if ARMV5TE_L_SUB
469	Word32 result;
470	asm (
471		"QSUB %[result], %[L_var1], %[L_var2]\n"
472		:[result]"=r"(result)
473		:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
474		);
475	return result;
476#else
477    Word32 L_var_out;
478
479    L_var_out = L_var1 - L_var2;
480
481    if (((L_var1 ^ L_var2) & MIN_32) != 0)
482    {
483        if ((L_var_out ^ L_var1) & MIN_32)
484        {
485            L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
486        }
487    }
488
489    return (L_var_out);
490#endif
491}
492#endif
493
494#if (L_SHL_IS_INLINE)
495__inline Word32 L_shl(Word32 L_var1, Word16 var2)
496{
497#if ARMV5TE_L_SHL
498    if(var2>=0)
499    {
500        return  ASM_L_shl( L_var1, var2);
501    }
502    else
503    {
504        return  ASM_L_shr( L_var1, -var2);
505    }
506#else
507    Word32 L_var_out = 0L;
508
509    if (var2 <= 0)
510    {
511        L_var1 = L_shr(L_var1, (Word16)-var2);
512    }
513    else
514    {
515        for (; var2 > 0; var2--)
516        {
517            if (L_var1 > (Word32) 0X3fffffffL)
518            {
519                return MAX_32;
520            }
521            else
522            {
523                if (L_var1 < (Word32) 0xc0000000L)
524                {
525                    return MIN_32;
526                }
527            }
528            L_var1 <<= 1;
529            L_var_out = L_var1;
530        }
531    }
532    return (L_var1);
533#endif
534}
535#endif
536
537#if (L_SHR_IS_INLINE)
538__inline Word32 L_shr (Word32 L_var1, Word16 var2)
539{
540#if ARMV5TE_L_SHR
541	if(var2>=0)
542	{
543		return ASM_L_shr( L_var1, var2);
544	}
545	else
546	{
547		return ASM_L_shl( L_var1, -var2);
548	}
549#else
550    Word32 L_var_out;
551
552    if (var2 < 0)
553    {
554        L_var_out = L_shl (L_var1, (Word16)-var2);
555    }
556    else
557    {
558        if (var2 >= 31)
559        {
560            L_var_out = (L_var1 < 0L) ? -1 : 0;
561        }
562        else
563        {
564            if (L_var1 < 0)
565            {
566                L_var_out = ~((~L_var1) >> var2);
567            }
568            else
569            {
570                L_var_out = L_var1 >> var2;
571            }
572        }
573    }
574    return (L_var_out);
575#endif
576}
577#endif
578
579/* Short add,           1   */
580#if (ADD_IS_INLINE)
581__inline Word16 add (Word16 var1, Word16 var2)
582{
583#if ARMV5TE_ADD
584	Word32 result;
585	Word32 tmp;
586	asm (
587		"ADD  %[result], %[var1], %[var2] \n"
588		"MOV  %[tmp], %[result], ASR #15 \n"
589		"TEQ  %[tmp], %[result], ASR #31 \n"
590		"EORNE %[result], %[mask], %[result], ASR #31"
591		:[result]"=&r"(result), [tmp]"=&r"(tmp)
592		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
593		);
594	return result;
595#else
596    Word16 var_out;
597    Word32 L_sum;
598
599    L_sum = (Word32) var1 + var2;
600    var_out = saturate(L_sum);
601
602    return (var_out);
603#endif
604}
605#endif
606
607/* Short sub,           1   */
608#if (SUB_IS_INLINE)
609__inline Word16 sub(Word16 var1, Word16 var2)
610{
611#if ARMV5TE_SUB
612	Word32 result;
613	Word32 tmp;
614	asm (
615		"SUB   %[result], %[var1], %[var2] \n"
616		"MOV   %[tmp], %[var1], ASR #15 \n"
617		"TEQ   %[tmp], %[var1], ASR #31 \n"
618		"EORNE %[result], %[mask], %[result], ASR #31 \n"
619		:[result]"=&r"(result), [tmp]"=&r"(tmp)
620		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
621		);
622	return result;
623#else
624    Word16 var_out;
625    Word32 L_diff;
626
627    L_diff = (Word32) var1 - var2;
628    var_out = saturate(L_diff);
629
630    return (var_out);
631#endif
632}
633#endif
634
635/* Short division,       18  */
636#if (DIV_S_IS_INLINE)
637__inline Word16 div_s (Word16 var1, Word16 var2)
638{
639    Word16 var_out = 0;
640    Word16 iteration;
641    Word32 L_num;
642    Word32 L_denom;
643
644    var_out = MAX_16;
645    if (var1!= var2)//var1!= var2
646    {
647    	var_out = 0;
648    	L_num = (Word32) var1;
649
650    	L_denom = (Word32) var2;
651
652		//return (L_num<<15)/var2;
653
654    	for (iteration = 0; iteration < 15; iteration++)
655    	{
656    		var_out <<= 1;
657    		L_num <<= 1;
658
659    		if (L_num >= L_denom)
660    		{
661    			L_num -= L_denom;
662    			var_out++;
663    		}
664    	}
665    }
666    return (var_out);
667}
668#endif
669
670/* Short mult,          1   */
671#if (MULT_IS_INLINE)
672__inline Word16 mult (Word16 var1, Word16 var2)
673{
674#if ARMV5TE_MULT
675	Word32 result, tmp;
676	asm (
677		"SMULBB %[tmp], %[var1], %[var2] \n"
678		"MOV	%[result], %[tmp], ASR #15\n"
679		"MOV	%[tmp], %[result], ASR #15\n"
680		"TEQ	%[tmp], %[result], ASR #31\n"
681		"EORNE  %[result], %[mask], %[result], ASR #31 \n"
682		:[result]"=&r"(result), [tmp]"=&r"(tmp)
683		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
684		);
685	return result;
686#else
687    Word16 var_out;
688    Word32 L_product;
689
690    L_product = (Word32) var1 *(Word32) var2;
691    L_product = (L_product & (Word32) 0xffff8000L) >> 15;
692    if (L_product & (Word32) 0x00010000L)
693        L_product = L_product | (Word32) 0xffff0000L;
694    var_out = saturate(L_product);
695
696    return (var_out);
697#endif
698}
699#endif
700
701
702/* Short norm,           15  */
703#if (NORM_S_IS_INLINE)
704__inline Word16 norm_s (Word16 var1)
705{
706#if ARMV5TE_NORM_S
707	Word16 result;
708	Word32 tmp;
709	asm (
710		"RSBS  %[tmp], %[var1], #0 \n"
711		"CLZLT %[result], %[var1]\n"
712		"CLZGT %[result], %[tmp]\n"
713		"SUBNE %[result], %[result], #17\n"
714		"MOVEQ %[result], #0\n"
715		"CMP   %[var1], #-1\n"
716		"MOVEQ %[result], #15\n"
717		:[result]"=&r"(result), [tmp]"=&r"(tmp)
718		:[var1]"r"(var1)
719		);
720	return result;
721#else
722    Word16 var_out;
723
724    if (var1 == 0)
725    {
726        var_out = 0;
727    }
728    else
729    {
730        if (var1 == -1)
731        {
732            var_out = 15;
733        }
734        else
735        {
736            if (var1 < 0)
737            {
738                var1 = (Word16)~var1;
739            }
740            for (var_out = 0; var1 < 0x4000; var_out++)
741            {
742                var1 <<= 1;
743            }
744        }
745    }
746    return (var_out);
747#endif
748}
749#endif
750
751/* Long norm,            30  */
752#if (NORM_L_IS_INLINE)
753__inline Word16 norm_l (Word32 L_var1)
754{
755#if ARMV5TE_NORM_L
756	Word16 result;
757	asm volatile(
758		"CMP    %[L_var1], #0\n"
759		"CLZNE  %[result], %[L_var1]\n"
760		"SUBNE  %[result], %[result], #1\n"
761		"MOVEQ  %[result], #0\n"
762		:[result]"=r"(result)
763		:[L_var1]"r"(L_var1)
764		);
765	return result;
766#else
767    //Word16 var_out;
768
769    //if (L_var1 == 0)
770    //{
771    //    var_out = 0;
772    //}
773    //else
774    //{
775    //    if (L_var1 == (Word32) 0xffffffffL)
776    //    {
777    //        var_out = 31;
778    //    }
779    //    else
780    //    {
781    //        if (L_var1 < 0)
782    //        {
783    //            L_var1 = ~L_var1;
784    //        }
785    //        for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
786    //        {
787    //            L_var1 <<= 1;
788    //        }
789    //    }
790    //}
791    //return (var_out);
792  Word16 a16;
793  Word16 r = 0 ;
794
795
796  if ( L_var1 < 0 ) {
797    L_var1 = ~L_var1;
798  }
799
800  if (0 == (L_var1 & 0x7fff8000)) {
801    a16 = extract_l(L_var1);
802    r += 16;
803
804    if (0 == (a16 & 0x7f80)) {
805      r += 8;
806
807      if (0 == (a16 & 0x0078)) {
808        r += 4;
809
810        if (0 == (a16 & 0x0006)) {
811          r += 2;
812
813          if (0 == (a16 & 0x0001)) {
814            r += 1;
815          }
816        }
817        else {
818
819          if (0 == (a16 & 0x0004)) {
820            r += 1;
821          }
822        }
823      }
824      else {
825
826        if (0 == (a16 & 0x0060)) {
827          r += 2;
828
829          if (0 == (a16 & 0x0010)) {
830            r += 1;
831          }
832        }
833        else {
834
835          if (0 == (a16 & 0x0040)) {
836            r += 1;
837          }
838        }
839      }
840    }
841    else {
842
843      if (0 == (a16 & 0x7800)) {
844        r += 4;
845
846        if (0 == (a16 & 0x0600)) {
847          r += 2;
848
849          if (0 == (a16 & 0x0100)) {
850            r += 1;
851          }
852        }
853        else {
854
855          if (0 == (a16 & 0x0400)) {
856            r += 1;
857          }
858        }
859      }
860      else {
861
862        if (0 == (a16 & 0x6000)) {
863          r += 2;
864
865          if (0 == (a16 & 0x1000)) {
866            r += 1;
867          }
868        }
869        else {
870
871          if (0 == (a16 & 0x4000)) {
872            r += 1;
873          }
874        }
875      }
876    }
877  }
878  else {
879    a16 = extract_h(L_var1);
880
881    if (0 == (a16 & 0x7f80)) {
882      r += 8;
883
884      if (0 == (a16 & 0x0078)) {
885        r += 4 ;
886
887        if (0 == (a16 & 0x0006)) {
888          r += 2;
889
890          if (0 == (a16 & 0x0001)) {
891            r += 1;
892          }
893        }
894        else {
895
896          if (0 == (a16 & 0x0004)) {
897            r += 1;
898          }
899        }
900      }
901      else {
902
903        if (0 == (a16 & 0x0060)) {
904          r += 2;
905
906          if (0 == (a16 & 0x0010)) {
907            r += 1;
908          }
909        }
910        else {
911
912          if (0 == (a16 & 0x0040)) {
913            r += 1;
914          }
915        }
916      }
917    }
918    else {
919
920      if (0 == (a16 & 0x7800)) {
921        r += 4;
922
923        if (0 == (a16 & 0x0600)) {
924          r += 2;
925
926          if (0 == (a16 & 0x0100)) {
927            r += 1;
928          }
929        }
930        else {
931
932          if (0 == (a16 & 0x0400)) {
933            r += 1;
934          }
935        }
936      }
937      else {
938
939        if (0 == (a16 & 0x6000)) {
940          r += 2;
941
942          if (0 == (a16 & 0x1000)) {
943            r += 1;
944          }
945        }
946        else {
947
948          if (0 == (a16 & 0x4000)) {
949            return 1;
950          }
951        }
952      }
953    }
954  }
955
956  return r ;
957#endif
958}
959#endif
960
961/* Round,               1   */
962#if (ROUND_IS_INLINE)
963__inline Word16 round16(Word32 L_var1)
964{
965#if ARMV5TE_ROUND
966	Word16 result;
967	asm (
968		"QADD  %[result], %[L_var1], %[bias]\n"
969		"MOV   %[result], %[result], ASR #16 \n"
970		:[result]"=r"(result)
971		:[L_var1]"r"(L_var1), [bias]"r"(0x8000)
972		);
973	return result;
974#else
975    Word16 var_out;
976    Word32 L_rounded;
977
978    L_rounded = L_add (L_var1, (Word32) 0x00008000L);
979    var_out = extract_h (L_rounded);
980    return (var_out);
981#endif
982}
983#endif
984
985/* Mac,  1  */
986#if (L_MAC_IS_INLINE)
987__inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
988{
989#if ARMV5TE_L_MAC
990	Word32 result;
991	asm (
992		"SMULBB %[result], %[var1], %[var2]\n"
993		"QADD	%[result], %[result], %[result]\n"
994		"QADD   %[result], %[result], %[L_var3]\n"
995		:[result]"=&r"(result)
996		: [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
997		);
998	return result;
999#else
1000    Word32 L_var_out;
1001    Word32 L_product;
1002
1003    L_product = L_mult(var1, var2);
1004    L_var_out = L_add (L_var3, L_product);
1005    return (L_var_out);
1006#endif
1007}
1008#endif
1009
1010#if (L_ADD_IS_INLINE)
1011__inline Word32 L_add (Word32 L_var1, Word32 L_var2)
1012{
1013#if ARMV5TE_L_ADD
1014	Word32 result;
1015	asm (
1016		"QADD %[result], %[L_var1], %[L_var2]\n"
1017		:[result]"=r"(result)
1018		:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
1019		);
1020	return result;
1021#else
1022    Word32 L_var_out;
1023
1024    L_var_out = L_var1 + L_var2;
1025    if (((L_var1 ^ L_var2) & MIN_32) == 0)
1026    {
1027        if ((L_var_out ^ L_var1) & MIN_32)
1028        {
1029            L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
1030        }
1031    }
1032    return (L_var_out);
1033#endif
1034}
1035#endif
1036
1037
1038
1039#if (MULT_R_IS_INLINE)
1040__inline Word16 mult_r (Word16 var1, Word16 var2)
1041{
1042    Word16 var_out;
1043    Word32 L_product_arr;
1044
1045    L_product_arr = (Word32)var1 *(Word32)var2;       /* product */
1046    L_product_arr += (Word32)0x00004000L;      /* round */
1047    L_product_arr >>= 15;       /* shift */
1048
1049    var_out = saturate(L_product_arr);
1050
1051    return (var_out);
1052}
1053#endif
1054
1055#if (SHR_R_IS_INLINE)
1056__inline Word16 shr_r (Word16 var1, Word16 var2)
1057{
1058    Word16 var_out;
1059
1060    if (var2 > 15)
1061    {
1062        var_out = 0;
1063    }
1064    else
1065    {
1066        var_out = shr(var1, var2);
1067
1068        if (var2 > 0)
1069        {
1070            if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
1071            {
1072                var_out++;
1073            }
1074        }
1075    }
1076
1077    return (var_out);
1078}
1079#endif
1080
1081#if (MAC_R_IS_INLINE)
1082__inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
1083{
1084    Word16 var_out;
1085
1086    L_var3 = L_mac (L_var3, var1, var2);
1087    var_out = (Word16)((L_var3 + 0x8000L) >> 16);
1088
1089    return (var_out);
1090}
1091#endif
1092
1093#if (MSU_R_IS_INLINE)
1094__inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
1095{
1096    Word16 var_out;
1097
1098    L_var3 = L_msu (L_var3, var1, var2);
1099    var_out = (Word16)((L_var3 + 0x8000L) >> 16);
1100
1101    return (var_out);
1102}
1103#endif
1104
1105#if (L_SHR_R_IS_INLINE)
1106__inline Word32 L_shr_r (Word32 L_var1, Word16 var2)
1107{
1108    Word32 L_var_out;
1109
1110    if (var2 > 31)
1111    {
1112        L_var_out = 0;
1113    }
1114    else
1115    {
1116        L_var_out = L_shr(L_var1, var2);
1117
1118        if (var2 > 0)
1119        {
1120            if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
1121            {
1122                L_var_out++;
1123            }
1124        }
1125    }
1126
1127    return (L_var_out);
1128}
1129#endif
1130
1131#if (EXTRACT_H_IS_INLINE)
1132__inline Word16 extract_h (Word32 L_var1)
1133{
1134    Word16 var_out;
1135
1136    var_out = (Word16) (L_var1 >> 16);
1137
1138    return (var_out);
1139}
1140#endif
1141
1142#if (EXTRACT_L_IS_INLINE)
1143__inline Word16 extract_l(Word32 L_var1)
1144{
1145	return (Word16) L_var1;
1146}
1147#endif
1148
1149#endif
1150