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
65 Word16 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
72 Word16 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
79 Word16 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
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, Word16 var1, Word16 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, Word16 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, Word16 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 Word16 add (Word16 var1, Word16 var2);
119 #else
120 Word16 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
127 Word16 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
134 Word16 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
141 Word16 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
148 Word16 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
155 Word16 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
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, Word16 var1, Word16 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 Word16 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 Word16 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 Word16 mult_r(Word16 var1, Word16 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 Word16 shr_r (Word16 var1, Word16 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 Word16 mac_r (Word32 L_var3, Word16 var1, Word16 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 Word16 msu_r (Word32 L_var3, Word16 var1, Word16 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, Word16 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,Word16 var2)228 __inline Word32 ASM_L_shr(Word32 L_var1, Word16 var2)
229 {
230 return L_var1 >> var2;
231 }
232
ASM_L_shl(Word32 L_var1,Word16 var2)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
ASM_shr(Word32 L_var1,Word16 var2)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
ASM_shl(Word32 L_var1,Word16 var2)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)
saturate(Word32 L_var1)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)
shl(Word16 var1,Word16 var2)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)
shr(Word16 var1,Word16 var2)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)
L_mult(Word16 var1,Word16 var2)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)
L_msu(Word32 L_var3,Word16 var1,Word16 var2)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 "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,Word16 var2)509 __inline Word32 L_shl(Word32 L_var1, Word16 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 if (var2 <= 0)
522 {
523 L_var1 = L_shr(L_var1, (Word16)-var2);
524 }
525 else
526 {
527 for (; var2 > 0; var2--)
528 {
529 if (L_var1 > (Word32) 0X3fffffffL)
530 {
531 return MAX_32;
532 }
533 else
534 {
535 if (L_var1 < (Word32) 0xc0000000L)
536 {
537 return MIN_32;
538 }
539 }
540 L_var1 <<= 1;
541 }
542 }
543 return (L_var1);
544 #endif
545 }
546 #endif
547
548 #if (L_SHR_IS_INLINE)
L_shr(Word32 L_var1,Word16 var2)549 __inline Word32 L_shr (Word32 L_var1, Word16 var2)
550 {
551 #if ARMV5TE_L_SHR
552 if(var2>=0)
553 {
554 return ASM_L_shr( L_var1, var2);
555 }
556 else
557 {
558 return ASM_L_shl( L_var1, -var2);
559 }
560 #else
561 Word32 L_var_out;
562
563 if (var2 < 0)
564 {
565 L_var_out = L_shl (L_var1, (Word16)-var2);
566 }
567 else
568 {
569 if (var2 >= 31)
570 {
571 L_var_out = (L_var1 < 0L) ? -1 : 0;
572 }
573 else
574 {
575 if (L_var1 < 0)
576 {
577 L_var_out = ~((~L_var1) >> var2);
578 }
579 else
580 {
581 L_var_out = L_var1 >> var2;
582 }
583 }
584 }
585 return (L_var_out);
586 #endif
587 }
588 #endif
589
590 /* Short add, 1 */
591 #if (ADD_IS_INLINE)
add(Word16 var1,Word16 var2)592 __inline Word16 add (Word16 var1, Word16 var2)
593 {
594 #if ARMV5TE_ADD
595 Word32 result;
596 Word32 tmp;
597 asm (
598 "ADD %[result], %[var1], %[var2] \n"
599 "MOV %[tmp], %[result], ASR #15 \n"
600 "TEQ %[tmp], %[result], ASR #31 \n"
601 "EORNE %[result], %[mask], %[result], ASR #31"
602 :[result]"=&r"(result), [tmp]"=&r"(tmp)
603 :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
604 );
605 return result;
606 #else
607 Word16 var_out;
608 Word32 L_sum;
609
610 L_sum = (Word32) var1 + var2;
611 var_out = saturate(L_sum);
612
613 return (var_out);
614 #endif
615 }
616 #endif
617
618 /* Short sub, 1 */
619 #if (SUB_IS_INLINE)
sub(Word16 var1,Word16 var2)620 __inline Word16 sub(Word16 var1, Word16 var2)
621 {
622 #if ARMV5TE_SUB
623 Word32 result;
624 Word32 tmp;
625 asm (
626 "SUB %[result], %[var1], %[var2] \n"
627 "MOV %[tmp], %[var1], ASR #15 \n"
628 "TEQ %[tmp], %[var1], ASR #31 \n"
629 "EORNE %[result], %[mask], %[result], ASR #31 \n"
630 :[result]"=&r"(result), [tmp]"=&r"(tmp)
631 :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
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)
div_s(Word16 var1,Word16 var2)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)
mult(Word16 var1,Word16 var2)683 __inline Word16 mult (Word16 var1, Word16 var2)
684 {
685 #if ARMV5TE_MULT && ARMV6_SAT
686 Word32 result;
687 asm (
688 "SMULBB %[result], %[var1], %[var2] \n"
689 "SSAT %[result], #16, %[result], ASR #15 \n"
690 :[result]"=r"(result)
691 :[var1]"r"(var1), [var2]"r"(var2)
692 );
693 return result;
694 #elif ARMV5TE_MULT
695 Word32 result, tmp;
696 asm (
697 "SMULBB %[tmp], %[var1], %[var2] \n"
698 "MOV %[result], %[tmp], ASR #15\n"
699 "MOV %[tmp], %[result], ASR #15\n"
700 "TEQ %[tmp], %[result], ASR #31\n"
701 "EORNE %[result], %[mask], %[result], ASR #31 \n"
702 :[result]"=&r"(result), [tmp]"=&r"(tmp)
703 :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
704 );
705 return result;
706 #else
707 Word16 var_out;
708 Word32 L_product;
709
710 L_product = (Word32) var1 *(Word32) var2;
711 L_product = (L_product & (Word32) 0xffff8000L) >> 15;
712 if (L_product & (Word32) 0x00010000L)
713 L_product = L_product | (Word32) 0xffff0000L;
714 var_out = saturate(L_product);
715
716 return (var_out);
717 #endif
718 }
719 #endif
720
721
722 /* Short norm, 15 */
723 #if (NORM_S_IS_INLINE)
norm_s(Word16 var1)724 __inline Word16 norm_s (Word16 var1)
725 {
726 #if ARMV5TE_NORM_S
727 Word16 result;
728 Word32 tmp;
729 asm (
730 "RSBS %[tmp], %[var1], #0 \n"
731 "CLZLT %[result], %[var1]\n"
732 "CLZGT %[result], %[tmp]\n"
733 "SUBNE %[result], %[result], #17\n"
734 "MOVEQ %[result], #0\n"
735 "CMP %[var1], #-1\n"
736 "MOVEQ %[result], #15\n"
737 :[result]"=&r"(result), [tmp]"=&r"(tmp)
738 :[var1]"r"(var1)
739 );
740 return result;
741 #else
742 Word16 var_out;
743
744 if (var1 == 0)
745 {
746 var_out = 0;
747 }
748 else
749 {
750 if (var1 == -1)
751 {
752 var_out = 15;
753 }
754 else
755 {
756 if (var1 < 0)
757 {
758 var1 = (Word16)~var1;
759 }
760 for (var_out = 0; var1 < 0x4000; var_out++)
761 {
762 var1 <<= 1;
763 }
764 }
765 }
766 return (var_out);
767 #endif
768 }
769 #endif
770
771 /* Long norm, 30 */
772 #if (NORM_L_IS_INLINE)
norm_l(Word32 L_var1)773 __inline Word16 norm_l (Word32 L_var1)
774 {
775 #if ARMV5TE_NORM_L
776 Word16 result;
777 asm volatile(
778 "CMP %[L_var1], #0\n"
779 "CLZNE %[result], %[L_var1]\n"
780 "SUBNE %[result], %[result], #1\n"
781 "MOVEQ %[result], #0\n"
782 :[result]"=r"(result)
783 :[L_var1]"r"(L_var1)
784 );
785 return result;
786 #else
787 //Word16 var_out;
788
789 //if (L_var1 == 0)
790 //{
791 // var_out = 0;
792 //}
793 //else
794 //{
795 // if (L_var1 == (Word32) 0xffffffffL)
796 // {
797 // var_out = 31;
798 // }
799 // else
800 // {
801 // if (L_var1 < 0)
802 // {
803 // L_var1 = ~L_var1;
804 // }
805 // for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
806 // {
807 // L_var1 <<= 1;
808 // }
809 // }
810 //}
811 //return (var_out);
812 Word16 a16;
813 Word16 r = 0 ;
814
815
816 if ( L_var1 < 0 ) {
817 L_var1 = ~L_var1;
818 }
819
820 if (0 == (L_var1 & 0x7fff8000)) {
821 a16 = extract_l(L_var1);
822 r += 16;
823
824 if (0 == (a16 & 0x7f80)) {
825 r += 8;
826
827 if (0 == (a16 & 0x0078)) {
828 r += 4;
829
830 if (0 == (a16 & 0x0006)) {
831 r += 2;
832
833 if (0 == (a16 & 0x0001)) {
834 r += 1;
835 }
836 }
837 else {
838
839 if (0 == (a16 & 0x0004)) {
840 r += 1;
841 }
842 }
843 }
844 else {
845
846 if (0 == (a16 & 0x0060)) {
847 r += 2;
848
849 if (0 == (a16 & 0x0010)) {
850 r += 1;
851 }
852 }
853 else {
854
855 if (0 == (a16 & 0x0040)) {
856 r += 1;
857 }
858 }
859 }
860 }
861 else {
862
863 if (0 == (a16 & 0x7800)) {
864 r += 4;
865
866 if (0 == (a16 & 0x0600)) {
867 r += 2;
868
869 if (0 == (a16 & 0x0100)) {
870 r += 1;
871 }
872 }
873 else {
874
875 if (0 == (a16 & 0x0400)) {
876 r += 1;
877 }
878 }
879 }
880 else {
881
882 if (0 == (a16 & 0x6000)) {
883 r += 2;
884
885 if (0 == (a16 & 0x1000)) {
886 r += 1;
887 }
888 }
889 else {
890
891 if (0 == (a16 & 0x4000)) {
892 r += 1;
893 }
894 }
895 }
896 }
897 }
898 else {
899 a16 = extract_h(L_var1);
900
901 if (0 == (a16 & 0x7f80)) {
902 r += 8;
903
904 if (0 == (a16 & 0x0078)) {
905 r += 4 ;
906
907 if (0 == (a16 & 0x0006)) {
908 r += 2;
909
910 if (0 == (a16 & 0x0001)) {
911 r += 1;
912 }
913 }
914 else {
915
916 if (0 == (a16 & 0x0004)) {
917 r += 1;
918 }
919 }
920 }
921 else {
922
923 if (0 == (a16 & 0x0060)) {
924 r += 2;
925
926 if (0 == (a16 & 0x0010)) {
927 r += 1;
928 }
929 }
930 else {
931
932 if (0 == (a16 & 0x0040)) {
933 r += 1;
934 }
935 }
936 }
937 }
938 else {
939
940 if (0 == (a16 & 0x7800)) {
941 r += 4;
942
943 if (0 == (a16 & 0x0600)) {
944 r += 2;
945
946 if (0 == (a16 & 0x0100)) {
947 r += 1;
948 }
949 }
950 else {
951
952 if (0 == (a16 & 0x0400)) {
953 r += 1;
954 }
955 }
956 }
957 else {
958
959 if (0 == (a16 & 0x6000)) {
960 r += 2;
961
962 if (0 == (a16 & 0x1000)) {
963 r += 1;
964 }
965 }
966 else {
967
968 if (0 == (a16 & 0x4000)) {
969 return 1;
970 }
971 }
972 }
973 }
974 }
975
976 return r ;
977 #endif
978 }
979 #endif
980
981 /* Round, 1 */
982 #if (ROUND_IS_INLINE)
round16(Word32 L_var1)983 __inline Word16 round16(Word32 L_var1)
984 {
985 #if ARMV5TE_ROUND
986 Word16 result;
987 asm (
988 "QADD %[result], %[L_var1], %[bias]\n"
989 "MOV %[result], %[result], ASR #16 \n"
990 :[result]"=r"(result)
991 :[L_var1]"r"(L_var1), [bias]"r"(0x8000)
992 );
993 return result;
994 #else
995 Word16 var_out;
996 Word32 L_rounded;
997
998 L_rounded = L_add (L_var1, (Word32) 0x00008000L);
999 var_out = extract_h (L_rounded);
1000 return (var_out);
1001 #endif
1002 }
1003 #endif
1004
1005 /* Mac, 1 */
1006 #if (L_MAC_IS_INLINE)
L_mac(Word32 L_var3,Word16 var1,Word16 var2)1007 __inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
1008 {
1009 #if ARMV5TE_L_MAC
1010 Word32 result;
1011 asm (
1012 "SMULBB %[result], %[var1], %[var2]\n"
1013 "QDADD %[result], %[L_var3], %[result]\n"
1014 :[result]"=&r"(result)
1015 : [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
1016 );
1017 return result;
1018 #else
1019 Word32 L_var_out;
1020 Word32 L_product;
1021
1022 L_product = L_mult(var1, var2);
1023 L_var_out = L_add (L_var3, L_product);
1024 return (L_var_out);
1025 #endif
1026 }
1027 #endif
1028
1029 #if (L_ADD_IS_INLINE)
L_add(Word32 L_var1,Word32 L_var2)1030 __inline Word32 L_add (Word32 L_var1, Word32 L_var2)
1031 {
1032 #if ARMV5TE_L_ADD
1033 Word32 result;
1034 asm (
1035 "QADD %[result], %[L_var1], %[L_var2]\n"
1036 :[result]"=r"(result)
1037 :[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
1038 );
1039 return result;
1040 #else
1041 Word32 L_var_out;
1042
1043 L_var_out = L_var1 + L_var2;
1044 if (((L_var1 ^ L_var2) & MIN_32) == 0)
1045 {
1046 if ((L_var_out ^ L_var1) & MIN_32)
1047 {
1048 L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
1049 }
1050 }
1051 return (L_var_out);
1052 #endif
1053 }
1054 #endif
1055
1056
1057
1058 #if (MULT_R_IS_INLINE)
mult_r(Word16 var1,Word16 var2)1059 __inline Word16 mult_r (Word16 var1, Word16 var2)
1060 {
1061 Word16 var_out;
1062 Word32 L_product_arr;
1063
1064 L_product_arr = (Word32)var1 *(Word32)var2; /* product */
1065 L_product_arr += (Word32)0x00004000L; /* round */
1066 L_product_arr >>= 15; /* shift */
1067
1068 var_out = saturate(L_product_arr);
1069
1070 return (var_out);
1071 }
1072 #endif
1073
1074 #if (SHR_R_IS_INLINE)
shr_r(Word16 var1,Word16 var2)1075 __inline Word16 shr_r (Word16 var1, Word16 var2)
1076 {
1077 Word16 var_out;
1078
1079 if (var2 > 15)
1080 {
1081 var_out = 0;
1082 }
1083 else
1084 {
1085 var_out = shr(var1, var2);
1086
1087 if (var2 > 0)
1088 {
1089 if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
1090 {
1091 var_out++;
1092 }
1093 }
1094 }
1095
1096 return (var_out);
1097 }
1098 #endif
1099
1100 #if (MAC_R_IS_INLINE)
mac_r(Word32 L_var3,Word16 var1,Word16 var2)1101 __inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
1102 {
1103 Word16 var_out;
1104
1105 L_var3 = L_mac (L_var3, var1, var2);
1106 var_out = (Word16)((L_var3 + 0x8000L) >> 16);
1107
1108 return (var_out);
1109 }
1110 #endif
1111
1112 #if (MSU_R_IS_INLINE)
msu_r(Word32 L_var3,Word16 var1,Word16 var2)1113 __inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
1114 {
1115 Word16 var_out;
1116
1117 L_var3 = L_msu (L_var3, var1, var2);
1118 var_out = (Word16)((L_var3 + 0x8000L) >> 16);
1119
1120 return (var_out);
1121 }
1122 #endif
1123
1124 #if (L_SHR_R_IS_INLINE)
L_shr_r(Word32 L_var1,Word16 var2)1125 __inline Word32 L_shr_r (Word32 L_var1, Word16 var2)
1126 {
1127 Word32 L_var_out;
1128
1129 if (var2 > 31)
1130 {
1131 L_var_out = 0;
1132 }
1133 else
1134 {
1135 L_var_out = L_shr(L_var1, var2);
1136
1137 if (var2 > 0)
1138 {
1139 if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
1140 {
1141 L_var_out++;
1142 }
1143 }
1144 }
1145
1146 return (L_var_out);
1147 }
1148 #endif
1149
1150 #if (EXTRACT_H_IS_INLINE)
extract_h(Word32 L_var1)1151 __inline Word16 extract_h (Word32 L_var1)
1152 {
1153 Word16 var_out;
1154
1155 var_out = (Word16) (L_var1 >> 16);
1156
1157 return (var_out);
1158 }
1159 #endif
1160
1161 #if (EXTRACT_L_IS_INLINE)
extract_l(Word32 L_var1)1162 __inline Word16 extract_l(Word32 L_var1)
1163 {
1164 return (Word16) L_var1;
1165 }
1166 #endif
1167
1168 #endif
1169