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