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)       (((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) (((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 Word32 saturate(Word32 L_var1);
64 #else
65 Word16 saturate(Word32 L_var1);
66 #endif
67 
68 /* Short shift left,    1   */
69 #if (SHL_IS_INLINE)
70 __inline Word32 shl (Word32 var1, Word32 var2);
71 #else
72 Word16 shl (Word16 var1, Word16 var2);
73 #endif
74 
75 /* Short shift right,   1   */
76 #if (SHR_IS_INLINE)
77 __inline Word32 shr (Word32 var1, Word32 var2);
78 #else
79 Word16 shr (Word16 var1, Word16 var2);
80 #endif
81 
82 #if (L_MULT_IS_INLINE)
83 __inline Word32 L_mult(Word32 var1, Word32 var2);
84 #else
85 Word32 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, Word32 var1, Word32 var2);
91 #else
92 Word32 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
99 Word32 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, Word32 var2);
105 #else
106 Word32 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, Word32 var2);
112 #else
113 Word32 L_shr (Word32 L_var1, Word16 var2);
114 #endif
115 
116 /* Short add,           1   */
117 #if (ADD_IS_INLINE)
118 __inline Word32 add (Word32 var1, Word32 var2);
119 #else
120 Word16 add (Word16 var1, Word16 var2);
121 #endif
122 
123 /* Short sub,           1   */
124 #if (SUB_IS_INLINE)
125 __inline Word32 sub(Word32 var1, Word32 var2);
126 #else
127 Word16 sub(Word16 var1, Word16 var2);
128 #endif
129 
130 /* Short division,       18  */
131 #if (DIV_S_IS_INLINE)
132 __inline Word32 div_s (Word32 var1, Word32 var2);
133 #else
134 Word16 div_s (Word16 var1, Word16 var2);
135 #endif
136 
137 /* Short mult,          1   */
138 #if (MULT_IS_INLINE)
139 __inline Word32 mult (Word32 var1, Word32 var2);
140 #else
141 Word16 mult (Word16 var1, Word16 var2);
142 #endif
143 
144 /* Short norm,           15  */
145 #if (NORM_S_IS_INLINE)
146 __inline Word32 norm_s (Word32 var1);
147 #else
148 Word16 norm_s (Word16 var1);
149 #endif
150 
151 /* Long norm,            30  */
152 #if (NORM_L_IS_INLINE)
153 __inline Word32 norm_l (Word32 L_var1);
154 #else
155 Word16 norm_l (Word32 L_var1);
156 #endif
157 
158 /* Round,               1   */
159 #if (ROUND_IS_INLINE)
160 __inline Word32 round16(Word32 L_var1);
161 #else
162 Word16 round16(Word32 L_var1);
163 #endif
164 
165 /* Mac,  1  */
166 #if (L_MAC_IS_INLINE)
167 __inline Word32 L_mac (Word32 L_var3, Word32 var1, Word32 var2);
168 #else
169 Word32 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
175 Word32 L_add (Word32 L_var1, Word32 L_var2);
176 #endif
177 
178 /* Extract high,        1   */
179 #if (EXTRACT_H_IS_INLINE)
180 __inline Word32 extract_h (Word32 L_var1);
181 #else
182 Word16 extract_h (Word32 L_var1);
183 #endif
184 
185 /* Extract low,         1   */
186 #if (EXTRACT_L_IS_INLINE)
187 __inline Word32 extract_l(Word32 L_var1);
188 #else
189 Word16 extract_l(Word32 L_var1);
190 #endif
191 
192 /* Mult with round, 2 */
193 #if (MULT_R_IS_INLINE)
194 __inline Word32 mult_r(Word32 var1, Word32 var2);
195 #else
196 Word16 mult_r(Word16 var1, Word16 var2);
197 #endif
198 
199 /* Shift right with round, 2           */
200 #if (SHR_R_IS_INLINE)
201 __inline Word32 shr_r (Word32 var1, Word32 var2);
202 #else
203 Word16 shr_r (Word16 var1, Word16 var2);
204 #endif
205 
206 /* Mac with rounding,2 */
207 #if (MAC_R_IS_INLINE)
208 __inline Word32 mac_r (Word32 L_var3, Word32 var1, Word32 var2);
209 #else
210 Word16 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 Word32 msu_r (Word32 L_var3, Word32 var1, Word32 var2);
216 #else
217 Word16 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, Word32 var2);
223 #else
224 Word32 L_shr_r (Word32 L_var1, Word16 var2);
225 #endif
226 
227 #if ARMV4_INASM
ASM_L_shr(Word32 L_var1,Word32 var2)228 __inline Word32 ASM_L_shr(Word32 L_var1, Word32 var2)
229 {
230 	return L_var1 >> var2;
231 }
232 
ASM_L_shl(Word32 L_var1,Word32 var2)233 __inline Word32 ASM_L_shl(Word32 L_var1, Word32 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 
ASM_shr(Word32 L_var1,Word32 var2)246 __inline Word32 ASM_shr(Word32 L_var1, Word32 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 
ASM_shl(Word32 L_var1,Word32 var2)259 __inline Word32 ASM_shl(Word32 L_var1, Word32 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)
saturate(Word32 L_var1)296 __inline Word32 saturate(Word32 L_var1)
297 {
298 #if ARMV6_SAT
299     Word32 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 	Word32 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     Word32 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)
shl(Word32 var1,Word32 var2)344 __inline Word32 shl (Word32 var1, Word32 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     Word32 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)
shr(Word32 var1,Word32 var2)383 __inline Word32 shr (Word32 var1, Word32 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     Word32 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)
L_mult(Word32 var1,Word32 var2)427 __inline Word32 L_mult(Word32 var1, Word32 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)
L_msu(Word32 L_var3,Word32 var1,Word32 var2)457 __inline Word32 L_msu (Word32 L_var3, Word32 var1, Word32 var2)
458 {
459 #if ARMV5TE_L_MSU
460 	Word32 result;
461 	asm (
462 		"SMULBB %[result], %[var1], %[var2] \n"
463 		"QDSUB %[result], %[L_var3], %[result]\n"
464 		:[result]"=&r"(result)
465 		:[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
466 		);
467 	return result;
468 #else
469     Word32 L_var_out;
470     Word32 L_product;
471 
472     L_product = L_mult(var1, var2);
473     L_var_out = L_sub(L_var3, L_product);
474     return (L_var_out);
475 #endif
476 }
477 #endif
478 
479 #if (L_SUB_IS_INLINE)
L_sub(Word32 L_var1,Word32 L_var2)480 __inline Word32 L_sub(Word32 L_var1, Word32 L_var2)
481 {
482 #if ARMV5TE_L_SUB
483 	Word32 result;
484 	asm (
485 		"QSUB %[result], %[L_var1], %[L_var2]\n"
486 		:[result]"=r"(result)
487 		:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
488 		);
489 	return result;
490 #else
491     Word32 L_var_out;
492 
493     L_var_out = L_var1 - L_var2;
494 
495     if (((L_var1 ^ L_var2) & MIN_32) != 0)
496     {
497         if ((L_var_out ^ L_var1) & MIN_32)
498         {
499             L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
500         }
501     }
502 
503     return (L_var_out);
504 #endif
505 }
506 #endif
507 
508 #if (L_SHL_IS_INLINE)
L_shl(Word32 L_var1,Word32 var2)509 __inline Word32 L_shl(Word32 L_var1, Word32 var2)
510 {
511 #if ARMV5TE_L_SHL
512     if(var2>=0)
513     {
514         return  ASM_L_shl( L_var1, var2);
515     }
516     else
517     {
518         return  ASM_L_shr( L_var1, -var2);
519     }
520 #else
521     Word32 L_var_out = 0L;
522 
523     if (var2 <= 0)
524     {
525         L_var1 = L_shr(L_var1, (Word16)-var2);
526     }
527     else
528     {
529         for (; var2 > 0; var2--)
530         {
531             if (L_var1 > (Word32) 0X3fffffffL)
532             {
533                 return MAX_32;
534             }
535             else
536             {
537                 if (L_var1 < (Word32) 0xc0000000L)
538                 {
539                     return MIN_32;
540                 }
541             }
542             L_var1 <<= 1;
543             L_var_out = L_var1;
544         }
545     }
546     return (L_var1);
547 #endif
548 }
549 #endif
550 
551 #if (L_SHR_IS_INLINE)
L_shr(Word32 L_var1,Word32 var2)552 __inline Word32 L_shr (Word32 L_var1, Word32 var2)
553 {
554 #if ARMV5TE_L_SHR
555 	if(var2>=0)
556 	{
557 		return ASM_L_shr( L_var1, var2);
558 	}
559 	else
560 	{
561 		return ASM_L_shl( L_var1, -var2);
562 	}
563 #else
564     Word32 L_var_out;
565 
566     if (var2 < 0)
567     {
568         L_var_out = L_shl (L_var1, (Word16)-var2);
569     }
570     else
571     {
572         if (var2 >= 31)
573         {
574             L_var_out = (L_var1 < 0L) ? -1 : 0;
575         }
576         else
577         {
578             if (L_var1 < 0)
579             {
580                 L_var_out = ~((~L_var1) >> var2);
581             }
582             else
583             {
584                 L_var_out = L_var1 >> var2;
585             }
586         }
587     }
588     return (L_var_out);
589 #endif
590 }
591 #endif
592 
593 /* Short add,           1   */
594 #if (ADD_IS_INLINE)
add(Word32 var1,Word32 var2)595 __inline Word32 add (Word32 var1, Word32 var2)
596 {
597 #if ARMV5TE_ADD
598 	Word32 result;
599 	Word32 tmp;
600 	asm (
601 		"ADD  %[result], %[var1], %[var2] \n"
602 		"MOV  %[tmp], %[result], ASR #15 \n"
603 		"TEQ  %[tmp], %[result], ASR #31 \n"
604 		"EORNE %[result], %[mask], %[result], ASR #31"
605 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
606 		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
607 		);
608 	return result;
609 #else
610     Word32 var_out;
611     Word32 L_sum;
612 
613     L_sum = (Word32) var1 + var2;
614     var_out = saturate(L_sum);
615 
616     return (var_out);
617 #endif
618 }
619 #endif
620 
621 /* Short sub,           1   */
622 #if (SUB_IS_INLINE)
sub(Word32 var1,Word32 var2)623 __inline Word32 sub(Word32 var1, Word32 var2)
624 {
625 #if ARMV5TE_SUB
626 	Word32 result;
627 	Word32 tmp;
628 	asm (
629 		"SUB   %[result], %[var1], %[var2] \n"
630 		"MOV   %[tmp], %[var1], ASR #15 \n"
631 		"TEQ   %[tmp], %[var1], ASR #31 \n"
632 		"EORNE %[result], %[mask], %[result], ASR #31 \n"
633 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
634 		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
635 		);
636 	return result;
637 #else
638     Word32 var_out;
639     Word32 L_diff;
640 
641     L_diff = (Word32) var1 - var2;
642     var_out = saturate(L_diff);
643 
644     return (var_out);
645 #endif
646 }
647 #endif
648 
649 /* Short division,       18  */
650 #if (DIV_S_IS_INLINE)
div_s(Word32 var1,Word32 var2)651 __inline Word32 div_s (Word32 var1, Word32 var2)
652 {
653     Word32 var_out = 0;
654     Word32 iteration;
655     Word32 L_num;
656     Word32 L_denom;
657 
658     var_out = MAX_16;
659     if (var1!= var2)//var1!= var2
660     {
661     	var_out = 0;
662     	L_num = (Word32) var1;
663 
664     	L_denom = (Word32) var2;
665 
666 		//return (L_num<<15)/var2;
667 
668     	for (iteration = 0; iteration < 15; iteration++)
669     	{
670     		var_out <<= 1;
671     		L_num <<= 1;
672 
673     		if (L_num >= L_denom)
674     		{
675     			L_num -= L_denom;
676     			var_out++;
677     		}
678     	}
679     }
680     return (var_out);
681 }
682 #endif
683 
684 /* Short mult,          1   */
685 #if (MULT_IS_INLINE)
mult(Word32 var1,Word32 var2)686 __inline Word32 mult (Word32 var1, Word32 var2)
687 {
688 #if ARMV5TE_MULT && ARMV6_SAT
689 	Word32 result;
690 	asm (
691 		"SMULBB %[result], %[var1], %[var2] \n"
692 		"SSAT   %[result], #16, %[result], ASR #15 \n"
693 		:[result]"=r"(result)
694 		:[var1]"r"(var1), [var2]"r"(var2)
695 		);
696 	return result;
697 #elif ARMV5TE_MULT
698 	Word32 result, tmp;
699 	asm (
700 		"SMULBB %[tmp], %[var1], %[var2] \n"
701 		"MOV	%[result], %[tmp], ASR #15\n"
702 		"MOV	%[tmp], %[result], ASR #15\n"
703 		"TEQ	%[tmp], %[result], ASR #31\n"
704 		"EORNE  %[result], %[mask], %[result], ASR #31 \n"
705 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
706 		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
707 		);
708 	return result;
709 #else
710     Word32 var_out;
711     Word32 L_product;
712 
713     L_product = (Word32) var1 *(Word32) var2;
714     L_product = (L_product & (Word32) 0xffff8000L) >> 15;
715     if (L_product & (Word32) 0x00010000L)
716         L_product = L_product | (Word32) 0xffff0000L;
717     var_out = saturate(L_product);
718 
719     return (var_out);
720 #endif
721 }
722 #endif
723 
724 
725 /* Short norm,           15  */
726 #if (NORM_S_IS_INLINE)
norm_s(Word32 var1)727 __inline Word32 norm_s (Word32 var1)
728 {
729 #if ARMV5TE_NORM_S
730 	Word32 result;
731 	Word32 tmp;
732 	asm (
733 		"RSBS  %[tmp], %[var1], #0 \n"
734 		"CLZLT %[result], %[var1]\n"
735 		"CLZGT %[result], %[tmp]\n"
736 		"SUBNE %[result], %[result], #17\n"
737 		"MOVEQ %[result], #0\n"
738 		"CMP   %[var1], #-1\n"
739 		"MOVEQ %[result], #15\n"
740 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
741 		:[var1]"r"(var1)
742 		);
743 	return result;
744 #else
745     Word32 var_out;
746 
747     if (var1 == 0)
748     {
749         var_out = 0;
750     }
751     else
752     {
753         if (var1 == -1)
754         {
755             var_out = 15;
756         }
757         else
758         {
759             if (var1 < 0)
760             {
761                 var1 = (Word16)~var1;
762             }
763             for (var_out = 0; var1 < 0x4000; var_out++)
764             {
765                 var1 <<= 1;
766             }
767         }
768     }
769     return (var_out);
770 #endif
771 }
772 #endif
773 
774 /* Long norm,            30  */
775 #if (NORM_L_IS_INLINE)
norm_l(Word32 L_var1)776 __inline Word32 norm_l (Word32 L_var1)
777 {
778 #if ARMV5TE_NORM_L
779 	Word32 result;
780 	asm volatile(
781 		"CMP    %[L_var1], #0\n"
782 		"CLZNE  %[result], %[L_var1]\n"
783 		"SUBNE  %[result], %[result], #1\n"
784 		"MOVEQ  %[result], #0\n"
785 		:[result]"=r"(result)
786 		:[L_var1]"r"(L_var1)
787 		);
788 	return result;
789 #else
790     //Word16 var_out;
791 
792     //if (L_var1 == 0)
793     //{
794     //    var_out = 0;
795     //}
796     //else
797     //{
798     //    if (L_var1 == (Word32) 0xffffffffL)
799     //    {
800     //        var_out = 31;
801     //    }
802     //    else
803     //    {
804     //        if (L_var1 < 0)
805     //        {
806     //            L_var1 = ~L_var1;
807     //        }
808     //        for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
809     //        {
810     //            L_var1 <<= 1;
811     //        }
812     //    }
813     //}
814     //return (var_out);
815   Word16 a16;
816   Word16 r = 0 ;
817 
818 
819   if ( L_var1 < 0 ) {
820     L_var1 = ~L_var1;
821   }
822 
823   if (0 == (L_var1 & 0x7fff8000)) {
824     a16 = extract_l(L_var1);
825     r += 16;
826 
827     if (0 == (a16 & 0x7f80)) {
828       r += 8;
829 
830       if (0 == (a16 & 0x0078)) {
831         r += 4;
832 
833         if (0 == (a16 & 0x0006)) {
834           r += 2;
835 
836           if (0 == (a16 & 0x0001)) {
837             r += 1;
838           }
839         }
840         else {
841 
842           if (0 == (a16 & 0x0004)) {
843             r += 1;
844           }
845         }
846       }
847       else {
848 
849         if (0 == (a16 & 0x0060)) {
850           r += 2;
851 
852           if (0 == (a16 & 0x0010)) {
853             r += 1;
854           }
855         }
856         else {
857 
858           if (0 == (a16 & 0x0040)) {
859             r += 1;
860           }
861         }
862       }
863     }
864     else {
865 
866       if (0 == (a16 & 0x7800)) {
867         r += 4;
868 
869         if (0 == (a16 & 0x0600)) {
870           r += 2;
871 
872           if (0 == (a16 & 0x0100)) {
873             r += 1;
874           }
875         }
876         else {
877 
878           if (0 == (a16 & 0x0400)) {
879             r += 1;
880           }
881         }
882       }
883       else {
884 
885         if (0 == (a16 & 0x6000)) {
886           r += 2;
887 
888           if (0 == (a16 & 0x1000)) {
889             r += 1;
890           }
891         }
892         else {
893 
894           if (0 == (a16 & 0x4000)) {
895             r += 1;
896           }
897         }
898       }
899     }
900   }
901   else {
902     a16 = extract_h(L_var1);
903 
904     if (0 == (a16 & 0x7f80)) {
905       r += 8;
906 
907       if (0 == (a16 & 0x0078)) {
908         r += 4 ;
909 
910         if (0 == (a16 & 0x0006)) {
911           r += 2;
912 
913           if (0 == (a16 & 0x0001)) {
914             r += 1;
915           }
916         }
917         else {
918 
919           if (0 == (a16 & 0x0004)) {
920             r += 1;
921           }
922         }
923       }
924       else {
925 
926         if (0 == (a16 & 0x0060)) {
927           r += 2;
928 
929           if (0 == (a16 & 0x0010)) {
930             r += 1;
931           }
932         }
933         else {
934 
935           if (0 == (a16 & 0x0040)) {
936             r += 1;
937           }
938         }
939       }
940     }
941     else {
942 
943       if (0 == (a16 & 0x7800)) {
944         r += 4;
945 
946         if (0 == (a16 & 0x0600)) {
947           r += 2;
948 
949           if (0 == (a16 & 0x0100)) {
950             r += 1;
951           }
952         }
953         else {
954 
955           if (0 == (a16 & 0x0400)) {
956             r += 1;
957           }
958         }
959       }
960       else {
961 
962         if (0 == (a16 & 0x6000)) {
963           r += 2;
964 
965           if (0 == (a16 & 0x1000)) {
966             r += 1;
967           }
968         }
969         else {
970 
971           if (0 == (a16 & 0x4000)) {
972             return 1;
973           }
974         }
975       }
976     }
977   }
978 
979   return r ;
980 #endif
981 }
982 #endif
983 
984 /* Round,               1   */
985 #if (ROUND_IS_INLINE)
round16(Word32 L_var1)986 __inline Word32 round16(Word32 L_var1)
987 {
988 #if ARMV5TE_ROUND
989 	Word32 result;
990 	asm (
991 		"QADD  %[result], %[L_var1], %[bias]\n"
992 		"MOV   %[result], %[result], ASR #16 \n"
993 		:[result]"=r"(result)
994 		:[L_var1]"r"(L_var1), [bias]"r"(0x8000)
995 		);
996 	return result;
997 #else
998     Word32 var_out;
999     Word32 L_rounded;
1000 
1001     L_rounded = L_add (L_var1, (Word32) 0x00008000L);
1002     var_out = extract_h (L_rounded);
1003     return (var_out);
1004 #endif
1005 }
1006 #endif
1007 
1008 /* Mac,  1  */
1009 #if (L_MAC_IS_INLINE)
L_mac(Word32 L_var3,Word32 var1,Word32 var2)1010 __inline Word32 L_mac (Word32 L_var3, Word32 var1, Word32 var2)
1011 {
1012 #if ARMV5TE_L_MAC
1013 	Word32 result;
1014 	asm (
1015 		"SMULBB %[result], %[var1], %[var2]\n"
1016 		"QDADD  %[result], %[L_var3], %[result]\n"
1017 		:[result]"=&r"(result)
1018 		: [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
1019 		);
1020 	return result;
1021 #else
1022     Word32 L_var_out;
1023     Word32 L_product;
1024 
1025     L_product = L_mult(var1, var2);
1026     L_var_out = L_add (L_var3, L_product);
1027     return (L_var_out);
1028 #endif
1029 }
1030 #endif
1031 
1032 #if (L_ADD_IS_INLINE)
L_add(Word32 L_var1,Word32 L_var2)1033 __inline Word32 L_add (Word32 L_var1, Word32 L_var2)
1034 {
1035 #if ARMV5TE_L_ADD
1036 	Word32 result;
1037 	asm (
1038 		"QADD %[result], %[L_var1], %[L_var2]\n"
1039 		:[result]"=r"(result)
1040 		:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
1041 		);
1042 	return result;
1043 #else
1044     Word32 L_var_out;
1045 
1046     L_var_out = L_var1 + L_var2;
1047     if (((L_var1 ^ L_var2) & MIN_32) == 0)
1048     {
1049         if ((L_var_out ^ L_var1) & MIN_32)
1050         {
1051             L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
1052         }
1053     }
1054     return (L_var_out);
1055 #endif
1056 }
1057 #endif
1058 
1059 
1060 
1061 #if (MULT_R_IS_INLINE)
mult_r(Word32 var1,Word32 var2)1062 __inline Word32 mult_r (Word32 var1, Word32 var2)
1063 {
1064     Word32 var_out;
1065     Word32 L_product_arr;
1066 
1067     L_product_arr = (Word32)var1 *(Word32)var2;       /* product */
1068     L_product_arr += (Word32)0x00004000L;      /* round */
1069     L_product_arr >>= 15;       /* shift */
1070 
1071     var_out = saturate(L_product_arr);
1072 
1073     return (var_out);
1074 }
1075 #endif
1076 
1077 #if (SHR_R_IS_INLINE)
shr_r(Word32 var1,Word32 var2)1078 __inline Word32 shr_r (Word32 var1, Word32 var2)
1079 {
1080     Word32 var_out;
1081 
1082     if (var2 > 15)
1083     {
1084         var_out = 0;
1085     }
1086     else
1087     {
1088         var_out = shr(var1, var2);
1089 
1090         if (var2 > 0)
1091         {
1092             if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
1093             {
1094                 var_out++;
1095             }
1096         }
1097     }
1098 
1099     return (var_out);
1100 }
1101 #endif
1102 
1103 #if (MAC_R_IS_INLINE)
mac_r(Word32 L_var3,Word32 var1,Word32 var2)1104 __inline Word32 mac_r (Word32 L_var3, Word32 var1, Word32 var2)
1105 {
1106     Word32 var_out;
1107 
1108     L_var3 = L_mac (L_var3, var1, var2);
1109     var_out = (Word16)((L_var3 + 0x8000L) >> 16);
1110 
1111     return (var_out);
1112 }
1113 #endif
1114 
1115 #if (MSU_R_IS_INLINE)
msu_r(Word32 L_var3,Word32 var1,Word32 var2)1116 __inline Word32 msu_r (Word32 L_var3, Word32 var1, Word32 var2)
1117 {
1118     Word32 var_out;
1119 
1120     L_var3 = L_msu (L_var3, var1, var2);
1121     var_out = (Word16)((L_var3 + 0x8000L) >> 16);
1122 
1123     return (var_out);
1124 }
1125 #endif
1126 
1127 #if (L_SHR_R_IS_INLINE)
L_shr_r(Word32 L_var1,Word32 var2)1128 __inline Word32 L_shr_r (Word32 L_var1, Word32 var2)
1129 {
1130     Word32 L_var_out;
1131 
1132     if (var2 > 31)
1133     {
1134         L_var_out = 0;
1135     }
1136     else
1137     {
1138         L_var_out = L_shr(L_var1, var2);
1139 
1140         if (var2 > 0)
1141         {
1142             if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
1143             {
1144                 L_var_out++;
1145             }
1146         }
1147     }
1148 
1149     return (L_var_out);
1150 }
1151 #endif
1152 
1153 #if (EXTRACT_H_IS_INLINE)
extract_h(Word32 L_var1)1154 __inline Word32 extract_h (Word32 L_var1)
1155 {
1156     Word32 var_out;
1157 
1158     var_out = (L_var1 >> 16);
1159 
1160     return (var_out);
1161 }
1162 #endif
1163 
1164 #if (EXTRACT_L_IS_INLINE)
extract_l(Word32 L_var1)1165 __inline Word32 extract_l(Word32 L_var1)
1166 {
1167 	return (Word16) L_var1;
1168 }
1169 #endif
1170 
1171 #endif
1172