FreeCalypso > hg > gsm-codec-lib
comparison libgsmhr1/mathdp31.c @ 503:3654df24451f
libgsmhr1/mathdp31.[ch]: import original
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Wed, 19 Jun 2024 01:16:47 +0000 |
| parents | |
| children | 024615de06fe |
comparison
equal
deleted
inserted
replaced
| 502:b0333fa167c3 | 503:3654df24451f |
|---|---|
| 1 /*************************************************************************** | |
| 2 * | |
| 3 * File Name: mathdp31.c | |
| 4 * | |
| 5 * Purpose: Contains functions increased-precision arithmetic operations. | |
| 6 * | |
| 7 * Below is a listing of all the functions in this file. There | |
| 8 * is no interdependence among the functions. | |
| 9 * | |
| 10 * L_mpy_ls() | |
| 11 * L_mpy_ll() | |
| 12 * isLwLimit() | |
| 13 * isSwLimit() | |
| 14 * | |
| 15 ***************************************************************************/ | |
| 16 /*_________________________________________________________________________ | |
| 17 | | | |
| 18 | Include Files | | |
| 19 |_________________________________________________________________________| | |
| 20 */ | |
| 21 | |
| 22 #include "mathhalf.h" | |
| 23 #include "typedefs.h" | |
| 24 | |
| 25 /**************************************************************************** | |
| 26 * | |
| 27 * FUNCTION NAME: isLwLimit | |
| 28 * | |
| 29 * PURPOSE: | |
| 30 * | |
| 31 * Check to see if the input Longword is at the | |
| 32 * upper or lower limit of its range. i.e. | |
| 33 * 0x7fff ffff or -0x8000 0000 | |
| 34 * | |
| 35 * Ostensibly this is a check for an overflow. | |
| 36 * This does not truly mean an overflow occurred, | |
| 37 * it means the value reached is the | |
| 38 * maximum/minimum value representable. It may | |
| 39 * have come about due to an overflow. | |
| 40 * | |
| 41 * INPUTS: | |
| 42 * | |
| 43 * L_In A Longword input variable | |
| 44 * | |
| 45 * | |
| 46 * OUTPUTS: none | |
| 47 * | |
| 48 * RETURN VALUE: 1 if input == 0x7fff ffff or -0x8000 0000 | |
| 49 * 0 otherwise | |
| 50 * | |
| 51 * KEYWORDS: saturation, limit | |
| 52 * | |
| 53 ***************************************************************************/ | |
| 54 | |
| 55 short isLwLimit(Longword L_In) | |
| 56 { | |
| 57 | |
| 58 Longword L_ls; | |
| 59 short siOut; | |
| 60 | |
| 61 if (L_In != 0) | |
| 62 { | |
| 63 L_ls = L_shl(L_In, 1); | |
| 64 if (L_sub(L_In, L_ls) == 0) | |
| 65 siOut = 1; | |
| 66 else | |
| 67 siOut = 0; | |
| 68 } | |
| 69 else | |
| 70 { | |
| 71 siOut = 0; | |
| 72 } | |
| 73 return (siOut); | |
| 74 } | |
| 75 | |
| 76 /**************************************************************************** | |
| 77 * | |
| 78 * FUNCTION NAME: isSwLimit | |
| 79 * | |
| 80 * PURPOSE: | |
| 81 * | |
| 82 * Check to see if the input Shortword is at the | |
| 83 * upper or lower limit of its range. i.e. | |
| 84 * 0x7fff or -0x8000 | |
| 85 * | |
| 86 * Ostensibly this is a check for an overflow. | |
| 87 * This does not truly mean an overflow occurred, | |
| 88 * it means the value reached is the | |
| 89 * maximum/minimum value representable. It may | |
| 90 * have come about due to an overflow. | |
| 91 * | |
| 92 * INPUTS: | |
| 93 * | |
| 94 * swIn A Shortword input variable | |
| 95 * | |
| 96 * | |
| 97 * OUTPUTS: none | |
| 98 * | |
| 99 * RETURN VALUE: 1 if input == 0x7fff or -0x8000 | |
| 100 * 0 otherwise | |
| 101 * | |
| 102 * KEYWORDS: saturation, limit | |
| 103 * | |
| 104 ***************************************************************************/ | |
| 105 | |
| 106 short isSwLimit(Shortword swIn) | |
| 107 { | |
| 108 | |
| 109 Shortword swls; | |
| 110 short siOut; | |
| 111 | |
| 112 if (swIn != 0) | |
| 113 { | |
| 114 swls = shl(swIn, 1); | |
| 115 if (sub(swIn, swls) == 0) /* logical compare outputs 1/0 */ | |
| 116 siOut = 1; | |
| 117 else | |
| 118 siOut = 0; | |
| 119 } | |
| 120 else | |
| 121 { | |
| 122 siOut = 0; | |
| 123 } | |
| 124 return (siOut); | |
| 125 | |
| 126 } | |
| 127 | |
| 128 /**************************************************************************** | |
| 129 * | |
| 130 * FUNCTION NAME: L_mpy_ll | |
| 131 * | |
| 132 * PURPOSE: Multiply a 32 bit number (L_var1) and a 32 bit number | |
| 133 * (L_var2), and return a 32 bit result. | |
| 134 * | |
| 135 * INPUTS: | |
| 136 * | |
| 137 * L_var1 A Longword input variable | |
| 138 * | |
| 139 * L_var2 A Longword input variable | |
| 140 * | |
| 141 * OUTPUTS: none | |
| 142 * | |
| 143 * IMPLEMENTATION: | |
| 144 * | |
| 145 * Performs a 31x31 bit multiply, Complexity=24 Ops. | |
| 146 * | |
| 147 * Let x1x0, or y1y0, be the two constituent halves | |
| 148 * of a 32 bit number. This function performs the | |
| 149 * following: | |
| 150 * | |
| 151 * low = ((x0 >> 1)*(y0 >> 1)) >> 16 (low * low) | |
| 152 * mid1 = [(x1 * (y0 >> 1)) >> 1 ] (high * low) | |
| 153 * mid2 = [(y1 * (x0 >> 1)) >> 1] (high * low) | |
| 154 * mid = (mid1 + low + mid2) >> 14 (sum so far) | |
| 155 * output = (y1*x1) + mid (high * high) | |
| 156 * | |
| 157 * | |
| 158 * RETURN VALUE: A Longword value | |
| 159 * | |
| 160 * KEYWORDS: mult,mpy,multiplication | |
| 161 * | |
| 162 ***************************************************************************/ | |
| 163 | |
| 164 Longword L_mpy_ll(Longword L_var1, Longword L_var2) | |
| 165 { | |
| 166 Shortword swLow1, | |
| 167 swLow2, | |
| 168 swHigh1, | |
| 169 swHigh2; | |
| 170 Longword L_varOut, | |
| 171 L_low, | |
| 172 L_mid1, | |
| 173 L_mid2, | |
| 174 L_mid; | |
| 175 | |
| 176 | |
| 177 swLow1 = shr(extract_l(L_var1), 1); | |
| 178 swLow1 = SW_MAX & swLow1; | |
| 179 | |
| 180 swLow2 = shr(extract_l(L_var2), 1); | |
| 181 swLow2 = SW_MAX & swLow2; | |
| 182 swHigh1 = extract_h(L_var1); | |
| 183 swHigh2 = extract_h(L_var2); | |
| 184 | |
| 185 L_low = L_mult(swLow1, swLow2); | |
| 186 L_low = L_shr(L_low, 16); | |
| 187 | |
| 188 L_mid1 = L_mult(swHigh1, swLow2); | |
| 189 L_mid1 = L_shr(L_mid1, 1); | |
| 190 L_mid = L_add(L_mid1, L_low); | |
| 191 | |
| 192 L_mid2 = L_mult(swHigh2, swLow1); | |
| 193 L_mid2 = L_shr(L_mid2, 1); | |
| 194 L_mid = L_add(L_mid, L_mid2); | |
| 195 | |
| 196 L_mid = L_shr(L_mid, 14); | |
| 197 L_varOut = L_mac(L_mid, swHigh1, swHigh2); | |
| 198 | |
| 199 return (L_varOut); | |
| 200 } | |
| 201 | |
| 202 /**************************************************************************** | |
| 203 * | |
| 204 * FUNCTION NAME: L_mpy_ls | |
| 205 * | |
| 206 * PURPOSE: Multiply a 32 bit number (L_var2) and a 16 bit | |
| 207 * number (var1) returning a 32 bit result. L_var2 | |
| 208 * is truncated to 31 bits prior to executing the | |
| 209 * multiply. | |
| 210 * | |
| 211 * INPUTS: | |
| 212 * | |
| 213 * L_var2 A Longword input variable | |
| 214 * | |
| 215 * var1 A Shortword input variable | |
| 216 * | |
| 217 * OUTPUTS: none | |
| 218 * | |
| 219 * RETURN VALUE: A Longword value | |
| 220 * | |
| 221 * KEYWORDS: mult,mpy,multiplication | |
| 222 * | |
| 223 ***************************************************************************/ | |
| 224 | |
| 225 Longword L_mpy_ls(Longword L_var2, Shortword var1) | |
| 226 { | |
| 227 Longword L_varOut; | |
| 228 Shortword swtemp; | |
| 229 | |
| 230 swtemp = shr(extract_l(L_var2), 1); | |
| 231 swtemp = (short) 32767 & (short) swtemp; | |
| 232 | |
| 233 L_varOut = L_mult(var1, swtemp); | |
| 234 L_varOut = L_shr(L_varOut, 15); | |
| 235 L_varOut = L_mac(L_varOut, var1, extract_h(L_var2)); | |
| 236 return (L_varOut); | |
| 237 } |
