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