annotate libgsmfr2/add.c @ 481:cc0c244bd233

doc/AMR-library-tests: new article
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 20 May 2024 01:02:37 +0000
parents a7b593e68ac3
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
264
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * This C source file has been adapted from TU-Berlin libgsm source,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * original notice follows:
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <stdint.h>
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <assert.h>
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include "tw_gsmfr.h"
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include "typedef.h"
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include "ed_state.h"
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include "ed_internal.h"
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 #define saturate(x) \
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 word gsm_add (word a, word b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 longword sum = (longword)a + (longword)b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 return saturate(sum);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 word gsm_sub (word a, word b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 longword diff = (longword)a - (longword)b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 return saturate(diff);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 word gsm_mult (word a, word b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 else return SASR( (longword)a * (longword)b, 15 );
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 word gsm_mult_r (word a, word b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 longword prod = (longword)a * (longword)b + 16384;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 prod >>= 15;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 return prod & 0xFFFF;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 word gsm_abs (word a)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 longword gsm_L_mult (word a, word b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 assert( a != MIN_WORD || b != MIN_WORD );
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 return ((longword)a * (longword)b) << 1;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 longword gsm_L_add (longword a, longword b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 if (a < 0) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 if (b >= 0) return a + b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 else if (b <= 0) return a + b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 ulongword A = (ulongword)a + (ulongword)b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 return A > MAX_LONGWORD ? MAX_LONGWORD : A;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 longword gsm_L_sub (longword a, longword b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 if (a >= 0) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 if (b >= 0) return a - b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 /* a>=0, b<0 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 ulongword A = (ulongword)a + -(b + 1);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 else if (b <= 0) return a - b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 /* a<0, b>0 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 ulongword A = (ulongword)-(a + 1) + b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 static unsigned char const bitoff[ 256 ] = {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 };
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 word gsm_norm (longword a)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 /*
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 * the number of left shifts needed to normalize the 32 bit
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 * variable L_var1 for positive values on the interval
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119 * with minimum of
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 * minimum of 1073741824 (01000000000000000000000000000000) and
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121 * maximum of 2147483647 (01111111111111111111111111111111)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
123 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
124 * and for negative values on the interval with
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
125 * minimum of -2147483648 (-10000000000000000000000000000000) and
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
126 * maximum of -1073741824 ( -1000000000000000000000000000000).
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
127 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
128 * in order to normalize the result, the following
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
129 * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
130 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
131 * (That's 'ffs', only from the left, not the right..)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
132 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
133 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
134 assert(a != 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
135
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
136 if (a < 0) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
137 if (a <= -1073741824) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
138 a = ~a;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
139 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
140
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
141 return a & 0xffff0000
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
142 ? ( a & 0xff000000
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
143 ? -1 + bitoff[ 0xFF & (a >> 24) ]
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
144 : 7 + bitoff[ 0xFF & (a >> 16) ] )
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
145 : ( a & 0xff00
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
146 ? 15 + bitoff[ 0xFF & (a >> 8) ]
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
147 : 23 + bitoff[ 0xFF & a ] );
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
148 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
149
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
150 longword gsm_L_asl (longword a, int n)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
151 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
152 if (n >= 32) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
153 if (n <= -32) return -(a < 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
154 if (n < 0) return gsm_L_asr(a, -n);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
155 return a << n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
156 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
157
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
158 word gsm_asl (word a, int n)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
159 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
160 if (n >= 16) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
161 if (n <= -16) return -(a < 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
162 if (n < 0) return gsm_asr(a, -n);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
163 return a << n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
164 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
165
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
166 longword gsm_L_asr (longword a, int n)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
167 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
168 if (n >= 32) return -(a < 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
169 if (n <= -32) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
170 if (n < 0) return a << -n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
171
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
172 # ifdef SASR
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
173 return a >> n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
174 # else
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
175 if (a >= 0) return a >> n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
176 else return -(longword)( -(ulongword)a >> n );
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
177 # endif
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
178 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
179
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
180 word gsm_asr (word a, int n)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
181 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
182 if (n >= 16) return -(a < 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
183 if (n <= -16) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
184 if (n < 0) return a << -n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
185
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
186 # ifdef SASR
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
187 return a >> n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
188 # else
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
189 if (a >= 0) return a >> n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
190 else return -(word)( -(uword)a >> n );
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
191 # endif
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
192 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
193
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
194 /*
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
195 * (From p. 46, end of section 4.2.5)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
196 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
197 * NOTE: The following lines gives [sic] one correct implementation
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
198 * of the div(num, denum) arithmetic operation. Compute div
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
199 * which is the integer division of num by denum: with denum
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
200 * >= num > 0
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
201 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
202
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
203 word gsm_div (word num, word denum)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
204 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
205 longword L_num = num;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
206 longword L_denum = denum;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
207 word div = 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
208 int k = 15;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
209
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
210 /* The parameter num sometimes becomes zero.
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
211 * Although this is explicitly guarded against in 4.2.5,
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
212 * we assume that the result should then be zero as well.
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
213 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
214
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
215 /* assert(num != 0); */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
216
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
217 assert(num >= 0 && denum >= num);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
218 if (num == 0)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
219 return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
220
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
221 while (k--) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
222 div <<= 1;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
223 L_num <<= 1;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
224
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
225 if (L_num >= L_denum) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
226 L_num -= L_denum;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
227 div++;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
228 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
229 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
230
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
231 return div;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
232 }