0
|
1 /* This is a software fixed-point library.
|
|
2 Copyright (C) 2007, 2009 Free Software Foundation, Inc.
|
|
3
|
|
4 This file is part of GCC.
|
|
5
|
|
6 GCC is free software; you can redistribute it and/or modify it under
|
|
7 the terms of the GNU General Public License as published by the Free
|
|
8 Software Foundation; either version 3, or (at your option) any later
|
|
9 version.
|
|
10
|
|
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 for more details.
|
|
15
|
|
16 Under Section 7 of GPL version 3, you are granted additional
|
|
17 permissions described in the GCC Runtime Library Exception, version
|
|
18 3.1, as published by the Free Software Foundation.
|
|
19
|
|
20 You should have received a copy of the GNU General Public License and
|
|
21 a copy of the GCC Runtime Library Exception along with this program;
|
|
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
23 <http://www.gnu.org/licenses/>. */
|
|
24
|
|
25 /* This implements fixed-point arithmetic.
|
|
26
|
|
27 Contributed by Chao-ying Fu <fu@mips.com>. */
|
|
28
|
|
29 /* To use this file, we need to define one of the following:
|
|
30 QQ_MODE, UQQ_MODE, HQ_MODE, UHQ_MODE, SQ_MODE, USQ_MODE, DQ_MODE, UDQ_MODE,
|
|
31 TQ_MODE, UTQ_MODE, HA_MODE, UHA_MODE, SA_MODE, USA_MODE, DA_MODE, UDA_MODE,
|
|
32 TA_MODE, UTA_MODE.
|
|
33 Then, all operators for this machine mode will be created.
|
|
34
|
|
35 Or, we need to define FROM_* TO_* for conversions from one mode to another
|
|
36 mode. The mode could be one of the following:
|
|
37 Fract: QQ, UQQ, HQ, UHQ, SQ, USQ, DQ, UDQ, TQ, UTQ
|
|
38 Accum: HA, UHA, SA, USA, DA, UDA, TA, UTA
|
|
39 Signed integer: QI, HI, SI, DI, TI
|
|
40 Unsigned integer: UQI, UHI, USI, UDI, UTI
|
|
41 Floating-point: SF, DF
|
|
42 Ex: If we define FROM_QQ and TO_SI, the conversion from QQ to SI is
|
|
43 generated. */
|
|
44
|
|
45 #include "tconfig.h"
|
|
46 #include "tsystem.h"
|
|
47 #include "coretypes.h"
|
|
48 #include "tm.h"
|
|
49
|
|
50 #ifndef MIN_UNITS_PER_WORD
|
|
51 #define MIN_UNITS_PER_WORD UNITS_PER_WORD
|
|
52 #endif
|
|
53
|
|
54 #include "config/fixed-bit.h"
|
|
55
|
|
56 #if defined(FIXED_ADD) && defined(L_add)
|
|
57 FIXED_C_TYPE
|
|
58 FIXED_ADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
59 {
|
|
60 FIXED_C_TYPE c;
|
|
61 INT_C_TYPE x, y, z;
|
|
62 memcpy (&x, &a, FIXED_SIZE);
|
|
63 memcpy (&y, &b, FIXED_SIZE);
|
|
64 z = x + y;
|
|
65 #if HAVE_PADDING_BITS
|
|
66 z = z << PADDING_BITS;
|
|
67 z = z >> PADDING_BITS;
|
|
68 #endif
|
|
69 memcpy (&c, &z, FIXED_SIZE);
|
|
70 return c;
|
|
71 }
|
|
72 #endif /* FIXED_ADD */
|
|
73
|
|
74 #if defined(FIXED_SSADD) && defined(L_ssadd)
|
|
75 FIXED_C_TYPE
|
|
76 FIXED_SSADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
77 {
|
|
78 FIXED_C_TYPE c;
|
|
79 INT_C_TYPE x, y, z;
|
|
80 memcpy (&x, &a, FIXED_SIZE);
|
|
81 memcpy (&y, &b, FIXED_SIZE);
|
|
82 z = x + y;
|
|
83 if ((((x ^ y) >> I_F_BITS) & 1) == 0)
|
|
84 {
|
|
85 if (((z ^ x) >> I_F_BITS) & 1)
|
|
86 {
|
|
87 z = 1;
|
|
88 z = z << I_F_BITS;
|
|
89 if (x >= 0)
|
|
90 z--;
|
|
91 }
|
|
92 }
|
|
93 #if HAVE_PADDING_BITS
|
|
94 z = z << PADDING_BITS;
|
|
95 z = z >> PADDING_BITS;
|
|
96 #endif
|
|
97 memcpy (&c, &z, FIXED_SIZE);
|
|
98 return c;
|
|
99 }
|
|
100 #endif /* FIXED_SSADD */
|
|
101
|
|
102 #if defined(FIXED_USADD) && defined(L_usadd)
|
|
103 FIXED_C_TYPE
|
|
104 FIXED_USADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
105 {
|
|
106 FIXED_C_TYPE c;
|
|
107 INT_C_TYPE x, y, z;
|
|
108 memcpy (&x, &a, FIXED_SIZE);
|
|
109 memcpy (&y, &b, FIXED_SIZE);
|
|
110 z = x + y;
|
|
111 #if HAVE_PADDING_BITS
|
|
112 z = z << PADDING_BITS;
|
|
113 z = z >> PADDING_BITS;
|
|
114 #endif
|
|
115 if (z < x || z < y) /* max */
|
|
116 {
|
|
117 z = -1;
|
|
118 #if HAVE_PADDING_BITS
|
|
119 z = z << PADDING_BITS;
|
|
120 z = z >> PADDING_BITS;
|
|
121 #endif
|
|
122 }
|
|
123 memcpy (&c, &z, FIXED_SIZE);
|
|
124 return c;
|
|
125 }
|
|
126 #endif /* FIXED_USADD */
|
|
127
|
|
128 #if defined(FIXED_SUB) && defined(L_sub)
|
|
129 FIXED_C_TYPE
|
|
130 FIXED_SUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
131 {
|
|
132 FIXED_C_TYPE c;
|
|
133 INT_C_TYPE x, y, z;
|
|
134 memcpy (&x, &a, FIXED_SIZE);
|
|
135 memcpy (&y, &b, FIXED_SIZE);
|
|
136 z = x - y;
|
|
137 #if HAVE_PADDING_BITS
|
|
138 z = z << PADDING_BITS;
|
|
139 z = z >> PADDING_BITS;
|
|
140 #endif
|
|
141 memcpy (&c, &z, FIXED_SIZE);
|
|
142 return c;
|
|
143 }
|
|
144 #endif /* FIXED_SUB */
|
|
145
|
|
146 #if defined(FIXED_SSSUB) && defined(L_sssub)
|
|
147 FIXED_C_TYPE
|
|
148 FIXED_SSSUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
149 {
|
|
150 FIXED_C_TYPE c;
|
|
151 INT_C_TYPE x, y, z;
|
|
152 memcpy (&x, &a, FIXED_SIZE);
|
|
153 memcpy (&y, &b, FIXED_SIZE);
|
|
154 z = x - y;
|
|
155 if (((x ^ y) >> I_F_BITS) & 1)
|
|
156 {
|
|
157 if (((z ^ x) >> I_F_BITS) & 1)
|
|
158 {
|
|
159 z = 1;
|
|
160 z = z << I_F_BITS;
|
|
161 if (x >= 0)
|
|
162 z--;
|
|
163 }
|
|
164 }
|
|
165 #if HAVE_PADDING_BITS
|
|
166 z = z << PADDING_BITS;
|
|
167 z = z >> PADDING_BITS;
|
|
168 #endif
|
|
169 memcpy (&c, &z, FIXED_SIZE);
|
|
170 return c;
|
|
171 }
|
|
172 #endif /* FIXED_SSSUB */
|
|
173
|
|
174 #if defined(FIXED_USSUB) && defined(L_ussub)
|
|
175 FIXED_C_TYPE
|
|
176 FIXED_USSUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
177 {
|
|
178 FIXED_C_TYPE c;
|
|
179 INT_C_TYPE x, y, z;
|
|
180 memcpy (&x, &a, FIXED_SIZE);
|
|
181 memcpy (&y, &b, FIXED_SIZE);
|
|
182 z = x - y;
|
|
183 if (x < y)
|
|
184 z = 0;
|
|
185 #if HAVE_PADDING_BITS
|
|
186 z = z << PADDING_BITS;
|
|
187 z = z >> PADDING_BITS;
|
|
188 #endif
|
|
189 memcpy (&c, &z, FIXED_SIZE);
|
|
190 return c;
|
|
191 }
|
|
192 #endif /* FIXED_USSUB */
|
|
193
|
|
194 #if defined(FIXED_SATURATE1) && defined(L_saturate1)
|
|
195 void
|
|
196 FIXED_SATURATE1 (DINT_C_TYPE *a)
|
|
197 {
|
|
198 DINT_C_TYPE max, min;
|
|
199 max = (DINT_C_TYPE)1 << I_F_BITS;
|
|
200 max = max - 1;
|
|
201 #if MODE_UNSIGNED == 0
|
|
202 min = (DINT_C_TYPE)1 << (2 * FIXED_WIDTH - 1);
|
|
203 min = min >> (2 * FIXED_WIDTH - 1 - I_F_BITS);
|
|
204 #else
|
|
205 min = 0;
|
|
206 #endif
|
|
207 if (*a > max)
|
|
208 *a = max;
|
|
209 else if (*a < min)
|
|
210 *a = min;
|
|
211 }
|
|
212 #endif /* FIXED_SATURATE1 */
|
|
213
|
|
214 #if defined(FIXED_SATURATE2) && defined(L_saturate2)
|
|
215 void
|
|
216 FIXED_SATURATE2 (INT_C_TYPE *high, INT_C_TYPE *low)
|
|
217 {
|
|
218 INT_C_TYPE r_max, s_max, r_min, s_min;
|
|
219 r_max = 0;
|
|
220 #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS
|
|
221 s_max = (INT_C_TYPE)1 << I_F_BITS;
|
|
222 s_max = s_max - 1;
|
|
223 #else
|
|
224 s_max = -1;
|
|
225 #endif
|
|
226 #if MODE_UNSIGNED == 0
|
|
227 r_min = -1;
|
|
228 s_min = (INT_C_TYPE)1 << (FIXED_WIDTH - 1);
|
|
229 s_min = s_min >> (FIXED_WIDTH - 1 - I_F_BITS);
|
|
230 #else
|
|
231 r_min = 0;
|
|
232 s_min = 0;
|
|
233 #endif
|
|
234
|
|
235 if (*high > r_max
|
|
236 || (*high == r_max && (UINT_C_TYPE)(*low) > (UINT_C_TYPE)s_max))
|
|
237 {
|
|
238 *high = r_max;
|
|
239 *low = s_max;
|
|
240 }
|
|
241 else if (*high < r_min ||
|
|
242 (*high == r_min && (UINT_C_TYPE)(*low) < (UINT_C_TYPE)s_min))
|
|
243 {
|
|
244 *high = r_min;
|
|
245 *low = s_min;
|
|
246 }
|
|
247 }
|
|
248 #endif /* FIXED_SATURATE2 */
|
|
249
|
|
250 #if defined(FIXED_MULHELPER) && defined(L_mulhelper)
|
|
251 FIXED_C_TYPE
|
|
252 FIXED_MULHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp)
|
|
253 {
|
|
254 FIXED_C_TYPE c;
|
|
255 INT_C_TYPE x, y;
|
|
256
|
|
257 #if defined (DINT_C_TYPE)
|
|
258 INT_C_TYPE z;
|
|
259 DINT_C_TYPE dx, dy, dz;
|
|
260 memcpy (&x, &a, FIXED_SIZE);
|
|
261 memcpy (&y, &b, FIXED_SIZE);
|
|
262 dx = (DINT_C_TYPE) x;
|
|
263 dy = (DINT_C_TYPE) y;
|
|
264 dz = dx * dy;
|
|
265 /* Round the result by adding (1 << (FBITS -1)). */
|
|
266 dz += ((DINT_C_TYPE) 1 << (FBITS - 1));
|
|
267 dz = dz >> FBITS;
|
|
268 if (satp)
|
|
269 FIXED_SATURATE1 (&dz);
|
|
270
|
|
271 z = (INT_C_TYPE) dz;
|
|
272 #if HAVE_PADDING_BITS
|
|
273 z = z << PADDING_BITS;
|
|
274 z = z >> PADDING_BITS;
|
|
275 #endif
|
|
276 memcpy (&c, &z, FIXED_SIZE);
|
|
277 return c;
|
|
278
|
|
279 #else /* No DINT_C_TYPE */
|
|
280 /* The result of multiplication expands to two INT_C_TYPE. */
|
|
281 INTunion aa, bb;
|
|
282 INTunion a_high, a_low, b_high, b_low;
|
|
283 INTunion high_high, high_low, low_high, low_low;
|
|
284 INTunion r, s, temp1, temp2;
|
|
285 INT_C_TYPE carry = 0;
|
|
286 INT_C_TYPE z;
|
|
287
|
|
288 memcpy (&x, &a, FIXED_SIZE);
|
|
289 memcpy (&y, &b, FIXED_SIZE);
|
|
290
|
|
291 /* Decompose a and b. */
|
|
292 aa.ll = x;
|
|
293 bb.ll = y;
|
|
294
|
|
295 a_high.s.low = aa.s.high;
|
|
296 a_high.s.high = 0;
|
|
297 a_low.s.low = aa.s.low;
|
|
298 a_low.s.high = 0;
|
|
299 b_high.s.low = bb.s.high;
|
|
300 b_high.s.high = 0;
|
|
301 b_low.s.low = bb.s.low;
|
|
302 b_low.s.high = 0;
|
|
303
|
|
304 /* Perform four multiplications. */
|
|
305 low_low.ll = a_low.ll * b_low.ll;
|
|
306 low_high.ll = a_low.ll * b_high.ll;
|
|
307 high_low.ll = a_high.ll * b_low.ll;
|
|
308 high_high.ll = a_high.ll * b_high.ll;
|
|
309
|
|
310 /* Accumulate four results to {r, s}. */
|
|
311 temp1.s.high = high_low.s.low;
|
|
312 temp1.s.low = 0;
|
|
313 s.ll = low_low.ll + temp1.ll;
|
|
314 if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) low_low.ll
|
|
315 || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll)
|
|
316 carry ++; /* Carry. */
|
|
317 temp1.ll = s.ll;
|
|
318 temp2.s.high = low_high.s.low;
|
|
319 temp2.s.low = 0;
|
|
320 s.ll = temp1.ll + temp2.ll;
|
|
321 if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll
|
|
322 || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp2.ll)
|
|
323 carry ++; /* Carry. */
|
|
324
|
|
325 temp1.s.low = high_low.s.high;
|
|
326 temp1.s.high = 0;
|
|
327 r.ll = high_high.ll + temp1.ll;
|
|
328 temp1.s.low = low_high.s.high;
|
|
329 temp1.s.high = 0;
|
|
330 r.ll = r.ll + temp1.ll + carry;
|
|
331
|
|
332 #if MODE_UNSIGNED == 0
|
|
333 /* For signed types, we need to add neg(y) to r, if x < 0. */
|
|
334 if (x < 0)
|
|
335 r.ll = r.ll - y;
|
|
336 /* We need to add neg(x) to r, if y < 0. */
|
|
337 if (y < 0)
|
|
338 r.ll = r.ll - x;
|
|
339 #endif
|
|
340
|
|
341 /* Round the result by adding (1 << (FBITS -1)). */
|
|
342 temp1.ll = s.ll;
|
|
343 s.ll += ((INT_C_TYPE) 1 << (FBITS -1));
|
|
344 if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll
|
|
345 || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) ((INT_C_TYPE) 1 << (FBITS -1)))
|
|
346 r.ll += 1;
|
|
347
|
|
348 /* Shift right the result by FBITS. */
|
|
349 #if FBITS == FIXED_WIDTH
|
|
350 /* This happens only for unsigned types without any padding bits.
|
|
351 So, it is safe to set r.ll to 0 as it is logically shifted right. */
|
|
352 s.ll = r.ll;
|
|
353 r.ll = 0;
|
|
354 #else
|
|
355 s.ll = ((UINT_C_TYPE)s.ll) >> FBITS;
|
|
356 temp1.ll = r.ll << (FIXED_WIDTH - FBITS);
|
|
357 s.ll = s.ll | temp1.ll;
|
|
358 r.ll = r.ll >> FBITS;
|
|
359 #endif
|
|
360
|
|
361 if (satp)
|
|
362 FIXED_SATURATE2 (&r.ll, &s.ll);
|
|
363
|
|
364 z = (INT_C_TYPE) s.ll;
|
|
365 #if HAVE_PADDING_BITS
|
|
366 z = z << PADDING_BITS;
|
|
367 z = z >> PADDING_BITS;
|
|
368 #endif
|
|
369 memcpy (&c, &z, FIXED_SIZE);
|
|
370 return c;
|
|
371 #endif
|
|
372 }
|
|
373 #endif /* FIXED_MULHELPER */
|
|
374
|
|
375 #if defined(FIXED_MUL) && defined(L_mul)
|
|
376 FIXED_C_TYPE
|
|
377 FIXED_MUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
378 {
|
|
379 return FIXED_MULHELPER (a, b, 0);
|
|
380 }
|
|
381 #endif /* FIXED_MUL */
|
|
382
|
|
383 #if defined(FIXED_SSMUL) && defined(L_ssmul)
|
|
384 FIXED_C_TYPE
|
|
385 FIXED_SSMUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
386 {
|
|
387 return FIXED_MULHELPER (a, b, 1);
|
|
388 }
|
|
389 #endif /* FIXED_SSMUL */
|
|
390
|
|
391 #if defined(FIXED_USMUL) && defined(L_usmul)
|
|
392 FIXED_C_TYPE
|
|
393 FIXED_USMUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
394 {
|
|
395 return FIXED_MULHELPER (a, b, 1);
|
|
396 }
|
|
397 #endif /* FIXED_USMUL */
|
|
398
|
|
399 #if defined(FIXED_DIVHELPER) && defined(L_divhelper)
|
|
400 FIXED_C_TYPE
|
|
401 FIXED_DIVHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp)
|
|
402 {
|
|
403 FIXED_C_TYPE c;
|
|
404 INT_C_TYPE x, y;
|
|
405 INT_C_TYPE z;
|
|
406
|
|
407 #if defined (DINT_C_TYPE)
|
|
408 DINT_C_TYPE dx, dy, dz;
|
|
409 memcpy (&x, &a, FIXED_SIZE);
|
|
410 memcpy (&y, &b, FIXED_SIZE);
|
|
411 dx = (DINT_C_TYPE) x;
|
|
412 dy = (DINT_C_TYPE) y;
|
|
413 dx = dx << FBITS;
|
|
414 dz = dx / dy;
|
|
415 if (satp)
|
|
416 FIXED_SATURATE1 (&dz);
|
|
417 z = (INT_C_TYPE) dz;
|
|
418 #if HAVE_PADDING_BITS
|
|
419 z = z << PADDING_BITS;
|
|
420 z = z >> PADDING_BITS;
|
|
421 #endif
|
|
422 memcpy (&c, &z, FIXED_SIZE);
|
|
423 return c;
|
|
424
|
|
425 #else /* No DINT_C_TYPE */
|
|
426 INT_C_TYPE pos_a, pos_b, r, s;
|
|
427 INT_C_TYPE quo_r, quo_s, mod, temp;
|
|
428 word_type i;
|
|
429 #if MODE_UNSIGNED == 0
|
|
430 word_type num_of_neg = 0;
|
|
431 #endif
|
|
432
|
|
433 memcpy (&x, &a, FIXED_SIZE);
|
|
434 memcpy (&y, &b, FIXED_SIZE);
|
|
435 pos_a = x;
|
|
436 pos_b = y;
|
|
437
|
|
438 #if MODE_UNSIGNED == 0
|
|
439 /* If a < 0, negate a. */
|
|
440 if (pos_a < 0)
|
|
441 {
|
|
442 pos_a = -pos_a;
|
|
443 num_of_neg ++;
|
|
444 }
|
|
445 /* If b < 0, negate b. */
|
|
446 if (pos_b < 0)
|
|
447 {
|
|
448 pos_b = -pos_b;
|
|
449 num_of_neg ++;
|
|
450 }
|
|
451 #endif
|
|
452
|
|
453 /* Left shift pos_a to {r, s} by FBITS. */
|
|
454 #if FBITS == FIXED_WIDTH
|
|
455 /* This happens only for unsigned types without any padding bits. */
|
|
456 r = pos_a;
|
|
457 s = 0;
|
|
458 #else
|
|
459 s = pos_a << FBITS;
|
|
460 r = pos_a >> (FIXED_WIDTH - FBITS);
|
|
461 #endif
|
|
462
|
|
463 /* Unsigned divide r by pos_b to quo_r. The remainder is in mod. */
|
|
464 quo_r = (UINT_C_TYPE)r / (UINT_C_TYPE)pos_b;
|
|
465 mod = (UINT_C_TYPE)r % (UINT_C_TYPE)pos_b;
|
|
466 quo_s = 0;
|
|
467
|
|
468 for (i = 0; i < FIXED_WIDTH; i++)
|
|
469 {
|
|
470 /* Record the leftmost bit of mod. */
|
|
471 word_type leftmost_mode = (mod >> (FIXED_WIDTH - 1)) & 1;
|
|
472 /* Shift left mod by 1 bit. */
|
|
473 mod = mod << 1;
|
|
474 /* Test the leftmost bit of s to add to mod. */
|
|
475 if ((s >> (FIXED_WIDTH - 1)) & 1)
|
|
476 mod ++;
|
|
477 /* Shift left quo_s by 1 bit. */
|
|
478 quo_s = quo_s << 1;
|
|
479 /* Try to calculate (mod - pos_b). */
|
|
480 temp = mod - pos_b;
|
|
481 if (leftmost_mode || (UINT_C_TYPE)mod >= (UINT_C_TYPE)pos_b)
|
|
482 {
|
|
483 quo_s ++;
|
|
484 mod = temp;
|
|
485 }
|
|
486 /* Shift left s by 1 bit. */
|
|
487 s = s << 1;
|
|
488 }
|
|
489
|
|
490 #if MODE_UNSIGNED == 0
|
|
491 if (num_of_neg == 1)
|
|
492 {
|
|
493 quo_s = -quo_s;
|
|
494 if (quo_s == 0)
|
|
495 quo_r = -quo_r;
|
|
496 else
|
|
497 quo_r = ~quo_r;
|
|
498 }
|
|
499 #endif
|
|
500 if (satp)
|
|
501 FIXED_SATURATE2 (&quo_r, &quo_s);
|
|
502 z = quo_s;
|
|
503 #if HAVE_PADDING_BITS
|
|
504 z = z << PADDING_BITS;
|
|
505 z = z >> PADDING_BITS;
|
|
506 #endif
|
|
507 memcpy (&c, &z, FIXED_SIZE);
|
|
508 return c;
|
|
509 #endif
|
|
510 }
|
|
511 #endif /* FIXED_DIVHELPER */
|
|
512
|
|
513 #if defined(FIXED_DIV) && defined(L_div)
|
|
514 FIXED_C_TYPE
|
|
515 FIXED_DIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
516 {
|
|
517 return FIXED_DIVHELPER (a, b, 0);
|
|
518 }
|
|
519 #endif /* FIXED_DIV */
|
|
520
|
|
521
|
|
522 #if defined(FIXED_UDIV) && defined(L_udiv)
|
|
523 FIXED_C_TYPE
|
|
524 FIXED_UDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
525 {
|
|
526 return FIXED_DIVHELPER (a, b, 0);
|
|
527 }
|
|
528 #endif /* FIXED_UDIV */
|
|
529
|
|
530 #if defined(FIXED_SSDIV) && defined(L_ssdiv)
|
|
531 FIXED_C_TYPE
|
|
532 FIXED_SSDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
533 {
|
|
534 return FIXED_DIVHELPER (a, b, 1);
|
|
535 }
|
|
536 #endif /* FIXED_SSDIV */
|
|
537
|
|
538 #if defined(FIXED_USDIV) && defined(L_usdiv)
|
|
539 FIXED_C_TYPE
|
|
540 FIXED_USDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
541 {
|
|
542 return FIXED_DIVHELPER (a, b, 1);
|
|
543 }
|
|
544 #endif /* FIXED_USDIV */
|
|
545
|
|
546 #if defined(FIXED_NEG) && defined(L_neg)
|
|
547 FIXED_C_TYPE
|
|
548 FIXED_NEG (FIXED_C_TYPE a)
|
|
549 {
|
|
550 FIXED_C_TYPE c;
|
|
551 INT_C_TYPE x, z;
|
|
552 memcpy (&x, &a, FIXED_SIZE);
|
|
553 z = -x;
|
|
554 #if HAVE_PADDING_BITS
|
|
555 z = z << PADDING_BITS;
|
|
556 z = z >> PADDING_BITS;
|
|
557 #endif
|
|
558 memcpy (&c, &z, FIXED_SIZE);
|
|
559 return c;
|
|
560 }
|
|
561 #endif /* FIXED_NEG */
|
|
562
|
|
563 #if defined(FIXED_SSNEG) && defined(L_ssneg)
|
|
564 FIXED_C_TYPE
|
|
565 FIXED_SSNEG (FIXED_C_TYPE a)
|
|
566 {
|
|
567 FIXED_C_TYPE c;
|
|
568 INT_C_TYPE x, y, z;
|
|
569 memcpy (&y, &a, FIXED_SIZE);
|
|
570 x = 0;
|
|
571 z = x - y;
|
|
572 if (((x ^ y) >> I_F_BITS) & 1)
|
|
573 {
|
|
574 if (((z ^ x) >> I_F_BITS) & 1)
|
|
575 {
|
|
576 z = 1;
|
|
577 z = z << I_F_BITS;
|
|
578 if (x >= 0)
|
|
579 z--;
|
|
580 }
|
|
581 }
|
|
582 #if HAVE_PADDING_BITS
|
|
583 z = z << PADDING_BITS;
|
|
584 z = z >> PADDING_BITS;
|
|
585 #endif
|
|
586 memcpy (&c, &z, FIXED_SIZE);
|
|
587 return c;
|
|
588 }
|
|
589 #endif /* FIXED_SSNEG */
|
|
590
|
|
591 #if defined(FIXED_USNEG) && defined(L_usneg)
|
|
592 FIXED_C_TYPE
|
|
593 FIXED_USNEG (FIXED_C_TYPE a __attribute__ ((__unused__)))
|
|
594 {
|
|
595 FIXED_C_TYPE c;
|
|
596 INT_C_TYPE z;
|
|
597 z = 0;
|
|
598 memcpy (&c, &z, FIXED_SIZE);
|
|
599 return c;
|
|
600 }
|
|
601 #endif /* FIXED_USNEG */
|
|
602
|
|
603 #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper)
|
|
604 FIXED_C_TYPE
|
|
605 FIXED_ASHLHELPER (FIXED_C_TYPE a, word_type b, word_type satp)
|
|
606 {
|
|
607 FIXED_C_TYPE c;
|
|
608 INT_C_TYPE x, z;
|
|
609
|
|
610 #if defined (DINT_C_TYPE)
|
|
611 DINT_C_TYPE dx, dz;
|
|
612 memcpy (&x, &a, FIXED_SIZE);
|
|
613 dx = (DINT_C_TYPE) x;
|
|
614 if (b >= FIXED_WIDTH)
|
|
615 dz = dx << FIXED_WIDTH;
|
|
616 else
|
|
617 dz = dx << b;
|
|
618 if (satp)
|
|
619 FIXED_SATURATE1 (&dz);
|
|
620 z = (INT_C_TYPE) dz;
|
|
621 #if HAVE_PADDING_BITS
|
|
622 z = z << PADDING_BITS;
|
|
623 z = z >> PADDING_BITS;
|
|
624 #endif
|
|
625 memcpy (&c, &z, FIXED_SIZE);
|
|
626 return c;
|
|
627
|
|
628 #else /* No DINT_C_TYPE */
|
|
629 INT_C_TYPE r, s;
|
|
630 memcpy (&x, &a, FIXED_SIZE);
|
|
631 /* We need to shift left x by b bits to {r, s}. */
|
|
632 if (b >= FIXED_WIDTH)
|
|
633 {
|
|
634 r = b;
|
|
635 s = 0;
|
|
636 }
|
|
637 else
|
|
638 {
|
|
639 s = x << b;
|
|
640 r = x >> (FIXED_WIDTH - b);
|
|
641 }
|
|
642 if (satp)
|
|
643 FIXED_SATURATE2 (&r, &s);
|
|
644 z = s;
|
|
645 #if HAVE_PADDING_BITS
|
|
646 z = z << PADDING_BITS;
|
|
647 z = z >> PADDING_BITS;
|
|
648 #endif
|
|
649 memcpy (&c, &z, FIXED_SIZE);
|
|
650 return c;
|
|
651 #endif
|
|
652 }
|
|
653 #endif /* FIXED_ASHLHELPER */
|
|
654
|
|
655 #if defined(FIXED_ASHL) && defined(L_ashl)
|
|
656 FIXED_C_TYPE
|
|
657 FIXED_ASHL (FIXED_C_TYPE a, word_type b)
|
|
658 {
|
|
659 return FIXED_ASHLHELPER (a, b, 0);
|
|
660 }
|
|
661 #endif /* FIXED_ASHL */
|
|
662
|
|
663 #if defined(FIXED_ASHR) && defined(L_ashr)
|
|
664 FIXED_C_TYPE
|
|
665 FIXED_ASHR (FIXED_C_TYPE a, word_type b)
|
|
666 {
|
|
667 FIXED_C_TYPE c;
|
|
668 INT_C_TYPE x, z;
|
|
669 memcpy (&x, &a, FIXED_SIZE);
|
|
670 z = x >> b;
|
|
671 #if HAVE_PADDING_BITS
|
|
672 z = z << PADDING_BITS;
|
|
673 z = z >> PADDING_BITS;
|
|
674 #endif
|
|
675 memcpy (&c, &z, FIXED_SIZE);
|
|
676 return c;
|
|
677 }
|
|
678 #endif /* FIXED_ASHR */
|
|
679
|
|
680 #if defined(FIXED_LSHR) && defined(L_lshr)
|
|
681 FIXED_C_TYPE
|
|
682 FIXED_LSHR (FIXED_C_TYPE a, word_type b)
|
|
683 {
|
|
684 FIXED_C_TYPE c;
|
|
685 INT_C_TYPE x, z;
|
|
686 memcpy (&x, &a, FIXED_SIZE);
|
|
687 z = x >> b;
|
|
688 #if HAVE_PADDING_BITS
|
|
689 z = z << PADDING_BITS;
|
|
690 z = z >> PADDING_BITS;
|
|
691 #endif
|
|
692 memcpy (&c, &z, FIXED_SIZE);
|
|
693 return c;
|
|
694 }
|
|
695 #endif /* FIXED_LSHR */
|
|
696
|
|
697 #if defined(FIXED_SSASHL) && defined(L_ssashl)
|
|
698 FIXED_C_TYPE
|
|
699 FIXED_SSASHL (FIXED_C_TYPE a, word_type b)
|
|
700 {
|
|
701 return FIXED_ASHLHELPER (a, b, 1);
|
|
702 }
|
|
703 #endif /* FIXED_SSASHL */
|
|
704
|
|
705 #if defined(FIXED_USASHL) && defined(L_usashl)
|
|
706 FIXED_C_TYPE
|
|
707 FIXED_USASHL (FIXED_C_TYPE a, word_type b)
|
|
708 {
|
|
709 return FIXED_ASHLHELPER (a, b, 1);
|
|
710 }
|
|
711 #endif /* FIXED_USASHL */
|
|
712
|
|
713 #if defined(FIXED_CMP) && defined(L_cmp)
|
|
714 word_type
|
|
715 FIXED_CMP (FIXED_C_TYPE a, FIXED_C_TYPE b)
|
|
716 {
|
|
717 INT_C_TYPE x, y;
|
|
718 memcpy (&x, &a, FIXED_SIZE);
|
|
719 memcpy (&y, &b, FIXED_SIZE);
|
|
720
|
|
721 if (x < y)
|
|
722 return 0;
|
|
723 else if (x > y)
|
|
724 return 2;
|
|
725
|
|
726 return 1;
|
|
727 }
|
|
728 #endif /* FIXED_CMP */
|
|
729
|
|
730 /* Fixed -> Fixed. */
|
|
731 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4
|
|
732 TO_FIXED_C_TYPE
|
|
733 FRACT (FROM_FIXED_C_TYPE a)
|
|
734 {
|
|
735 TO_FIXED_C_TYPE c;
|
|
736 FROM_INT_C_TYPE x;
|
|
737 TO_INT_C_TYPE z;
|
|
738 int shift_amount;
|
|
739 memcpy (&x, &a, FROM_FIXED_SIZE);
|
|
740 #if TO_FBITS > FROM_FBITS /* Need left shift. */
|
|
741 shift_amount = TO_FBITS - FROM_FBITS;
|
|
742 z = (TO_INT_C_TYPE) x;
|
|
743 z = z << shift_amount;
|
|
744 #else /* TO_FBITS <= FROM_FBITS. Need right Shift. */
|
|
745 shift_amount = FROM_FBITS - TO_FBITS;
|
|
746 x = x >> shift_amount;
|
|
747 z = (TO_INT_C_TYPE) x;
|
|
748 #endif /* TO_FBITS > FROM_FBITS */
|
|
749
|
|
750 #if TO_HAVE_PADDING_BITS
|
|
751 z = z << TO_PADDING_BITS;
|
|
752 z = z >> TO_PADDING_BITS;
|
|
753 #endif
|
|
754 memcpy (&c, &z, TO_FIXED_SIZE);
|
|
755 return c;
|
|
756 }
|
|
757 #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4 */
|
|
758
|
|
759 /* Fixed -> Fixed with saturation. */
|
|
760 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4
|
|
761 TO_FIXED_C_TYPE
|
|
762 SATFRACT (FROM_FIXED_C_TYPE a)
|
|
763 {
|
|
764 TO_FIXED_C_TYPE c;
|
|
765 TO_INT_C_TYPE z;
|
|
766 FROM_INT_C_TYPE x;
|
|
767 #if FROM_MODE_UNSIGNED == 0
|
|
768 BIG_SINT_C_TYPE high, low;
|
|
769 BIG_SINT_C_TYPE max_high, max_low;
|
|
770 BIG_SINT_C_TYPE min_high, min_low;
|
|
771 #else
|
|
772 BIG_UINT_C_TYPE high, low;
|
|
773 BIG_UINT_C_TYPE max_high, max_low;
|
|
774 BIG_UINT_C_TYPE min_high, min_low;
|
|
775 #endif
|
|
776 #if TO_FBITS > FROM_FBITS
|
|
777 BIG_UINT_C_TYPE utemp;
|
|
778 #endif
|
|
779 #if TO_MODE_UNSIGNED == 0
|
|
780 BIG_SINT_C_TYPE stemp;
|
|
781 #endif
|
|
782 #if TO_FBITS != FROM_FBITS
|
|
783 int shift_amount;
|
|
784 #endif
|
|
785 memcpy (&x, &a, FROM_FIXED_SIZE);
|
|
786
|
|
787 /* Step 1. We need to store x to {high, low}. */
|
|
788 #if FROM_MODE_UNSIGNED == 0
|
|
789 low = (BIG_SINT_C_TYPE) x;
|
|
790 if (x < 0)
|
|
791 high = -1;
|
|
792 else
|
|
793 high = 0;
|
|
794 #else
|
|
795 low = (BIG_UINT_C_TYPE) x;
|
|
796 high = 0;
|
|
797 #endif
|
|
798
|
|
799 /* Step 2. We need to shift {high, low}. */
|
|
800 #if TO_FBITS > FROM_FBITS /* Left shift. */
|
|
801 shift_amount = TO_FBITS - FROM_FBITS;
|
|
802 utemp = (BIG_UINT_C_TYPE) low;
|
|
803 utemp = utemp >> (BIG_WIDTH - shift_amount);
|
|
804 high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
|
|
805 low = low << shift_amount;
|
|
806 #elif TO_FBITS < FROM_FBITS /* Right shift. */
|
|
807 shift_amount = FROM_FBITS - TO_FBITS;
|
|
808 low = low >> shift_amount;
|
|
809 #endif
|
|
810
|
|
811 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
|
|
812 max_high = 0;
|
|
813 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
|
|
814 max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
|
|
815 max_low = max_low - 1;
|
|
816 #else
|
|
817 max_low = -1;
|
|
818 #endif
|
|
819
|
|
820 #if TO_MODE_UNSIGNED == 0
|
|
821 min_high = -1;
|
|
822 stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1);
|
|
823 stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS);
|
|
824 min_low = stemp;
|
|
825 #else
|
|
826 min_high = 0;
|
|
827 min_low = 0;
|
|
828 #endif
|
|
829
|
|
830 #if FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 0
|
|
831 /* Signed -> Signed. */
|
|
832 if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
|
|
833 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
|
|
834 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
|
|
835 low = max_low; /* Maximum. */
|
|
836 else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high
|
|
837 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high
|
|
838 && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low))
|
|
839 low = min_low; /* Minimum. */
|
|
840 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 1
|
|
841 /* Unigned -> Unsigned. */
|
|
842 if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
|
|
843 || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
|
|
844 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
|
|
845 low = max_low; /* Maximum. */
|
|
846 #elif FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 1
|
|
847 /* Signed -> Unsigned. */
|
|
848 if (x < 0)
|
|
849 low = 0; /* Minimum. */
|
|
850 else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
|
|
851 || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
|
|
852 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
|
|
853 low = max_low; /* Maximum. */
|
|
854 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 0
|
|
855 /* Unsigned -> Signed. */
|
|
856 if ((BIG_SINT_C_TYPE) high < 0)
|
|
857 low = max_low; /* Maximum. */
|
|
858 else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
|
|
859 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
|
|
860 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
|
|
861 low = max_low; /* Maximum. */
|
|
862 #endif
|
|
863
|
|
864 /* Step 4. Store the result. */
|
|
865 z = (TO_INT_C_TYPE) low;
|
|
866 #if TO_HAVE_PADDING_BITS
|
|
867 z = z << TO_PADDING_BITS;
|
|
868 z = z >> TO_PADDING_BITS;
|
|
869 #endif
|
|
870 memcpy (&c, &z, TO_FIXED_SIZE);
|
|
871 return c;
|
|
872 }
|
|
873 #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4 */
|
|
874
|
|
875 /* Fixed -> Int. */
|
|
876 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1
|
|
877 TO_INT_C_TYPE
|
|
878 FRACT (FROM_FIXED_C_TYPE a)
|
|
879 {
|
|
880 FROM_INT_C_TYPE x;
|
|
881 TO_INT_C_TYPE z;
|
|
882 FROM_INT_C_TYPE i = 0;
|
|
883 memcpy (&x, &a, FROM_FIXED_SIZE);
|
|
884
|
|
885 #if FROM_MODE_UNSIGNED == 0
|
|
886 if (x < 0)
|
|
887 {
|
|
888 #if FROM_FIXED_WIDTH == FROM_FBITS
|
|
889 if (x != 0)
|
|
890 i = 1;
|
|
891 #else
|
|
892 if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0)
|
|
893 i = 1;
|
|
894 #endif
|
|
895 }
|
|
896 #endif
|
|
897
|
|
898 #if FROM_FIXED_WIDTH == FROM_FBITS
|
|
899 x = 0;
|
|
900 #else
|
|
901 x = x >> FROM_FBITS;
|
|
902 #endif
|
|
903 x = x + i;
|
|
904 z = (TO_INT_C_TYPE) x;
|
|
905 return z;
|
|
906 }
|
|
907 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1 */
|
|
908
|
|
909 /* Fixed -> Unsigned int. */
|
|
910 #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2
|
|
911 TO_INT_C_TYPE
|
|
912 FRACTUNS (FROM_FIXED_C_TYPE a)
|
|
913 {
|
|
914 FROM_INT_C_TYPE x;
|
|
915 TO_INT_C_TYPE z;
|
|
916 FROM_INT_C_TYPE i = 0;
|
|
917 memcpy (&x, &a, FROM_FIXED_SIZE);
|
|
918
|
|
919 #if FROM_MODE_UNSIGNED == 0
|
|
920 if (x < 0)
|
|
921 {
|
|
922 #if FROM_FIXED_WIDTH == FROM_FBITS
|
|
923 if (x != 0)
|
|
924 i = 1;
|
|
925 #else
|
|
926 if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0)
|
|
927 i = 1;
|
|
928 #endif
|
|
929 }
|
|
930 #endif
|
|
931
|
|
932 #if FROM_FIXED_WIDTH == FROM_FBITS
|
|
933 x = 0;
|
|
934 #else
|
|
935 x = x >> FROM_FBITS;
|
|
936 #endif
|
|
937 x = x + i;
|
|
938 z = (TO_INT_C_TYPE) x;
|
|
939 return z;
|
|
940 }
|
|
941 #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2 */
|
|
942
|
|
943 /* Int -> Fixed. */
|
|
944 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4
|
|
945 TO_FIXED_C_TYPE
|
|
946 FRACT (FROM_INT_C_TYPE a)
|
|
947 {
|
|
948 TO_FIXED_C_TYPE c;
|
|
949 TO_INT_C_TYPE z;
|
|
950 z = (TO_INT_C_TYPE) a;
|
|
951 #if TO_FIXED_WIDTH == TO_FBITS
|
|
952 z = 0;
|
|
953 #else
|
|
954 z = z << TO_FBITS;
|
|
955 #endif
|
|
956 #if TO_HAVE_PADDING_BITS
|
|
957 z = z << TO_PADDING_BITS;
|
|
958 z = z >> TO_PADDING_BITS;
|
|
959 #endif
|
|
960 memcpy (&c, &z, TO_FIXED_SIZE);
|
|
961 return c;
|
|
962 }
|
|
963 #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
|
|
964
|
|
965 /* Signed int -> Fixed with saturation. */
|
|
966 #if defined(SATFRACT) && defined(L_satfract) &&FROM_TYPE == 1 && TO_TYPE == 4
|
|
967 TO_FIXED_C_TYPE
|
|
968 SATFRACT (FROM_INT_C_TYPE a)
|
|
969 {
|
|
970 TO_FIXED_C_TYPE c;
|
|
971 TO_INT_C_TYPE z;
|
|
972 FROM_INT_C_TYPE x = a;
|
|
973 BIG_SINT_C_TYPE high, low;
|
|
974 BIG_SINT_C_TYPE max_high, max_low;
|
|
975 BIG_SINT_C_TYPE min_high, min_low;
|
|
976 #if TO_MODE_UNSIGNED == 0
|
|
977 BIG_SINT_C_TYPE stemp;
|
|
978 #endif
|
|
979 #if BIG_WIDTH != TO_FBITS
|
|
980 BIG_UINT_C_TYPE utemp;
|
|
981 int shift_amount;
|
|
982 #endif
|
|
983
|
|
984 /* Step 1. We need to store x to {high, low}. */
|
|
985 low = (BIG_SINT_C_TYPE) x;
|
|
986 if (x < 0)
|
|
987 high = -1;
|
|
988 else
|
|
989 high = 0;
|
|
990
|
|
991 /* Step 2. We need to left shift {high, low}. */
|
|
992 #if BIG_WIDTH == TO_FBITS
|
|
993 high = low;
|
|
994 low = 0;
|
|
995 #else
|
|
996 shift_amount = TO_FBITS;
|
|
997 utemp = (BIG_UINT_C_TYPE) low;
|
|
998 utemp = utemp >> (BIG_WIDTH - shift_amount);
|
|
999 high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
|
|
1000 low = low << shift_amount;
|
|
1001 #endif
|
|
1002
|
|
1003 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
|
|
1004 max_high = 0;
|
|
1005 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
|
|
1006 max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
|
|
1007 max_low = max_low - 1;
|
|
1008 #else
|
|
1009 max_low = -1;
|
|
1010 #endif
|
|
1011
|
|
1012 #if TO_MODE_UNSIGNED == 0
|
|
1013 min_high = -1;
|
|
1014 stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1);
|
|
1015 stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS);
|
|
1016 min_low = stemp;
|
|
1017 #else
|
|
1018 min_high = 0;
|
|
1019 min_low = 0;
|
|
1020 #endif
|
|
1021
|
|
1022 #if TO_MODE_UNSIGNED == 0
|
|
1023 /* Signed -> Signed. */
|
|
1024 if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
|
|
1025 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
|
|
1026 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
|
|
1027 low = max_low; /* Maximum. */
|
|
1028 else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high
|
|
1029 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high
|
|
1030 && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low))
|
|
1031 low = min_low; /* Minimum. */
|
|
1032 #else
|
|
1033 /* Signed -> Unsigned. */
|
|
1034 if (x < 0)
|
|
1035 low = 0; /* Minimum. */
|
|
1036 else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
|
|
1037 || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
|
|
1038 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
|
|
1039 low = max_low; /* Maximum. */
|
|
1040 #endif
|
|
1041
|
|
1042 /* Step 4. Store the result. */
|
|
1043 z = (TO_INT_C_TYPE) low;
|
|
1044 #if TO_HAVE_PADDING_BITS
|
|
1045 z = z << TO_PADDING_BITS;
|
|
1046 z = z >> TO_PADDING_BITS;
|
|
1047 #endif
|
|
1048 memcpy (&c, &z, TO_FIXED_SIZE);
|
|
1049 return c;
|
|
1050 }
|
|
1051 #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
|
|
1052
|
|
1053 /* Unsigned int -> Fixed. */
|
|
1054 #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4
|
|
1055 TO_FIXED_C_TYPE
|
|
1056 FRACTUNS (FROM_INT_C_TYPE a)
|
|
1057 {
|
|
1058 TO_FIXED_C_TYPE c;
|
|
1059 TO_INT_C_TYPE z;
|
|
1060 z = (TO_INT_C_TYPE) a;
|
|
1061 #if TO_FIXED_WIDTH == TO_FBITS
|
|
1062 z = 0;
|
|
1063 #else
|
|
1064 z = z << TO_FBITS;
|
|
1065 #endif
|
|
1066 #if TO_HAVE_PADDING_BITS
|
|
1067 z = z << TO_PADDING_BITS;
|
|
1068 z = z >> TO_PADDING_BITS;
|
|
1069 #endif
|
|
1070 memcpy (&c, &z, TO_FIXED_SIZE);
|
|
1071 return c;
|
|
1072 }
|
|
1073 #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
|
|
1074
|
|
1075 /* Unsigned int -> Fixed with saturation. */
|
|
1076 #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4
|
|
1077 TO_FIXED_C_TYPE
|
|
1078 SATFRACTUNS (FROM_INT_C_TYPE a)
|
|
1079 {
|
|
1080 TO_FIXED_C_TYPE c;
|
|
1081 TO_INT_C_TYPE z;
|
|
1082 FROM_INT_C_TYPE x = a;
|
|
1083 BIG_UINT_C_TYPE high, low;
|
|
1084 BIG_UINT_C_TYPE max_high, max_low;
|
|
1085 #if BIG_WIDTH != TO_FBITS
|
|
1086 BIG_UINT_C_TYPE utemp;
|
|
1087 int shift_amount;
|
|
1088 #endif
|
|
1089
|
|
1090 /* Step 1. We need to store x to {high, low}. */
|
|
1091 low = (BIG_UINT_C_TYPE) x;
|
|
1092 high = 0;
|
|
1093
|
|
1094 /* Step 2. We need to left shift {high, low}. */
|
|
1095 #if BIG_WIDTH == TO_FBITS
|
|
1096 high = low;
|
|
1097 low = 0;
|
|
1098 #else
|
|
1099 shift_amount = TO_FBITS;
|
|
1100 utemp = (BIG_UINT_C_TYPE) low;
|
|
1101 utemp = utemp >> (BIG_WIDTH - shift_amount);
|
|
1102 high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
|
|
1103 low = low << shift_amount;
|
|
1104 #endif
|
|
1105
|
|
1106 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
|
|
1107 max_high = 0;
|
|
1108 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
|
|
1109 max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
|
|
1110 max_low = max_low - 1;
|
|
1111 #else
|
|
1112 max_low = -1;
|
|
1113 #endif
|
|
1114
|
|
1115 #if TO_MODE_UNSIGNED == 1
|
|
1116 /* Unigned -> Unsigned. */
|
|
1117 if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
|
|
1118 || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
|
|
1119 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
|
|
1120 low = max_low; /* Maximum. */
|
|
1121 #else
|
|
1122 /* Unsigned -> Signed. */
|
|
1123 if ((BIG_SINT_C_TYPE) high < 0)
|
|
1124 low = max_low; /* Maximum. */
|
|
1125 else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
|
|
1126 || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
|
|
1127 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
|
|
1128 low = max_low; /* Maximum. */
|
|
1129 #endif
|
|
1130
|
|
1131 /* Step 4. Store the result. */
|
|
1132 z = (TO_INT_C_TYPE) low;
|
|
1133 #if TO_HAVE_PADDING_BITS
|
|
1134 z = z << TO_PADDING_BITS;
|
|
1135 z = z >> TO_PADDING_BITS;
|
|
1136 #endif
|
|
1137 memcpy (&c, &z, TO_FIXED_SIZE);
|
|
1138 return c;
|
|
1139 }
|
|
1140 #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
|
|
1141
|
|
1142 /* Fixed -> Float. */
|
|
1143 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3
|
|
1144 TO_FLOAT_C_TYPE
|
|
1145 FRACT (FROM_FIXED_C_TYPE a)
|
|
1146 {
|
|
1147 FROM_INT_C_TYPE x;
|
|
1148 TO_FLOAT_C_TYPE z;
|
|
1149 memcpy (&x, &a, FROM_FIXED_SIZE);
|
|
1150 z = (TO_FLOAT_C_TYPE) x;
|
|
1151 z = z / BASE;
|
|
1152 return z;
|
|
1153 }
|
|
1154 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3 */
|
|
1155
|
|
1156 /* Float -> Fixed. */
|
|
1157 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4
|
|
1158 TO_FIXED_C_TYPE
|
|
1159 FRACT (FROM_FLOAT_C_TYPE a)
|
|
1160 {
|
|
1161 FROM_FLOAT_C_TYPE temp;
|
|
1162 TO_INT_C_TYPE z;
|
|
1163 TO_FIXED_C_TYPE c;
|
|
1164
|
|
1165 temp = a * BASE;
|
|
1166 z = (TO_INT_C_TYPE) temp;
|
|
1167 #if TO_HAVE_PADDING_BITS
|
|
1168 z = z << TO_PADDING_BITS;
|
|
1169 z = z >> TO_PADDING_BITS;
|
|
1170 #endif
|
|
1171 memcpy (&c, &z, TO_FIXED_SIZE);
|
|
1172 return c;
|
|
1173 }
|
|
1174 #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */
|
|
1175
|
|
1176 /* Float -> Fixed with saturation. */
|
|
1177 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4
|
|
1178 TO_FIXED_C_TYPE
|
|
1179 SATFRACT (FROM_FLOAT_C_TYPE a)
|
|
1180 {
|
|
1181 FROM_FLOAT_C_TYPE temp;
|
|
1182 TO_INT_C_TYPE z;
|
|
1183 TO_FIXED_C_TYPE c;
|
|
1184
|
|
1185 if (a >= FIXED_MAX)
|
|
1186 {
|
|
1187 #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
|
|
1188 z = (TO_INT_C_TYPE)1 << TO_I_F_BITS;
|
|
1189 z = z - 1;
|
|
1190 #else
|
|
1191 z = -1;
|
|
1192 #endif
|
|
1193 }
|
|
1194 else if (a <= FIXED_MIN)
|
|
1195 {
|
|
1196 #if TO_MODE_UNSIGNED == 0
|
|
1197 z = (TO_INT_C_TYPE)1 << TO_I_F_BITS;
|
|
1198 #else
|
|
1199 z = 0;
|
|
1200 #endif
|
|
1201 }
|
|
1202 else
|
|
1203 {
|
|
1204 temp = a * BASE;
|
|
1205 z = (TO_INT_C_TYPE) temp;
|
|
1206 }
|
|
1207
|
|
1208 #if TO_HAVE_PADDING_BITS
|
|
1209 z = z << TO_PADDING_BITS;
|
|
1210 z = z >> TO_PADDING_BITS;
|
|
1211 #endif
|
|
1212 memcpy (&c, &z, TO_FIXED_SIZE);
|
|
1213 return c;
|
|
1214 }
|
|
1215 #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */
|
|
1216
|