Line data Source code
1 : /*****************************************************************************
2 : * $Id: oper_32b.c 1094 2014-02-10 17:12:11Z jdr $
3 : *
4 : * This file contains operations in double precision. *
5 : * These operations are not standard double precision operations. *
6 : * They are used where single precision is not enough but the full 32 bits *
7 : * precision is not necessary. For example, the function Div_32() has a *
8 : * 24 bits precision which is enough for our purposes. *
9 : * *
10 : * The double precision numbers use a special representation: *
11 : * *
12 : * L_32 = hi<<16 + lo<<1 *
13 : * *
14 : * L_32 is a 32 bit integer. *
15 : * hi and lo are 16 bit signed integers. *
16 : * As the low part also contains the sign, this allows fast multiplication. *
17 : * *
18 : * 0x8000 0000 <= L_32 <= 0x7fff fffe. *
19 : * *
20 : * We will use DPF (Double Precision Format) in this file to specify *
21 : * this special format. *
22 : *****************************************************************************
23 : */
24 :
25 : #include "stl.h"
26 : #include "basop32.h"
27 :
28 : #define WMC_TOOL_SKIP
29 :
30 : /*****************************************************************************
31 : * *
32 : * Function L_Extract() *
33 : * *
34 : * Extract from a 32 bit integer two 16 bit DPF. *
35 : * *
36 : * Arguments: *
37 : * *
38 : * L_32 : 32 bit integer. *
39 : * 0x8000 0000 <= L_32 <= 0x7fff ffff. *
40 : * hi : b16 to b31 of L_32 *
41 : * lo : (L_32 - hi<<16)>>1 *
42 : *****************************************************************************
43 : */
44 :
45 545589512 : void L_Extract( Word32 L_32, Word16 *hi, Word16 *lo )
46 : {
47 545589512 : *hi = extract_h( L_32 );
48 545589512 : *lo = extract_l( L_msu( L_shr( L_32, 1 ), *hi, 16384 ) );
49 545589512 : return;
50 : }
51 :
52 : /*****************************************************************************
53 : * *
54 : * Function L_Extract_lc() *
55 : * *
56 : * Extract from a 32 bit integer two 16 bit DPF. *
57 : * (lo is returned, store to memory is not accounted for) *
58 : * *
59 : * Arguments: *
60 : * *
61 : * L_32 : 32 bit integer. *
62 : * 0x8000 0000 <= L_32 <= 0x7fff ffff. *
63 : * hi : b16 to b31 of L_32 *
64 : * lo : (L_32 - hi<<16)>>1 *
65 : *****************************************************************************
66 : */
67 :
68 219881306 : Word16 L_Extract_lc( Word32 L_32, Word16 *hi )
69 : {
70 219881306 : *hi = extract_h( L_32 );
71 :
72 219881306 : return lshr( extract_l( L_32 ), 1 );
73 : }
74 :
75 : /*****************************************************************************
76 : * *
77 : * Function L_Comp() *
78 : * *
79 : * Compose from two 16 bit DPF a 32 bit integer. *
80 : * *
81 : * L_32 = hi<<16 + lo<<1 *
82 : * *
83 : * Arguments: *
84 : * *
85 : * hi msb *
86 : * lo lsf (with sign) *
87 : * *
88 : * Return Value : *
89 : * *
90 : * 32 bit long signed integer (Word32) whose value falls in the *
91 : * range : 0x8000 0000 <= L_32 <= 0x7fff fff0. *
92 : * *
93 : *****************************************************************************
94 : */
95 :
96 486104166 : Word32 L_Comp( Word16 hi, Word16 lo )
97 : {
98 : Word32 L_32;
99 :
100 486104166 : L_32 = L_deposit_h( hi );
101 486104166 : return ( L_mac( L_32, lo, 1 ) ); /* = hi<<16 + lo<<1 */
102 : }
103 :
104 : /*****************************************************************************
105 : * Function Mpy_32() *
106 : * *
107 : * Multiply two 32 bit integers (DPF). The result is divided by 2**31 *
108 : * *
109 : * L_32 = (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 *
110 : * *
111 : * This operation can also be viewed as the multiplication of two Q31 *
112 : * number and the result is also in Q31. *
113 : * *
114 : * Arguments: *
115 : * *
116 : * hi1 hi part of first number *
117 : * lo1 lo part of first number *
118 : * hi2 hi part of second number *
119 : * lo2 lo part of second number *
120 : * *
121 : *****************************************************************************
122 : */
123 :
124 98610782 : Word32 Mpy_32( Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2 )
125 : {
126 : Word32 L_32;
127 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
128 98610782 : Flag Overflow = 0;
129 : #endif
130 :
131 98610782 : L_32 = L_mult( hi1, hi2 );
132 98610782 : L_32 = L_mac_o( L_32, mult( hi1, lo2 ), 1, &Overflow );
133 98610782 : L_32 = L_mac_o( L_32, mult( lo1, hi2 ), 1, &Overflow );
134 :
135 98610782 : return ( L_32 );
136 : }
137 :
138 : /*****************************************************************************
139 : * Function Mac_32() *
140 : * *
141 : * Multiply two 32 bit integers (DPF). The result is divided by 2**31 *
142 : * Adds a 32 bit integer (non DFP) *
143 : * *
144 : * L_32 = L_num + (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 *
145 : * *
146 : * This operation can also be viewed as the multiplication of two Q31 *
147 : * number and the result is also in Q31. *
148 : * *
149 : * Arguments: *
150 : * *
151 : * hi1 hi part of first number *
152 : * lo1 lo part of first number *
153 : * hi2 hi part of second number *
154 : * lo2 lo part of second number *
155 : * *
156 : *****************************************************************************
157 : */
158 :
159 709662444 : Word32 Mac_32( Word32 L_num, Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2 )
160 : {
161 : Word32 L_32;
162 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
163 709662444 : Flag Overflow = 0;
164 : #endif
165 :
166 709662444 : L_32 = L_mac_o( L_num, hi1, hi2, &Overflow );
167 709662444 : L_32 = L_mac_o( L_32, mult( hi1, lo2 ), 1, &Overflow );
168 709662444 : L_32 = L_mac_o( L_32, mult( lo1, hi2 ), 1, &Overflow );
169 :
170 709662444 : return ( L_32 );
171 : }
172 :
173 : /*****************************************************************************
174 : * Function Sqr_32() *
175 : * *
176 : * Square one 32 bit integer (DPF). The result is divided by 2**31 *
177 : * *
178 : * L_32 = (hi*hi)<<1 + ( (hi*lo)>>15 *2)<<1 *
179 : * *
180 : * This operation can also be viewed as the square of one Q31 *
181 : * number and the result is also in Q31. *
182 : * *
183 : * Arguments: *
184 : * *
185 : * hi1 hi part of first number *
186 : * lo1 lo part of first number *
187 : * hi2 hi part of second number *
188 : * lo2 lo part of second number *
189 : * *
190 : *****************************************************************************
191 : */
192 :
193 3255868 : Word32 Sqr_32( Word16 hi, Word16 lo )
194 : {
195 : Word32 L_32;
196 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
197 3255868 : Flag Overflow = 0;
198 : #endif
199 :
200 3255868 : L_32 = L_mult_o( hi, hi, &Overflow );
201 3255868 : L_32 = L_mac_o( L_32, mult( hi, lo ), 2, &Overflow );
202 :
203 3255868 : return ( L_32 );
204 : }
205 :
206 : /*****************************************************************************
207 : * Function Sad_32() *
208 : * *
209 : * Square one 32 bit integer (DPF). The result is divided by 2**31 *
210 : * Adds a 32 bit integer (non DFP) *
211 : * *
212 : * L_32 = L_num + (hi*hi)<<1 + ( (hi*lo)>>15 *2)<<1 *
213 : * *
214 : * This operation can also be viewed as the square of one Q31 *
215 : * number and the result is also in Q31. *
216 : * *
217 : * Arguments: *
218 : * *
219 : * hi1 hi part of first number *
220 : * lo1 lo part of first number *
221 : * hi2 hi part of second number *
222 : * lo2 lo part of second number *
223 : * *
224 : *****************************************************************************
225 : */
226 :
227 0 : Word32 Sad_32( Word32 L_num, Word16 hi, Word16 lo )
228 : {
229 : Word32 L_32;
230 :
231 0 : L_32 = L_mac( L_num, hi, hi );
232 0 : L_32 = L_mac( L_32, mult( hi, lo ), 2 );
233 :
234 0 : return ( L_32 );
235 : }
236 :
237 : /*****************************************************************************
238 : * Function Mpy_32_16() *
239 : * *
240 : * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
241 : * by 2**15 *
242 : * *
243 : * *
244 : * L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
245 : * *
246 : * Arguments: *
247 : * *
248 : * hi hi part of 32 bit number. *
249 : * lo lo part of 32 bit number. *
250 : * n 16 bit number. *
251 : * *
252 : *****************************************************************************
253 : */
254 :
255 50605443 : Word32 Mpy_32_16( Word16 hi, Word16 lo, Word16 n )
256 : {
257 : Word32 L_32;
258 :
259 50605443 : L_32 = L_mult( hi, n );
260 50605443 : L_32 = L_mac( L_32, mult( lo, n ), 1 );
261 :
262 50605443 : return ( L_32 );
263 : }
264 :
265 : /*****************************************************************************
266 : * Function Mac_32_16() *
267 : * *
268 : * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
269 : * by 2**15 *
270 : * Adds a 32 bit integer (non DFP) *
271 : * *
272 : * *
273 : * L_32 = L_num + (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
274 : * *
275 : * Arguments: *
276 : * *
277 : * L_num 32 bit long signed integer (Word32) *
278 : * hi hi part of 32 bit number. *
279 : * lo lo part of 32 bit number. *
280 : * n 16 bit number. *
281 : * *
282 : *****************************************************************************
283 : */
284 :
285 0 : Word32 Mac_32_16( Word32 L_num, Word16 hi, Word16 lo, Word16 n )
286 : {
287 : Word32 L_32;
288 :
289 0 : L_32 = L_mac( L_num, hi, n );
290 0 : L_32 = L_mac( L_32, mult( lo, n ), 1 );
291 :
292 0 : return ( L_32 );
293 : }
294 :
295 : /*****************************************************************************
296 : * Function Msu_32_16() *
297 : * *
298 : * Substract a 32 bit integer (non DFP) *
299 : * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
300 : * by 2**15 *
301 : * *
302 : * *
303 : * L_32 = L_num - (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
304 : * *
305 : * Arguments: *
306 : * *
307 : * L_num 32 bit long signed integer (Word32) *
308 : * hi hi part of 32 bit number. *
309 : * lo lo part of 32 bit number. *
310 : * n 16 bit number. *
311 : * *
312 : *****************************************************************************
313 : */
314 :
315 50030789 : Word32 Msu_32_16( Word32 L_num, Word16 hi, Word16 lo, Word16 n )
316 : {
317 : Word32 L_32;
318 :
319 50030789 : L_32 = L_msu( L_num, hi, n );
320 50030789 : L_32 = L_msu( L_32, mult( lo, n ), 1 );
321 :
322 50030789 : return ( L_32 );
323 : }
324 :
325 : /*****************************************************************************
326 : * *
327 : * Function Name : Div_32 *
328 : * *
329 : * Purpose : *
330 : * Fractional integer division of two 32 bit numbers. *
331 : * L_num / L_denom. *
332 : * L_num and L_denom must be positive and L_num < L_denom. *
333 : * L_denom = denom_hi<<16 + denom_lo<<1 *
334 : * denom_hi is a normalize number. *
335 : * *
336 : * Inputs : *
337 : * *
338 : * L_num *
339 : * 32 bit long signed integer (Word32) whose value falls in the *
340 : * range : 0x0000 0000 < L_num < L_denom *
341 : * *
342 : * L_denom = denom_hi<<16 + denom_lo<<1 (DPF) *
343 : * *
344 : * denom_hi *
345 : * 16 bit positive normalized integer whose value falls in the *
346 : * range : 0x4000 < hi < 0x7fff *
347 : * denom_lo *
348 : * 16 bit positive integer whose value falls in the *
349 : * range : 0 < lo < 0x7fff *
350 : * *
351 : * Return Value : *
352 : * *
353 : * L_div *
354 : * 32 bit long signed integer (Word32) whose value falls in the *
355 : * range : 0x0000 0000 <= L_div <= 0x7fff ffff. *
356 : * *
357 : * Algorithm: *
358 : * *
359 : * - find = 1/L_denom. *
360 : * First approximation: approx = 1 / denom_hi *
361 : * 1/L_denom = approx * (2.0 - L_denom * approx ) *
362 : * *
363 : * - result = L_num * (1/L_denom) *
364 : *****************************************************************************
365 : */
366 :
367 1711524 : Word32 Div_32( Word32 L_num, Word16 denom_hi, Word16 denom_lo )
368 : {
369 : Word16 approx, hi, lo, n_hi, n_lo;
370 : Word32 L_32;
371 :
372 : /* First approximation: 1 / L_denom = 1/denom_hi */
373 :
374 1711524 : approx = div_s( (Word16) 0x3fff, denom_hi );
375 :
376 : /* 1/L_denom = approx * (2.0 - L_denom * approx) */
377 :
378 1711524 : L_32 = Msu_32_16( (Word32) 0x7fffffffL, denom_hi, denom_lo, approx );
379 :
380 1711524 : lo = L_Extract_lc( L_32, &hi );
381 1711524 : L_32 = Mpy_32_16( hi, lo, approx );
382 :
383 : /* L_num * (1/L_denom) */
384 :
385 1711524 : lo = L_Extract_lc( L_32, &hi );
386 1711524 : n_lo = L_Extract_lc( L_num, &n_hi );
387 1711524 : L_32 = Mpy_32( n_hi, n_lo, hi, lo );
388 1711524 : L_32 = L_shl_sat( L_32, 2 );
389 1711524 : return ( L_32 );
390 : }
391 :
392 : #undef WMC_TOOL_SKIP
|