annotate libtwamr/inv_sqrt.c @ 483:4f13db3a7086

doc/Utils-overview: document new utilities
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 20 May 2024 01:26:12 +0000
parents 07f936338de1
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
253
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 *
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * R99 Version 3.3.0
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 * REL-4 Version 4.1.0
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 *
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 *
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 * File : inv_sqrt.c
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 * Purpose : Computes 1/sqrt(L_x), where L_x is positive.
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 * : If L_x is negative or zero,
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 * : the result is 1 (3fff ffff).
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 * Description :
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 * The function 1/sqrt(L_x) is approximated by a table and linear
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 * interpolation. The inverse square root is computed using the
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 * following steps:
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 * 1- Normalization of L_x.
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 * 2- If (30-exponent) is even then shift right once.
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 * 3- exponent = (30-exponent)/2 +1
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 * 4- i = bit25-b31 of L_x; 16<=i<=63 because of normalization.
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 * 5- a = bit10-b24
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 * 6- i -=16
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 * 7- L_y = table[i]<<16 - (table[i] - table[i+1]) * a * 2
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 * 8- L_y >>= exponent
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 *
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 /*
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 * MODULE INCLUDE FILE AND VERSION ID
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 #include "namespace.h"
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 #include "inv_sqrt.h"
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 /*
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 * INCLUDE FILES
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 #include "typedef.h"
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 #include "basic_op.h"
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 #include "no_count.h"
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 /*
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 * LOCAL VARIABLES AND TABLES
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 #include "inv_sqrt.tab" /* Table for inv_sqrt() */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 /*
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 * PUBLIC PROGRAM CODE
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 ********************************************************************************
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 Word32 Inv_sqrt ( /* (o) : output value */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 Word32 L_x /* (i) : input value */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 )
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 {
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 Word16 exp, i, a, tmp;
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 Word32 L_y;
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 test ();
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 if (L_x <= (Word32) 0)
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 return ((Word32) 0x3fffffffL);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 exp = norm_l (L_x);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 L_x = L_shl (L_x, exp); /* L_x is normalize */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 exp = sub (30, exp);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 test (); logic16 ();
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 if ((exp & 1) == 0) /* If exponent even -> shift right */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 {
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 L_x = L_shr (L_x, 1);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 }
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 exp = shr (exp, 1);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 exp = add (exp, 1);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 L_x = L_shr (L_x, 9);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 i = extract_h (L_x); /* Extract b25-b31 */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 L_x = L_shr (L_x, 1);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 a = extract_l (L_x); /* Extract b10-b24 */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 a = a & (Word16) 0x7fff; logic16 ();
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 i = sub (i, 16);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 L_y = L_deposit_h (table[i]); /* table[i] << 16 */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 tmp = sub (table[i], table[i + 1]); /* table[i] - table[i+1]) */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 L_y = L_msu (L_y, tmp, a); /* L_y -= tmp*a*2 */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 L_y = L_shr (L_y, exp); /* denormalization */
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 return (L_y);
54f6bc41ed10 libtwamr: integrate a* modules
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 }