6f4eb5cc5fcc239d392add1c8fafe7ffa0c6cbdc
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.
8 * See private.h for the more commonly used macro versions.
14 #include "gsm610_priv.h"
17 ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
19 word
gsm_add ( word a
, word b
)
21 longword sum
= (longword
)a
+ (longword
)b
;
25 word
gsm_sub ( word a
, word b
)
27 longword diff
= (longword
)a
- (longword
)b
;
28 return saturate(diff
);
31 word
gsm_mult ( word a
, word b
)
33 if (a
== MIN_WORD
&& b
== MIN_WORD
)
36 return SASR_L( (longword
)a
* (longword
)b
, 15 );
39 word
gsm_mult_r ( word a
, word b
)
41 if (b
== MIN_WORD
&& a
== MIN_WORD
) return MAX_WORD
;
43 longword prod
= (longword
)a
* (longword
)b
+ 16384;
51 return a
< 0 ? (a
== MIN_WORD
? MAX_WORD
: -a
) : a
;
54 longword
gsm_L_mult (word a
, word b
)
56 assert( a
!= MIN_WORD
|| b
!= MIN_WORD
);
57 return ((longword
)a
* (longword
)b
) << 1;
60 longword
gsm_L_add ( longword a
, longword b
)
63 if (b
>= 0) return a
+ b
;
65 ulongword A
= (ulongword
)-(a
+ 1) + (ulongword
)-(b
+ 1);
66 return A
>= MAX_LONGWORD
? MIN_LONGWORD
:-(longword
)A
-2;
69 else if (b
<= 0) return a
+ b
;
71 ulongword A
= (ulongword
)a
+ (ulongword
)b
;
72 return A
> MAX_LONGWORD
? MAX_LONGWORD
: A
;
76 longword
gsm_L_sub ( longword a
, longword b
)
79 if (b
>= 0) return a
- b
;
83 ulongword A
= (ulongword
)a
+ -(b
+ 1);
84 return A
>= MAX_LONGWORD
? MAX_LONGWORD
: (A
+ 1);
87 else if (b
<= 0) return a
- b
;
91 ulongword A
= (ulongword
)-(a
+ 1) + b
;
92 return A
>= MAX_LONGWORD
? MIN_LONGWORD
: -(longword
)A
- 1;
96 static unsigned char const bitoff
[ 256 ] = {
97 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
98 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
99 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
100 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
101 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
102 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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
115 word
gsm_norm (longword a
)
117 * the number of left shifts needed to normalize the 32 bit
118 * variable L_var1 for positive values on the interval
121 * minimum of 1073741824 (01000000000000000000000000000000) and
122 * maximum of 2147483647 (01111111111111111111111111111111)
125 * and for negative values on the interval with
126 * minimum of -2147483648 (-10000000000000000000000000000000) and
127 * maximum of -1073741824 ( -1000000000000000000000000000000).
129 * in order to normalize the result, the following
130 * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
132 * (That's 'ffs', only from the left, not the right..)
138 if (a
<= -1073741824) return 0;
142 return a
& 0xffff0000
144 ? -1 + bitoff
[ 0xFF & (a
>> 24) ]
145 : 7 + bitoff
[ 0xFF & (a
>> 16) ] )
147 ? 15 + bitoff
[ 0xFF & (a
>> 8) ]
148 : 23 + bitoff
[ 0xFF & a
] );
151 longword
gsm_L_asl (longword a
, int n
)
153 if (n
>= 32) return 0;
154 if (n
<= -32) return -(a
< 0);
155 if (n
< 0) return gsm_L_asr(a
, -n
);
159 word
gsm_asr (word a
, int n
)
161 if (n
>= 16) return -(a
< 0);
162 if (n
<= -16) return 0;
163 if (n
< 0) return a
<< -n
;
165 return SASR_W (a
, (word
) n
);
168 word
gsm_asl (word a
, int n
)
170 if (n
>= 16) return 0;
171 if (n
<= -16) return -(a
< 0);
172 if (n
< 0) return gsm_asr(a
, -n
);
176 longword
gsm_L_asr (longword a
, int n
)
178 if (n
>= 32) return -(a
< 0);
179 if (n
<= -32) return 0;
180 if (n
< 0) return a
<< -n
;
182 return SASR_L (a
, (word
) n
);
186 ** word gsm_asr (word a, int n)
188 ** if (n >= 16) return -(a < 0);
189 ** if (n <= -16) return 0;
190 ** if (n < 0) return a << -n;
195 ** if (a >= 0) return a >> n;
196 ** else return -(word)( -(uword)a >> n );
202 * (From p. 46, end of section 4.2.5)
204 * NOTE: The following lines gives [sic] one correct implementation
205 * of the div(num, denum) arithmetic operation. Compute div
206 * which is the integer division of num by denum: with denum
210 word
gsm_div (word num
, word denum
)
212 longword L_num
= num
;
213 longword L_denum
= denum
;
217 /* The parameter num sometimes becomes zero.
218 * Although this is explicitly guarded against in 4.2.5,
219 * we assume that the result should then be zero as well.
222 /* assert(num != 0); */
224 assert(num
>= 0 && denum
>= num
);
232 if (L_num
>= L_denum
) {