add.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
00003  * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
00004  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
00005  */
00006 
00007 /* $Header$ */
00008 
00009 /*
00010  *  See private.h for the more commonly used macro versions.
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 (word)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 (word)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 (word)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 (word)(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          /* a>=0, b<0 */
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       /* a<0, b>0 */  
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  * the number of left shifts needed to normalize the 32 bit
00120  * variable L_var1 for positive values on the interval
00121  *
00122  * with minimum of
00123  * minimum of 1073741824  (01000000000000000000000000000000) and 
00124  * maximum of 2147483647  (01111111111111111111111111111111)
00125  *
00126  *
00127  * and for negative values on the interval with
00128  * minimum of -2147483648 (-10000000000000000000000000000000) and
00129  * maximum of -1073741824 ( -1000000000000000000000000000000).
00130  *
00131  * in order to normalize the result, the following
00132  * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
00133  *
00134  * (That's 'ffs', only from the left, not the right..)
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  *  (From p. 46, end of section 4.2.5)
00199  *
00200  *  NOTE: The following lines gives [sic] one correct implementation
00201  *      of the div(num, denum) arithmetic operation.  Compute div
00202  *        which is the integer division of num by denum: with denum
00203  *   >= num > 0
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    /* The parameter num sometimes becomes zero.
00214     * Although this is explicitly guarded against in 4.2.5,
00215     * we assume that the result should then be zero as well.
00216     */
00217 
00218    /* assert(num != 0); */
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 }

Generated on Thu Apr 16 06:27:06 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6