1 /* This is a software fixed-point library.
2 Copyright (C) 2007-2020 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 #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
FIXED_ADD(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_SSADD(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_USADD(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_SUB(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_SSSUB(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_USSUB(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_SATURATE1(DINT_C_TYPE * a)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
FIXED_SATURATE2(INT_C_TYPE * high,INT_C_TYPE * low)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
FIXED_MULHELPER(FIXED_C_TYPE a,FIXED_C_TYPE b,word_type satp)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
FIXED_MUL(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_SSMUL(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_USMUL(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_DIVHELPER(FIXED_C_TYPE a,FIXED_C_TYPE b,word_type satp)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
FIXED_DIV(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_UDIV(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_SSDIV(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_USDIV(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FIXED_NEG(FIXED_C_TYPE a)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
FIXED_SSNEG(FIXED_C_TYPE a)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
FIXED_USNEG(FIXED_C_TYPE a)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
FIXED_ASHLHELPER(FIXED_C_TYPE a,word_type b,word_type satp)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
FIXED_ASHL(FIXED_C_TYPE a,word_type b)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
FIXED_ASHR(FIXED_C_TYPE a,word_type b)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
FIXED_LSHR(FIXED_C_TYPE a,word_type b)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
FIXED_SSASHL(FIXED_C_TYPE a,word_type b)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
FIXED_USASHL(FIXED_C_TYPE a,word_type b)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
FIXED_CMP(FIXED_C_TYPE a,FIXED_C_TYPE b)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
FRACT(FROM_FIXED_C_TYPE a)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
SATFRACT(FROM_FIXED_C_TYPE a)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
FRACT(FROM_FIXED_C_TYPE a)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
FRACTUNS(FROM_FIXED_C_TYPE a)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
FRACT(FROM_INT_C_TYPE a)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
SATFRACT(FROM_INT_C_TYPE a)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
FRACTUNS(FROM_INT_C_TYPE a)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
SATFRACTUNS(FROM_INT_C_TYPE a)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
FRACT(FROM_FIXED_C_TYPE a)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
FRACT(FROM_FLOAT_C_TYPE a)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
SATFRACT(FROM_FLOAT_C_TYPE a)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
1206