comparison intercom/gsm/add.c @ 2:13be24d74cd2

import intercom-0.4.1
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 09:57:52 +0200
parents
children
comparison
equal deleted inserted replaced
1:9cadc470e3da 2:13be24d74cd2
1 /*
2 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
3 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
4 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
5 */
6
7 /* $Header: /home/kbs/jutta/src/gsm/gsm-1.0/src/RCS/add.c,v 1.2 1993/01/29 18:23:15 jutta Exp $ */
8
9 /*
10 * See private.h for the more commonly used macro versions.
11 */
12
13 #include <stdio.h>
14 #include <assert.h>
15
16 #include "private.h"
17 #include "gsm.h"
18 #include "proto.h"
19
20 #define saturate(x) \
21 ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
22
23 word gsm_add P2((a, b), word a, word b)
24 {
25 longword sum = (longword) a + (longword) b;
26 return saturate(sum);
27 }
28
29 word gsm_sub P2((a, b), word a, word b)
30 {
31 longword diff = (longword) a - (longword) b;
32 return saturate(diff);
33 }
34
35 word gsm_mult P2((a, b), word a, word b)
36 {
37 if (a == MIN_WORD && b == MIN_WORD)
38 return MAX_WORD;
39 else
40 return (word) (SASR((longword) a * (longword) b, 15));
41 }
42
43 word gsm_mult_r P2((a, b), word a, word b)
44 {
45 if (b == MIN_WORD && a == MIN_WORD)
46 return MAX_WORD;
47 else {
48 longword prod = (longword) a * (longword) b + 16384;
49 prod >>= 15;
50 return prod & 0xFFFF;
51 }
52 }
53
54 word gsm_abs P1((a), word a)
55 {
56 return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
57 }
58
59 longword gsm_L_mult P2((a, b), word a, word b)
60 {
61 assert(a != MIN_WORD || b != MIN_WORD);
62 return ((longword) a * (longword) b) << 1;
63 }
64
65 longword gsm_L_add P2((a, b), longword a, longword b)
66 {
67 if (a < 0) {
68 if (b >= 0)
69 return a + b;
70 else {
71 ulongword A = (ulongword) - (a + 1) + (ulongword) - (b + 1);
72 return A >=
73 (ulongword) MAX_LONGWORD ? MIN_LONGWORD : -(longword) A - 2;
74 }
75 } else if (b <= 0)
76 return a + b;
77 else {
78 ulongword A = (ulongword) a + (ulongword) b;
79 return A > (ulongword) MAX_LONGWORD ? MAX_LONGWORD : A;
80 }
81 }
82
83 longword gsm_L_sub P2((a, b), longword a, longword b)
84 {
85 if (a >= 0) {
86 if (b >= 0)
87 return a - b;
88 else {
89 /* a>=0, b<0 */
90
91 ulongword A = (ulongword) a + -(b + 1);
92 return A >= (ulongword) MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
93 }
94 } else if (b <= 0)
95 return a - b;
96 else {
97 /* a<0, b>0 */
98
99 ulongword A = (ulongword) - (a + 1) + b;
100 return A >= (ulongword) MAX_LONGWORD ? MIN_LONGWORD : -A - 1;
101 }
102 }
103
104 static unsigned char bitoff[256] = {
105 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
106 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
107 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
108 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
109 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
110 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
111 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
112 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
121 };
122
123 word gsm_norm P1((a), longword a)
124 /*
125 * the number of left shifts needed to normalize the 32 bit
126 * variable L_var1 for positive values on the interval
127 *
128 * with minimum of
129 * minimum of 1073741824 (01000000000000000000000000000000) and
130 * maximum of 2147483647 (01111111111111111111111111111111)
131 *
132 *
133 * and for negative values on the interval with
134 * minimum of -2147483648 (-10000000000000000000000000000000) and
135 * maximum of -1073741824 ( -1000000000000000000000000000000).
136 *
137 * in order to normalize the result, the following
138 * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
139 *
140 * (That's 'ffs', only from the left, not the right..)
141 */
142 {
143 assert(a != 0);
144
145 if (a < 0) {
146 if (a <= (longword) - 1073741824)
147 return 0;
148 a = ~a;
149 }
150
151 return a & 0xffff0000
152 ? (a & 0xff000000 ? -1 + bitoff[(unsigned char) (0xFF & (a >> 24))]
153 : 7 + bitoff[(unsigned char) (0xFF & (a >> 16))])
154 : (a & 0xff00 ? 15 + bitoff[(unsigned char) (0xFF & (a >> 8))]
155 : 23 + bitoff[(unsigned char) (0xFF & a)]);
156 }
157
158 longword gsm_L_asl P2((a, n), longword a, int n)
159 {
160 if (n >= 32)
161 return 0;
162 if (n <= -32)
163 return -(a < 0);
164 if (n < 0)
165 return gsm_asr(a, -n);
166 return a << n;
167 }
168
169 word gsm_asl P2((a, n), word a, int n)
170 {
171 if (n >= 16)
172 return 0;
173 if (n <= -16)
174 return -(a < 0);
175 if (n < 0)
176 return gsm_asr(a, -n);
177 return a << n;
178 }
179
180 longword gsm_L_asr P2((a, n), longword a, int n)
181 {
182 if (n >= 32)
183 return -(a < 0);
184 if (n <= -32)
185 return 0;
186 if (n < 0)
187 return a << -n;
188
189 # ifdef SASR
190 return a >> n;
191 # else
192 if (a >= 0)
193 return a >> n;
194 else
195 return -(longword) (-(ulongword) a >> n);
196 # endif
197 }
198
199 word gsm_asr P2((a, n), word a, int n)
200 {
201 if (n >= 16)
202 return -(a < 0);
203 if (n <= -16)
204 return 0;
205 if (n < 0)
206 return a << -n;
207
208 # ifdef SASR
209 return a >> n;
210 # else
211 if (a >= 0)
212 return a >> n;
213 else
214 return -(word) (-(uword) a >> n);
215 # endif
216 }
217
218 /*
219 * (From p. 46, end of section 4.2.5)
220 *
221 * NOTE: The following lines gives [sic] one correct implementation
222 * of the div(num, denum) arithmetic operation. Compute div
223 * which is the integer division of num by denum: with denum
224 * >= num > 0
225 */
226
227 word gsm_div P2((num, denum), word num, word denum)
228 {
229 longword L_num = num;
230 longword L_denum = denum;
231 word div = 0;
232 int k = 15;
233
234 /* The parameter num sometimes becomes zero.
235 * Although this is explicitly guarded against in 4.2.5,
236 * we assume that the result should then be zero as well.
237 */
238
239 /* assert(num != 0); */
240
241 assert(num >= 0 && denum >= num);
242 if (num == 0)
243 return 0;
244
245 while (k--) {
246 div <<= 1;
247 L_num <<= 1;
248
249 if (L_num >= L_denum) {
250 L_num -= L_denum;
251 div++;
252 }
253 }
254
255 return div;
256 }

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.