Asterisk - The Open Source Telephony Project  18.5.0
add.c
Go to the documentation of this file.
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$ */
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 (word)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 (word)saturate(diff);
33 }
34 
35 word gsm_mult P2((a,b), word a, word b)
36 {
37  if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;
38  else return (word)SASR( (longword)a * (longword)b, 15 );
39 }
40 
41 word gsm_mult_r P2((a,b), word a, word b)
42 {
43  if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
44  else {
45  longword prod = (longword)a * (longword)b + 16384;
46  prod >>= 15;
47  return (word)(prod & 0xFFFF);
48  }
49 }
50 
51 word gsm_abs P1((a), word a)
52 {
53  return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
54 }
55 
56 longword gsm_L_mult P2((a,b),word a, word b)
57 {
58  assert( a != MIN_WORD || b != MIN_WORD );
59  return ((longword)a * (longword)b) << 1;
60 }
61 
62 longword gsm_L_add P2((a,b), longword a, longword b)
63 {
64  if (a < 0) {
65  if (b >= 0) return a + b;
66  else {
67  ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
68  return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
69  }
70  }
71  else if (b <= 0) return a + b;
72  else {
73  ulongword A = (ulongword)a + (ulongword)b;
74  return A > MAX_LONGWORD ? MAX_LONGWORD : A;
75  }
76 }
77 
78 longword gsm_L_sub P2((a,b), longword a, longword b)
79 {
80  if (a >= 0) {
81  if (b >= 0) return a - b;
82  else {
83  /* a>=0, b<0 */
84 
85  ulongword A = (ulongword)a + -(b + 1);
86  return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
87  }
88  }
89  else if (b <= 0) return a - b;
90  else {
91  /* a<0, b>0 */
92 
93  ulongword A = (ulongword)-(a + 1) + b;
94  return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
95  }
96 }
97 
98 static unsigned char const bitoff[ 256 ] = {
99  8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
100  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
101  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
102  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
103  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
104  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
105  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
106  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
107  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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 };
116 
117 word gsm_norm P1((a), longword a )
118 /*
119  * the number of left shifts needed to normalize the 32 bit
120  * variable L_var1 for positive values on the interval
121  *
122  * with minimum of
123  * minimum of 1073741824 (01000000000000000000000000000000) and
124  * maximum of 2147483647 (01111111111111111111111111111111)
125  *
126  *
127  * and for negative values on the interval with
128  * minimum of -2147483648 (-10000000000000000000000000000000) and
129  * maximum of -1073741824 ( -1000000000000000000000000000000).
130  *
131  * in order to normalize the result, the following
132  * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
133  *
134  * (That's 'ffs', only from the left, not the right..)
135  */
136 {
137  assert(a != 0);
138 
139  if (a < 0) {
140  if (a <= -1073741824) return 0;
141  a = ~a;
142  }
143 
144  return a & 0xffff0000
145  ? ( a & 0xff000000
146  ? -1 + bitoff[ 0xFF & (a >> 24) ]
147  : 7 + bitoff[ 0xFF & (a >> 16) ] )
148  : ( a & 0xff00
149  ? 15 + bitoff[ 0xFF & (a >> 8) ]
150  : 23 + bitoff[ 0xFF & a ] );
151 }
152 
153 longword gsm_L_asl P2((a,n), longword a, int n)
154 {
155  if (n >= 32) return 0;
156  if (n <= -32) return -(a < 0);
157  if (n < 0) return gsm_L_asr(a, -n);
158  return a << n;
159 }
160 
161 word gsm_asl P2((a,n), word a, int n)
162 {
163  if (n >= 16) return 0;
164  if (n <= -16) return -(a < 0);
165  if (n < 0) return gsm_asr(a, -n);
166  return a << n;
167 }
168 
169 longword gsm_L_asr P2((a,n), longword a, int n)
170 {
171  if (n >= 32) return -(a < 0);
172  if (n <= -32) return 0;
173  if (n < 0) return a << -n;
174 
175 # ifdef SASR
176  return a >> n;
177 # else
178  if (a >= 0) return a >> n;
179  else return -(longword)( -(ulongword)a >> n );
180 # endif
181 }
182 
183 word gsm_asr P2((a,n), word a, int n)
184 {
185  if (n >= 16) return -(a < 0);
186  if (n <= -16) return 0;
187  if (n < 0) return a << -n;
188 
189 # ifdef SASR
190  return a >> n;
191 # else
192  if (a >= 0) return a >> n;
193  else return -(word)( -(uword)a >> n );
194 # endif
195 }
196 
197 /*
198  * (From p. 46, end of section 4.2.5)
199  *
200  * NOTE: The following lines gives [sic] one correct implementation
201  * of the div(num, denum) arithmetic operation. Compute div
202  * which is the integer division of num by denum: with denum
203  * >= num > 0
204  */
205 
206 word gsm_div P2((num,denum), word num, word denum)
207 {
208  longword L_num = num;
209  longword L_denum = denum;
210  word div = 0;
211  int k = 15;
212 
213  /* The parameter num sometimes becomes zero.
214  * Although this is explicitly guarded against in 4.2.5,
215  * we assume that the result should then be zero as well.
216  */
217 
218  /* assert(num != 0); */
219 
220  assert(num >= 0 && denum >= num);
221  if (num == 0)
222  return 0;
223 
224  while (k--) {
225  div <<= 1;
226  L_num <<= 1;
227 
228  if (L_num >= L_denum) {
229  L_num -= L_denum;
230  div++;
231  }
232  }
233 
234  return div;
235 }
static unsigned char const bitoff[256]
Definition: add.c:98
#define saturate(x)
Definition: add.c:20
word gsm_abs P1((a), word a)
Definition: add.c:51
#define MAX_WORD
#define SASR(x, by)
word gsm_add P2((a, b), word a, word b)
Definition: add.c:23
unsigned short uword
#define MIN_LONGWORD
#define MAX_LONGWORD
static struct test_val b
#define MIN_WORD
long longword
unsigned long ulongword
short word
static struct test_val a