annotate libgsmfr2/add.c @ 264:8b21a6b7a3bf

libgsmfr2: beginning to integrate TU-Berlin code guts
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 14 Apr 2024 00:06:50 +0000
parents
children a7b593e68ac3
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 <string.h>
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include "tw_gsmfr.h"
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include "typedef.h"
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include "ed_state.h"
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 #include "ed_internal.h"
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 #define saturate(x) \
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 ((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
20
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 word gsm_add (word a, word b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 longword sum = (longword)a + (longword)b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 return saturate(sum);
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 word gsm_sub (word a, word b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 longword diff = (longword)a - (longword)b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 return saturate(diff);
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 word gsm_mult (word a, word b)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 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
36 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
37 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 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
40 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 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
42 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 longword prod = (longword)a * (longword)b + 16384;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 prod >>= 15;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 return prod & 0xFFFF;
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 word gsm_abs (word a)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 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
52 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 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
55 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 assert( a != MIN_WORD || b != MIN_WORD );
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 return ((longword)a * (longword)b) << 1;
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 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
61 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 if (a < 0) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 if (b >= 0) return a + b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 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
66 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
67 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 else if (b <= 0) return a + b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 ulongword A = (ulongword)a + (ulongword)b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 return A > MAX_LONGWORD ? MAX_LONGWORD : A;
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 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
77 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 if (a >= 0) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 if (b >= 0) return a - b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 /* a>=0, b<0 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 ulongword A = (ulongword)a + -(b + 1);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 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
85 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 }
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 else if (b <= 0) return a - b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 else {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 /* a<0, b>0 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 ulongword A = (ulongword)-(a + 1) + b;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 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
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 static unsigned char const bitoff[ 256 ] = {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 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
98 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
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 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
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 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
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 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
113 };
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 word gsm_norm (longword a)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 /*
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 * 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
118 * 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
119 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 * with minimum of
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121 * minimum of 1073741824 (01000000000000000000000000000000) and
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 * maximum of 2147483647 (01111111111111111111111111111111)
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 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
125 * 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
126 * minimum of -2147483648 (-10000000000000000000000000000000) and
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
127 * maximum of -1073741824 ( -1000000000000000000000000000000).
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
128 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
129 * 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
130 * 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
131 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
132 * (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
133 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
134 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
135 assert(a != 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
136
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
137 if (a < 0) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
138 if (a <= -1073741824) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
139 a = ~a;
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
142 return a & 0xffff0000
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
143 ? ( a & 0xff000000
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
144 ? -1 + bitoff[ 0xFF & (a >> 24) ]
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
145 : 7 + bitoff[ 0xFF & (a >> 16) ] )
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
146 : ( a & 0xff00
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
147 ? 15 + bitoff[ 0xFF & (a >> 8) ]
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
148 : 23 + bitoff[ 0xFF & a ] );
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
151 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
152 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
153 if (n >= 32) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
154 if (n <= -32) return -(a < 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
155 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
156 return a << n;
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
159 word gsm_asl (word a, int n)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
160 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
161 if (n >= 16) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
162 if (n <= -16) return -(a < 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
163 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
164 return a << n;
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
167 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
168 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
169 if (n >= 32) return -(a < 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
170 if (n <= -32) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
171 if (n < 0) return a << -n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
172
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
173 # ifdef SASR
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
174 return a >> n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
175 # else
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
176 if (a >= 0) return a >> n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
177 else return -(longword)( -(ulongword)a >> n );
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
178 # endif
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
181 word gsm_asr (word a, int n)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
182 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
183 if (n >= 16) return -(a < 0);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
184 if (n <= -16) return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
185 if (n < 0) return a << -n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
186
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
187 # ifdef SASR
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
188 return a >> n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
189 # else
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
190 if (a >= 0) return a >> n;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
191 else return -(word)( -(uword)a >> n );
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
192 # endif
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 /*
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
196 * (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
197 *
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
198 * 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
199 * 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
200 * 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
201 * >= num > 0
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
204 word gsm_div (word num, word denum)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
205 {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
206 longword L_num = num;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
207 longword L_denum = denum;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
208 word div = 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
209 int k = 15;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
210
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
211 /* The parameter num sometimes becomes zero.
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
212 * 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
213 * 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
214 */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
215
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
216 /* assert(num != 0); */
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
217
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
218 assert(num >= 0 && denum >= num);
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
219 if (num == 0)
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
220 return 0;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
221
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
222 while (k--) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
223 div <<= 1;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
224 L_num <<= 1;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
225
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
226 if (L_num >= L_denum) {
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
227 L_num -= L_denum;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
228 div++;
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
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
232 return div;
8b21a6b7a3bf libgsmfr2: beginning to integrate TU-Berlin code guts
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
233 }