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