jni/gsm/add.c
changeset 823 2036ebfaccda
equal deleted inserted replaced
536:537ddd8aa407 823:2036ebfaccda
       
     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: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/add.c,v 1.6 1996/07/02 09:57:33 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) return MAX_WORD;
       
    38 	else return 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 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 }