00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdio.h>
00014 #include <assert.h>
00015
00016 #include "private.h"
00017 #include "gsm.h"
00018 #include "proto.h"
00019
00020 #define saturate(x) \
00021 ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
00022
00023 word gsm_add P2((a,b), word a, word b)
00024 {
00025 longword sum = (longword)a + (longword)b;
00026 return saturate(sum);
00027 }
00028
00029 word gsm_sub P2((a,b), word a, word b)
00030 {
00031 longword diff = (longword)a - (longword)b;
00032 return saturate(diff);
00033 }
00034
00035 word gsm_mult P2((a,b), word a, word b)
00036 {
00037 if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;
00038 else return SASR( (longword)a * (longword)b, 15 );
00039 }
00040
00041 word gsm_mult_r P2((a,b), word a, word b)
00042 {
00043 if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
00044 else {
00045 longword prod = (longword)a * (longword)b + 16384;
00046 prod >>= 15;
00047 return prod & 0xFFFF;
00048 }
00049 }
00050
00051 word gsm_abs P1((a), word a)
00052 {
00053 return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
00054 }
00055
00056 longword gsm_L_mult P2((a,b),word a, word b)
00057 {
00058 assert( a != MIN_WORD || b != MIN_WORD );
00059 return ((longword)a * (longword)b) << 1;
00060 }
00061
00062 longword gsm_L_add P2((a,b), longword a, longword b)
00063 {
00064 if (a < 0) {
00065 if (b >= 0) return a + b;
00066 else {
00067 ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
00068 return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
00069 }
00070 }
00071 else if (b <= 0) return a + b;
00072 else {
00073 ulongword A = (ulongword)a + (ulongword)b;
00074 return A > MAX_LONGWORD ? MAX_LONGWORD : A;
00075 }
00076 }
00077
00078 longword gsm_L_sub P2((a,b), longword a, longword b)
00079 {
00080 if (a >= 0) {
00081 if (b >= 0) return a - b;
00082 else {
00083
00084
00085 ulongword A = (ulongword)a + -(b + 1);
00086 return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
00087 }
00088 }
00089 else if (b <= 0) return a - b;
00090 else {
00091
00092
00093 ulongword A = (ulongword)-(a + 1) + b;
00094 return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
00095 }
00096 }
00097
00098 static unsigned char const bitoff[ 256 ] = {
00099 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
00100 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
00101 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00102 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00103 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00104 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00105 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00106 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00115 };
00116
00117 word gsm_norm P1((a), longword a )
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 {
00137 assert(a != 0);
00138
00139 if (a < 0) {
00140 if (a <= -1073741824) return 0;
00141 a = ~a;
00142 }
00143
00144 return a & 0xffff0000
00145 ? ( a & 0xff000000
00146 ? -1 + bitoff[ 0xFF & (a >> 24) ]
00147 : 7 + bitoff[ 0xFF & (a >> 16) ] )
00148 : ( a & 0xff00
00149 ? 15 + bitoff[ 0xFF & (a >> 8) ]
00150 : 23 + bitoff[ 0xFF & a ] );
00151 }
00152
00153 longword gsm_L_asl P2((a,n), longword a, int n)
00154 {
00155 if (n >= 32) return 0;
00156 if (n <= -32) return -(a < 0);
00157 if (n < 0) return gsm_L_asr(a, -n);
00158 return a << n;
00159 }
00160
00161 word gsm_asl P2((a,n), word a, int n)
00162 {
00163 if (n >= 16) return 0;
00164 if (n <= -16) return -(a < 0);
00165 if (n < 0) return gsm_asr(a, -n);
00166 return a << n;
00167 }
00168
00169 longword gsm_L_asr P2((a,n), longword a, int n)
00170 {
00171 if (n >= 32) return -(a < 0);
00172 if (n <= -32) return 0;
00173 if (n < 0) return a << -n;
00174
00175 # ifdef SASR
00176 return a >> n;
00177 # else
00178 if (a >= 0) return a >> n;
00179 else return -(longword)( -(ulongword)a >> n );
00180 # endif
00181 }
00182
00183 word gsm_asr P2((a,n), word a, int n)
00184 {
00185 if (n >= 16) return -(a < 0);
00186 if (n <= -16) return 0;
00187 if (n < 0) return a << -n;
00188
00189 # ifdef SASR
00190 return a >> n;
00191 # else
00192 if (a >= 0) return a >> n;
00193 else return -(word)( -(uword)a >> n );
00194 # endif
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 word gsm_div P2((num,denum), word num, word denum)
00207 {
00208 longword L_num = num;
00209 longword L_denum = denum;
00210 word div = 0;
00211 int k = 15;
00212
00213
00214
00215
00216
00217
00218
00219
00220 assert(num >= 0 && denum >= num);
00221 if (num == 0)
00222 return 0;
00223
00224 while (k--) {
00225 div <<= 1;
00226 L_num <<= 1;
00227
00228 if (L_num >= L_denum) {
00229 L_num -= L_denum;
00230 div++;
00231 }
00232 }
00233
00234 return div;
00235 }