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 3863227 : void L_Extract( Word32 L_32, Word16 *hi, Word16 *lo )
46 : {
47 3863227 : *hi = extract_h( L_32 );
48 3863227 : *lo = extract_l( L_msu( L_shr( L_32, 1 ), *hi, 16384 ) );
49 3863227 : 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 27757437 : Word16 L_Extract_lc( Word32 L_32, Word16 *hi )
69 : {
70 27757437 : *hi = extract_h( L_32 );
71 :
72 27757437 : 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 4175421 : Word32 L_Comp( Word16 hi, Word16 lo )
97 : {
98 : Word32 L_32;
99 :
100 4175421 : L_32 = L_deposit_h( hi );
101 4175421 : 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 6495191 : Word32 Mpy_32( Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2 )
125 : {
126 : Word32 L_32;
127 : #ifndef ISSUE_1836_replace_overflow_libcom
128 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
129 : Flag Overflow = 0;
130 : #endif
131 : #endif
132 :
133 6495191 : L_32 = L_mult( hi1, hi2 );
134 : #ifdef ISSUE_1836_replace_overflow_libcom
135 6495191 : L_32 = L_mac_sat( L_32, mult( hi1, lo2 ), 1 );
136 6495191 : L_32 = L_mac_sat( L_32, mult( lo1, hi2 ), 1 );
137 : #else
138 : L_32 = L_mac_o( L_32, mult( hi1, lo2 ), 1, &Overflow );
139 : L_32 = L_mac_o( L_32, mult( lo1, hi2 ), 1, &Overflow );
140 : #endif
141 :
142 6495191 : return ( L_32 );
143 : }
144 :
145 : /*****************************************************************************
146 : * Function Mac_32() *
147 : * *
148 : * Multiply two 32 bit integers (DPF). The result is divided by 2**31 *
149 : * Adds a 32 bit integer (non DFP) *
150 : * *
151 : * L_32 = L_num + (hi1*hi2)<<1 + ( (hi1*lo2)>>15 + (lo1*hi2)>>15 )<<1 *
152 : * *
153 : * This operation can also be viewed as the multiplication of two Q31 *
154 : * number and the result is also in Q31. *
155 : * *
156 : * Arguments: *
157 : * *
158 : * hi1 hi part of first number *
159 : * lo1 lo part of first number *
160 : * hi2 hi part of second number *
161 : * lo2 lo part of second number *
162 : * *
163 : *****************************************************************************
164 : */
165 :
166 5581846 : Word32 Mac_32( Word32 L_num, Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2 )
167 : {
168 : Word32 L_32;
169 : #ifndef ISSUE_1836_replace_overflow_libcom
170 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
171 : Flag Overflow = 0;
172 : #endif
173 : #endif
174 :
175 : #ifdef ISSUE_1836_replace_overflow_libcom
176 5581846 : L_32 = L_mac_sat( L_num, hi1, hi2 );
177 5581846 : L_32 = L_mac_sat( L_32, mult( hi1, lo2 ), 1 );
178 5581846 : L_32 = L_mac_sat( L_32, mult( lo1, hi2 ), 1 );
179 : #else
180 : L_32 = L_mac_o( L_num, hi1, hi2, &Overflow );
181 : L_32 = L_mac_o( L_32, mult( hi1, lo2 ), 1, &Overflow );
182 : L_32 = L_mac_o( L_32, mult( lo1, hi2 ), 1, &Overflow );
183 : #endif
184 :
185 5581846 : return ( L_32 );
186 : }
187 :
188 : /*****************************************************************************
189 : * Function Sqr_32() *
190 : * *
191 : * Square one 32 bit integer (DPF). The result is divided by 2**31 *
192 : * *
193 : * L_32 = (hi*hi)<<1 + ( (hi*lo)>>15 *2)<<1 *
194 : * *
195 : * This operation can also be viewed as the square of one Q31 *
196 : * number and the result is also in Q31. *
197 : * *
198 : * Arguments: *
199 : * *
200 : * hi1 hi part of first number *
201 : * lo1 lo part of first number *
202 : * hi2 hi part of second number *
203 : * lo2 lo part of second number *
204 : * *
205 : *****************************************************************************
206 : */
207 :
208 122323 : Word32 Sqr_32( Word16 hi, Word16 lo )
209 : {
210 : Word32 L_32;
211 : #ifndef ISSUE_1836_replace_overflow_libcom
212 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
213 : Flag Overflow = 0;
214 : #endif
215 : #endif
216 :
217 : #ifdef ISSUE_1836_replace_overflow_libcom
218 122323 : L_32 = L_mult_sat( hi, hi );
219 122323 : L_32 = L_mac_sat( L_32, mult( hi, lo ), 2 );
220 : #else
221 : L_32 = L_mult_o( hi, hi, &Overflow );
222 : L_32 = L_mac_o( L_32, mult( hi, lo ), 2, &Overflow );
223 : #endif
224 :
225 122323 : return ( L_32 );
226 : }
227 :
228 : /*****************************************************************************
229 : * Function Sad_32() *
230 : * *
231 : * Square one 32 bit integer (DPF). The result is divided by 2**31 *
232 : * Adds a 32 bit integer (non DFP) *
233 : * *
234 : * L_32 = L_num + (hi*hi)<<1 + ( (hi*lo)>>15 *2)<<1 *
235 : * *
236 : * This operation can also be viewed as the square of one Q31 *
237 : * number and the result is also in Q31. *
238 : * *
239 : * Arguments: *
240 : * *
241 : * hi1 hi part of first number *
242 : * lo1 lo part of first number *
243 : * hi2 hi part of second number *
244 : * lo2 lo part of second number *
245 : * *
246 : *****************************************************************************
247 : */
248 :
249 0 : Word32 Sad_32( Word32 L_num, Word16 hi, Word16 lo )
250 : {
251 : Word32 L_32;
252 :
253 0 : L_32 = L_mac( L_num, hi, hi );
254 0 : L_32 = L_mac( L_32, mult( hi, lo ), 2 );
255 :
256 0 : return ( L_32 );
257 : }
258 :
259 : /*****************************************************************************
260 : * Function Mpy_32_16() *
261 : * *
262 : * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
263 : * by 2**15 *
264 : * *
265 : * *
266 : * L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
267 : * *
268 : * Arguments: *
269 : * *
270 : * hi hi part of 32 bit number. *
271 : * lo lo part of 32 bit number. *
272 : * n 16 bit number. *
273 : * *
274 : *****************************************************************************
275 : */
276 :
277 23594201 : Word32 Mpy_32_16( Word16 hi, Word16 lo, Word16 n )
278 : {
279 : Word32 L_32;
280 :
281 23594201 : L_32 = L_mult( hi, n );
282 23594201 : L_32 = L_mac( L_32, mult( lo, n ), 1 );
283 :
284 23594201 : return ( L_32 );
285 : }
286 :
287 : /*****************************************************************************
288 : * Function Mac_32_16() *
289 : * *
290 : * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
291 : * by 2**15 *
292 : * Adds a 32 bit integer (non DFP) *
293 : * *
294 : * *
295 : * L_32 = L_num + (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
296 : * *
297 : * Arguments: *
298 : * *
299 : * L_num 32 bit long signed integer (Word32) *
300 : * hi hi part of 32 bit number. *
301 : * lo lo part of 32 bit number. *
302 : * n 16 bit number. *
303 : * *
304 : *****************************************************************************
305 : */
306 :
307 0 : Word32 Mac_32_16( Word32 L_num, Word16 hi, Word16 lo, Word16 n )
308 : {
309 : Word32 L_32;
310 :
311 0 : L_32 = L_mac( L_num, hi, n );
312 0 : L_32 = L_mac( L_32, mult( lo, n ), 1 );
313 :
314 0 : return ( L_32 );
315 : }
316 :
317 : /*****************************************************************************
318 : * Function Msu_32_16() *
319 : * *
320 : * Substract a 32 bit integer (non DFP) *
321 : * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided *
322 : * by 2**15 *
323 : * *
324 : * *
325 : * L_32 = L_num - (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 *
326 : * *
327 : * Arguments: *
328 : * *
329 : * L_num 32 bit long signed integer (Word32) *
330 : * hi hi part of 32 bit number. *
331 : * lo lo part of 32 bit number. *
332 : * n 16 bit number. *
333 : * *
334 : *****************************************************************************
335 : */
336 :
337 2344492 : Word32 Msu_32_16( Word32 L_num, Word16 hi, Word16 lo, Word16 n )
338 : {
339 : Word32 L_32;
340 :
341 2344492 : L_32 = L_msu( L_num, hi, n );
342 2344492 : L_32 = L_msu( L_32, mult( lo, n ), 1 );
343 :
344 2344492 : return ( L_32 );
345 : }
346 :
347 : /*****************************************************************************
348 : * *
349 : * Function Name : Div_32 *
350 : * *
351 : * Purpose : *
352 : * Fractional integer division of two 32 bit numbers. *
353 : * L_num / L_denom. *
354 : * L_num and L_denom must be positive and L_num < L_denom. *
355 : * L_denom = denom_hi<<16 + denom_lo<<1 *
356 : * denom_hi is a normalize number. *
357 : * *
358 : * Inputs : *
359 : * *
360 : * L_num *
361 : * 32 bit long signed integer (Word32) whose value falls in the *
362 : * range : 0x0000 0000 < L_num < L_denom *
363 : * *
364 : * L_denom = denom_hi<<16 + denom_lo<<1 (DPF) *
365 : * *
366 : * denom_hi *
367 : * 16 bit positive normalized integer whose value falls in the *
368 : * range : 0x4000 < hi < 0x7fff *
369 : * denom_lo *
370 : * 16 bit positive integer whose value falls in the *
371 : * range : 0 < lo < 0x7fff *
372 : * *
373 : * Return Value : *
374 : * *
375 : * L_div *
376 : * 32 bit long signed integer (Word32) whose value falls in the *
377 : * range : 0x0000 0000 <= L_div <= 0x7fff ffff. *
378 : * *
379 : * Algorithm: *
380 : * *
381 : * - find = 1/L_denom. *
382 : * First approximation: approx = 1 / denom_hi *
383 : * 1/L_denom = approx * (2.0 - L_denom * approx ) *
384 : * *
385 : * - result = L_num * (1/L_denom) *
386 : *****************************************************************************
387 : */
388 :
389 1749474 : Word32 Div_32( Word32 L_num, Word16 denom_hi, Word16 denom_lo )
390 : {
391 : Word16 approx, hi, lo, n_hi, n_lo;
392 : Word32 L_32;
393 :
394 : /* First approximation: 1 / L_denom = 1/denom_hi */
395 :
396 1749474 : approx = div_s( (Word16) 0x3fff, denom_hi );
397 :
398 : /* 1/L_denom = approx * (2.0 - L_denom * approx) */
399 :
400 1749474 : L_32 = Msu_32_16( (Word32) 0x7fffffffL, denom_hi, denom_lo, approx );
401 :
402 1749474 : lo = L_Extract_lc( L_32, &hi );
403 1749474 : L_32 = Mpy_32_16( hi, lo, approx );
404 :
405 : /* L_num * (1/L_denom) */
406 :
407 1749474 : lo = L_Extract_lc( L_32, &hi );
408 1749474 : n_lo = L_Extract_lc( L_num, &n_hi );
409 1749474 : L_32 = Mpy_32( n_hi, n_lo, hi, lo );
410 1749474 : L_32 = L_shl_sat( L_32, 2 );
411 1749474 : return ( L_32 );
412 : }
413 :
414 : #undef WMC_TOOL_SKIP
|