1 /* This is a software fixed-point library.
2 Copyright (C) 2007, 2009, 2011 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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.
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/>. */
25 /* This implements fixed-point arithmetic.
27 Contributed by Chao-ying Fu <fu@mips.com>. */
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,
33 Then, all operators for this machine mode will be created.
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
47 #include "coretypes.h"
49 #include "libgcc_tm.h"
51 #ifndef MIN_UNITS_PER_WORD
52 #define MIN_UNITS_PER_WORD UNITS_PER_WORD
55 #include "fixed-bit.h"
57 #if defined(FIXED_ADD) && defined(L_add)
59 FIXED_ADD (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
63 memcpy (&x
, &a
, FIXED_SIZE
);
64 memcpy (&y
, &b
, FIXED_SIZE
);
67 z
= z
<< PADDING_BITS
;
68 z
= z
>> PADDING_BITS
;
70 memcpy (&c
, &z
, FIXED_SIZE
);
73 #endif /* FIXED_ADD */
75 #if defined(FIXED_SSADD) && defined(L_ssadd)
77 FIXED_SSADD (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
81 memcpy (&x
, &a
, FIXED_SIZE
);
82 memcpy (&y
, &b
, FIXED_SIZE
);
84 if ((((x
^ y
) >> I_F_BITS
) & 1) == 0)
86 if (((z
^ x
) >> I_F_BITS
) & 1)
95 z
= z
<< PADDING_BITS
;
96 z
= z
>> PADDING_BITS
;
98 memcpy (&c
, &z
, FIXED_SIZE
);
101 #endif /* FIXED_SSADD */
103 #if defined(FIXED_USADD) && defined(L_usadd)
105 FIXED_USADD (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
109 memcpy (&x
, &a
, FIXED_SIZE
);
110 memcpy (&y
, &b
, FIXED_SIZE
);
112 #if HAVE_PADDING_BITS
113 z
= z
<< PADDING_BITS
;
114 z
= z
>> PADDING_BITS
;
116 if (z
< x
|| z
< y
) /* max */
119 #if HAVE_PADDING_BITS
120 z
= z
<< PADDING_BITS
;
121 z
= z
>> PADDING_BITS
;
124 memcpy (&c
, &z
, FIXED_SIZE
);
127 #endif /* FIXED_USADD */
129 #if defined(FIXED_SUB) && defined(L_sub)
131 FIXED_SUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
135 memcpy (&x
, &a
, FIXED_SIZE
);
136 memcpy (&y
, &b
, FIXED_SIZE
);
138 #if HAVE_PADDING_BITS
139 z
= z
<< PADDING_BITS
;
140 z
= z
>> PADDING_BITS
;
142 memcpy (&c
, &z
, FIXED_SIZE
);
145 #endif /* FIXED_SUB */
147 #if defined(FIXED_SSSUB) && defined(L_sssub)
149 FIXED_SSSUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
153 memcpy (&x
, &a
, FIXED_SIZE
);
154 memcpy (&y
, &b
, FIXED_SIZE
);
156 if (((x
^ y
) >> I_F_BITS
) & 1)
158 if (((z
^ x
) >> I_F_BITS
) & 1)
166 #if HAVE_PADDING_BITS
167 z
= z
<< PADDING_BITS
;
168 z
= z
>> PADDING_BITS
;
170 memcpy (&c
, &z
, FIXED_SIZE
);
173 #endif /* FIXED_SSSUB */
175 #if defined(FIXED_USSUB) && defined(L_ussub)
177 FIXED_USSUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
181 memcpy (&x
, &a
, FIXED_SIZE
);
182 memcpy (&y
, &b
, FIXED_SIZE
);
186 #if HAVE_PADDING_BITS
187 z
= z
<< PADDING_BITS
;
188 z
= z
>> PADDING_BITS
;
190 memcpy (&c
, &z
, FIXED_SIZE
);
193 #endif /* FIXED_USSUB */
195 #if defined(FIXED_SATURATE1) && defined(L_saturate1)
197 FIXED_SATURATE1 (DINT_C_TYPE
*a
)
199 DINT_C_TYPE max
, min
;
200 max
= (DINT_C_TYPE
)1 << I_F_BITS
;
202 #if MODE_UNSIGNED == 0
203 min
= (DINT_C_TYPE
)1 << (2 * FIXED_WIDTH
- 1);
204 min
= min
>> (2 * FIXED_WIDTH
- 1 - I_F_BITS
);
213 #endif /* FIXED_SATURATE1 */
215 #if defined(FIXED_SATURATE2) && defined(L_saturate2)
217 FIXED_SATURATE2 (INT_C_TYPE
*high
, INT_C_TYPE
*low
)
219 INT_C_TYPE r_max
, s_max
, r_min
, s_min
;
221 #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS
222 s_max
= (INT_C_TYPE
)1 << I_F_BITS
;
227 #if MODE_UNSIGNED == 0
229 s_min
= (INT_C_TYPE
)1 << (FIXED_WIDTH
- 1);
230 s_min
= s_min
>> (FIXED_WIDTH
- 1 - I_F_BITS
);
237 || (*high
== r_max
&& (UINT_C_TYPE
)(*low
) > (UINT_C_TYPE
)s_max
))
242 else if (*high
< r_min
||
243 (*high
== r_min
&& (UINT_C_TYPE
)(*low
) < (UINT_C_TYPE
)s_min
))
249 #endif /* FIXED_SATURATE2 */
251 #if defined(FIXED_MULHELPER) && defined(L_mulhelper)
253 FIXED_MULHELPER (FIXED_C_TYPE a
, FIXED_C_TYPE b
, word_type satp
)
258 #if defined (DINT_C_TYPE)
260 DINT_C_TYPE dx
, dy
, dz
;
261 memcpy (&x
, &a
, FIXED_SIZE
);
262 memcpy (&y
, &b
, FIXED_SIZE
);
263 dx
= (DINT_C_TYPE
) x
;
264 dy
= (DINT_C_TYPE
) y
;
266 /* Round the result by adding (1 << (FBITS -1)). */
267 dz
+= ((DINT_C_TYPE
) 1 << (FBITS
- 1));
270 FIXED_SATURATE1 (&dz
);
273 #if HAVE_PADDING_BITS
274 z
= z
<< PADDING_BITS
;
275 z
= z
>> PADDING_BITS
;
277 memcpy (&c
, &z
, FIXED_SIZE
);
280 #else /* No DINT_C_TYPE */
281 /* The result of multiplication expands to two INT_C_TYPE. */
283 INTunion a_high
, a_low
, b_high
, b_low
;
284 INTunion high_high
, high_low
, low_high
, low_low
;
285 INTunion r
, s
, temp1
, temp2
;
286 INT_C_TYPE carry
= 0;
289 memcpy (&x
, &a
, FIXED_SIZE
);
290 memcpy (&y
, &b
, FIXED_SIZE
);
292 /* Decompose a and b. */
296 a_high
.s
.low
= aa
.s
.high
;
298 a_low
.s
.low
= aa
.s
.low
;
300 b_high
.s
.low
= bb
.s
.high
;
302 b_low
.s
.low
= bb
.s
.low
;
305 /* Perform four multiplications. */
306 low_low
.ll
= a_low
.ll
* b_low
.ll
;
307 low_high
.ll
= a_low
.ll
* b_high
.ll
;
308 high_low
.ll
= a_high
.ll
* b_low
.ll
;
309 high_high
.ll
= a_high
.ll
* b_high
.ll
;
311 /* Accumulate four results to {r, s}. */
312 temp1
.s
.high
= high_low
.s
.low
;
314 s
.ll
= low_low
.ll
+ temp1
.ll
;
315 if ((UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) low_low
.ll
316 || (UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp1
.ll
)
317 carry
++; /* Carry. */
319 temp2
.s
.high
= low_high
.s
.low
;
321 s
.ll
= temp1
.ll
+ temp2
.ll
;
322 if ((UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp1
.ll
323 || (UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp2
.ll
)
324 carry
++; /* Carry. */
326 temp1
.s
.low
= high_low
.s
.high
;
328 r
.ll
= high_high
.ll
+ temp1
.ll
;
329 temp1
.s
.low
= low_high
.s
.high
;
331 r
.ll
= r
.ll
+ temp1
.ll
+ carry
;
333 #if MODE_UNSIGNED == 0
334 /* For signed types, we need to add neg(y) to r, if x < 0. */
337 /* We need to add neg(x) to r, if y < 0. */
342 /* Round the result by adding (1 << (FBITS -1)). */
344 s
.ll
+= ((INT_C_TYPE
) 1 << (FBITS
-1));
345 if ((UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp1
.ll
346 || (UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) ((INT_C_TYPE
) 1 << (FBITS
-1)))
349 /* Shift right the result by FBITS. */
350 #if FBITS == FIXED_WIDTH
351 /* This happens only for unsigned types without any padding bits.
352 So, it is safe to set r.ll to 0 as it is logically shifted right. */
356 s
.ll
= ((UINT_C_TYPE
)s
.ll
) >> FBITS
;
357 temp1
.ll
= r
.ll
<< (FIXED_WIDTH
- FBITS
);
358 s
.ll
= s
.ll
| temp1
.ll
;
359 r
.ll
= r
.ll
>> FBITS
;
363 FIXED_SATURATE2 (&r
.ll
, &s
.ll
);
365 z
= (INT_C_TYPE
) s
.ll
;
366 #if HAVE_PADDING_BITS
367 z
= z
<< PADDING_BITS
;
368 z
= z
>> PADDING_BITS
;
370 memcpy (&c
, &z
, FIXED_SIZE
);
374 #endif /* FIXED_MULHELPER */
376 #if defined(FIXED_MUL) && defined(L_mul)
378 FIXED_MUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
380 return FIXED_MULHELPER (a
, b
, 0);
382 #endif /* FIXED_MUL */
384 #if defined(FIXED_SSMUL) && defined(L_ssmul)
386 FIXED_SSMUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
388 return FIXED_MULHELPER (a
, b
, 1);
390 #endif /* FIXED_SSMUL */
392 #if defined(FIXED_USMUL) && defined(L_usmul)
394 FIXED_USMUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
396 return FIXED_MULHELPER (a
, b
, 1);
398 #endif /* FIXED_USMUL */
400 #if defined(FIXED_DIVHELPER) && defined(L_divhelper)
402 FIXED_DIVHELPER (FIXED_C_TYPE a
, FIXED_C_TYPE b
, word_type satp
)
408 #if defined (DINT_C_TYPE)
409 DINT_C_TYPE dx
, dy
, dz
;
410 memcpy (&x
, &a
, FIXED_SIZE
);
411 memcpy (&y
, &b
, FIXED_SIZE
);
412 dx
= (DINT_C_TYPE
) x
;
413 dy
= (DINT_C_TYPE
) y
;
417 FIXED_SATURATE1 (&dz
);
419 #if HAVE_PADDING_BITS
420 z
= z
<< PADDING_BITS
;
421 z
= z
>> PADDING_BITS
;
423 memcpy (&c
, &z
, FIXED_SIZE
);
426 #else /* No DINT_C_TYPE */
427 INT_C_TYPE pos_a
, pos_b
, r
, s
;
428 INT_C_TYPE quo_r
, quo_s
, mod
, temp
;
430 #if MODE_UNSIGNED == 0
431 word_type num_of_neg
= 0;
434 memcpy (&x
, &a
, FIXED_SIZE
);
435 memcpy (&y
, &b
, FIXED_SIZE
);
439 #if MODE_UNSIGNED == 0
440 /* If a < 0, negate a. */
446 /* If b < 0, negate b. */
454 /* Left shift pos_a to {r, s} by FBITS. */
455 #if FBITS == FIXED_WIDTH
456 /* This happens only for unsigned types without any padding bits. */
461 r
= pos_a
>> (FIXED_WIDTH
- FBITS
);
464 /* Unsigned divide r by pos_b to quo_r. The remainder is in mod. */
465 quo_r
= (UINT_C_TYPE
)r
/ (UINT_C_TYPE
)pos_b
;
466 mod
= (UINT_C_TYPE
)r
% (UINT_C_TYPE
)pos_b
;
469 for (i
= 0; i
< FIXED_WIDTH
; i
++)
471 /* Record the leftmost bit of mod. */
472 word_type leftmost_mode
= (mod
>> (FIXED_WIDTH
- 1)) & 1;
473 /* Shift left mod by 1 bit. */
475 /* Test the leftmost bit of s to add to mod. */
476 if ((s
>> (FIXED_WIDTH
- 1)) & 1)
478 /* Shift left quo_s by 1 bit. */
480 /* Try to calculate (mod - pos_b). */
482 if (leftmost_mode
|| (UINT_C_TYPE
)mod
>= (UINT_C_TYPE
)pos_b
)
487 /* Shift left s by 1 bit. */
491 #if MODE_UNSIGNED == 0
502 FIXED_SATURATE2 (&quo_r
, &quo_s
);
504 #if HAVE_PADDING_BITS
505 z
= z
<< PADDING_BITS
;
506 z
= z
>> PADDING_BITS
;
508 memcpy (&c
, &z
, FIXED_SIZE
);
512 #endif /* FIXED_DIVHELPER */
514 #if defined(FIXED_DIV) && defined(L_div)
516 FIXED_DIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
518 return FIXED_DIVHELPER (a
, b
, 0);
520 #endif /* FIXED_DIV */
523 #if defined(FIXED_UDIV) && defined(L_udiv)
525 FIXED_UDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
527 return FIXED_DIVHELPER (a
, b
, 0);
529 #endif /* FIXED_UDIV */
531 #if defined(FIXED_SSDIV) && defined(L_ssdiv)
533 FIXED_SSDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
535 return FIXED_DIVHELPER (a
, b
, 1);
537 #endif /* FIXED_SSDIV */
539 #if defined(FIXED_USDIV) && defined(L_usdiv)
541 FIXED_USDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
543 return FIXED_DIVHELPER (a
, b
, 1);
545 #endif /* FIXED_USDIV */
547 #if defined(FIXED_NEG) && defined(L_neg)
549 FIXED_NEG (FIXED_C_TYPE a
)
553 memcpy (&x
, &a
, FIXED_SIZE
);
555 #if HAVE_PADDING_BITS
556 z
= z
<< PADDING_BITS
;
557 z
= z
>> PADDING_BITS
;
559 memcpy (&c
, &z
, FIXED_SIZE
);
562 #endif /* FIXED_NEG */
564 #if defined(FIXED_SSNEG) && defined(L_ssneg)
566 FIXED_SSNEG (FIXED_C_TYPE a
)
570 memcpy (&y
, &a
, FIXED_SIZE
);
573 if (((x
^ y
) >> I_F_BITS
) & 1)
575 if (((z
^ x
) >> I_F_BITS
) & 1)
583 #if HAVE_PADDING_BITS
584 z
= z
<< PADDING_BITS
;
585 z
= z
>> PADDING_BITS
;
587 memcpy (&c
, &z
, FIXED_SIZE
);
590 #endif /* FIXED_SSNEG */
592 #if defined(FIXED_USNEG) && defined(L_usneg)
594 FIXED_USNEG (FIXED_C_TYPE a
__attribute__ ((__unused__
)))
599 memcpy (&c
, &z
, FIXED_SIZE
);
602 #endif /* FIXED_USNEG */
604 #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper)
606 FIXED_ASHLHELPER (FIXED_C_TYPE a
, word_type b
, word_type satp
)
611 #if defined (DINT_C_TYPE)
613 memcpy (&x
, &a
, FIXED_SIZE
);
614 dx
= (DINT_C_TYPE
) x
;
615 if (b
>= FIXED_WIDTH
)
616 dz
= dx
<< FIXED_WIDTH
;
620 FIXED_SATURATE1 (&dz
);
622 #if HAVE_PADDING_BITS
623 z
= z
<< PADDING_BITS
;
624 z
= z
>> PADDING_BITS
;
626 memcpy (&c
, &z
, FIXED_SIZE
);
629 #else /* No DINT_C_TYPE */
631 memcpy (&x
, &a
, FIXED_SIZE
);
632 /* We need to shift left x by b bits to {r, s}. */
633 if (b
>= FIXED_WIDTH
)
641 r
= x
>> (FIXED_WIDTH
- b
);
644 FIXED_SATURATE2 (&r
, &s
);
646 #if HAVE_PADDING_BITS
647 z
= z
<< PADDING_BITS
;
648 z
= z
>> PADDING_BITS
;
650 memcpy (&c
, &z
, FIXED_SIZE
);
654 #endif /* FIXED_ASHLHELPER */
656 #if defined(FIXED_ASHL) && defined(L_ashl)
658 FIXED_ASHL (FIXED_C_TYPE a
, word_type b
)
660 return FIXED_ASHLHELPER (a
, b
, 0);
662 #endif /* FIXED_ASHL */
664 #if defined(FIXED_ASHR) && defined(L_ashr)
666 FIXED_ASHR (FIXED_C_TYPE a
, word_type b
)
670 memcpy (&x
, &a
, FIXED_SIZE
);
672 #if HAVE_PADDING_BITS
673 z
= z
<< PADDING_BITS
;
674 z
= z
>> PADDING_BITS
;
676 memcpy (&c
, &z
, FIXED_SIZE
);
679 #endif /* FIXED_ASHR */
681 #if defined(FIXED_LSHR) && defined(L_lshr)
683 FIXED_LSHR (FIXED_C_TYPE a
, word_type b
)
687 memcpy (&x
, &a
, FIXED_SIZE
);
689 #if HAVE_PADDING_BITS
690 z
= z
<< PADDING_BITS
;
691 z
= z
>> PADDING_BITS
;
693 memcpy (&c
, &z
, FIXED_SIZE
);
696 #endif /* FIXED_LSHR */
698 #if defined(FIXED_SSASHL) && defined(L_ssashl)
700 FIXED_SSASHL (FIXED_C_TYPE a
, word_type b
)
702 return FIXED_ASHLHELPER (a
, b
, 1);
704 #endif /* FIXED_SSASHL */
706 #if defined(FIXED_USASHL) && defined(L_usashl)
708 FIXED_USASHL (FIXED_C_TYPE a
, word_type b
)
710 return FIXED_ASHLHELPER (a
, b
, 1);
712 #endif /* FIXED_USASHL */
714 #if defined(FIXED_CMP) && defined(L_cmp)
716 FIXED_CMP (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
719 memcpy (&x
, &a
, FIXED_SIZE
);
720 memcpy (&y
, &b
, FIXED_SIZE
);
729 #endif /* FIXED_CMP */
731 /* Fixed -> Fixed. */
732 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4
734 FRACT (FROM_FIXED_C_TYPE a
)
740 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
741 #if TO_FBITS > FROM_FBITS /* Need left shift. */
742 shift_amount
= TO_FBITS
- FROM_FBITS
;
743 z
= (TO_INT_C_TYPE
) x
;
744 z
= z
<< shift_amount
;
745 #else /* TO_FBITS <= FROM_FBITS. Need right Shift. */
746 shift_amount
= FROM_FBITS
- TO_FBITS
;
747 x
= x
>> shift_amount
;
748 z
= (TO_INT_C_TYPE
) x
;
749 #endif /* TO_FBITS > FROM_FBITS */
751 #if TO_HAVE_PADDING_BITS
752 z
= z
<< TO_PADDING_BITS
;
753 z
= z
>> TO_PADDING_BITS
;
755 memcpy (&c
, &z
, TO_FIXED_SIZE
);
758 #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4 */
760 /* Fixed -> Fixed with saturation. */
761 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4
763 SATFRACT (FROM_FIXED_C_TYPE a
)
768 #if FROM_MODE_UNSIGNED == 0
769 BIG_SINT_C_TYPE high
, low
;
770 BIG_SINT_C_TYPE max_high
, max_low
;
771 BIG_SINT_C_TYPE min_high
, min_low
;
773 BIG_UINT_C_TYPE high
, low
;
774 BIG_UINT_C_TYPE max_high
, max_low
;
775 BIG_UINT_C_TYPE min_high
, min_low
;
777 #if TO_FBITS > FROM_FBITS
778 BIG_UINT_C_TYPE utemp
;
780 #if TO_MODE_UNSIGNED == 0
781 BIG_SINT_C_TYPE stemp
;
783 #if TO_FBITS != FROM_FBITS
786 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
788 /* Step 1. We need to store x to {high, low}. */
789 #if FROM_MODE_UNSIGNED == 0
790 low
= (BIG_SINT_C_TYPE
) x
;
796 low
= (BIG_UINT_C_TYPE
) x
;
800 /* Step 2. We need to shift {high, low}. */
801 #if TO_FBITS > FROM_FBITS /* Left shift. */
802 shift_amount
= TO_FBITS
- FROM_FBITS
;
803 utemp
= (BIG_UINT_C_TYPE
) low
;
804 utemp
= utemp
>> (BIG_WIDTH
- shift_amount
);
805 high
= ((BIG_UINT_C_TYPE
)(high
<< shift_amount
)) | utemp
;
806 low
= low
<< shift_amount
;
807 #elif TO_FBITS < FROM_FBITS /* Right shift. */
808 shift_amount
= FROM_FBITS
- TO_FBITS
;
809 low
= low
>> shift_amount
;
812 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
814 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
815 max_low
= (BIG_UINT_C_TYPE
)1 << TO_I_F_BITS
;
816 max_low
= max_low
- 1;
821 #if TO_MODE_UNSIGNED == 0
823 stemp
= (BIG_SINT_C_TYPE
)1 << (BIG_WIDTH
- 1);
824 stemp
= stemp
>> (BIG_WIDTH
- 1 - TO_I_F_BITS
);
831 #if FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 0
832 /* Signed -> Signed. */
833 if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
834 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
835 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
836 low
= max_low
; /* Maximum. */
837 else if ((BIG_SINT_C_TYPE
) high
< (BIG_SINT_C_TYPE
) min_high
838 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) min_high
839 && (BIG_UINT_C_TYPE
) low
< (BIG_UINT_C_TYPE
) min_low
))
840 low
= min_low
; /* Minimum. */
841 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 1
842 /* Unigned -> Unsigned. */
843 if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
844 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
845 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
846 low
= max_low
; /* Maximum. */
847 #elif FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 1
848 /* Signed -> Unsigned. */
850 low
= 0; /* Minimum. */
851 else if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
852 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
853 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
854 low
= max_low
; /* Maximum. */
855 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 0
856 /* Unsigned -> Signed. */
857 if ((BIG_SINT_C_TYPE
) high
< 0)
858 low
= max_low
; /* Maximum. */
859 else if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
860 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
861 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
862 low
= max_low
; /* Maximum. */
865 /* Step 4. Store the result. */
866 z
= (TO_INT_C_TYPE
) low
;
867 #if TO_HAVE_PADDING_BITS
868 z
= z
<< TO_PADDING_BITS
;
869 z
= z
>> TO_PADDING_BITS
;
871 memcpy (&c
, &z
, TO_FIXED_SIZE
);
874 #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4 */
877 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1
879 FRACT (FROM_FIXED_C_TYPE a
)
883 FROM_INT_C_TYPE i
= 0;
884 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
886 #if FROM_MODE_UNSIGNED == 0
889 #if FROM_FIXED_WIDTH == FROM_FBITS
893 if (((FROM_INT_C_TYPE
)(x
<< (FROM_FIXED_WIDTH
- FROM_FBITS
))) != 0)
899 #if FROM_FIXED_WIDTH == FROM_FBITS
905 z
= (TO_INT_C_TYPE
) x
;
908 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1 */
910 /* Fixed -> Unsigned int. */
911 #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2
913 FRACTUNS (FROM_FIXED_C_TYPE a
)
917 FROM_INT_C_TYPE i
= 0;
918 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
920 #if FROM_MODE_UNSIGNED == 0
923 #if FROM_FIXED_WIDTH == FROM_FBITS
927 if (((FROM_INT_C_TYPE
)(x
<< (FROM_FIXED_WIDTH
- FROM_FBITS
))) != 0)
933 #if FROM_FIXED_WIDTH == FROM_FBITS
939 z
= (TO_INT_C_TYPE
) x
;
942 #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2 */
945 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4
947 FRACT (FROM_INT_C_TYPE a
)
951 z
= (TO_INT_C_TYPE
) a
;
952 #if TO_FIXED_WIDTH == TO_FBITS
957 #if TO_HAVE_PADDING_BITS
958 z
= z
<< TO_PADDING_BITS
;
959 z
= z
>> TO_PADDING_BITS
;
961 memcpy (&c
, &z
, TO_FIXED_SIZE
);
964 #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
966 /* Signed int -> Fixed with saturation. */
967 #if defined(SATFRACT) && defined(L_satfract) &&FROM_TYPE == 1 && TO_TYPE == 4
969 SATFRACT (FROM_INT_C_TYPE a
)
973 FROM_INT_C_TYPE x
= a
;
974 BIG_SINT_C_TYPE high
, low
;
975 BIG_SINT_C_TYPE max_high
, max_low
;
976 BIG_SINT_C_TYPE min_high
, min_low
;
977 #if TO_MODE_UNSIGNED == 0
978 BIG_SINT_C_TYPE stemp
;
980 #if BIG_WIDTH != TO_FBITS
981 BIG_UINT_C_TYPE utemp
;
985 /* Step 1. We need to store x to {high, low}. */
986 low
= (BIG_SINT_C_TYPE
) x
;
992 /* Step 2. We need to left shift {high, low}. */
993 #if BIG_WIDTH == TO_FBITS
997 shift_amount
= TO_FBITS
;
998 utemp
= (BIG_UINT_C_TYPE
) low
;
999 utemp
= utemp
>> (BIG_WIDTH
- shift_amount
);
1000 high
= ((BIG_UINT_C_TYPE
)(high
<< shift_amount
)) | utemp
;
1001 low
= low
<< shift_amount
;
1004 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
1006 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1007 max_low
= (BIG_UINT_C_TYPE
)1 << TO_I_F_BITS
;
1008 max_low
= max_low
- 1;
1013 #if TO_MODE_UNSIGNED == 0
1015 stemp
= (BIG_SINT_C_TYPE
)1 << (BIG_WIDTH
- 1);
1016 stemp
= stemp
>> (BIG_WIDTH
- 1 - TO_I_F_BITS
);
1023 #if TO_MODE_UNSIGNED == 0
1024 /* Signed -> Signed. */
1025 if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
1026 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
1027 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1028 low
= max_low
; /* Maximum. */
1029 else if ((BIG_SINT_C_TYPE
) high
< (BIG_SINT_C_TYPE
) min_high
1030 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) min_high
1031 && (BIG_UINT_C_TYPE
) low
< (BIG_UINT_C_TYPE
) min_low
))
1032 low
= min_low
; /* Minimum. */
1034 /* Signed -> Unsigned. */
1036 low
= 0; /* Minimum. */
1037 else if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
1038 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
1039 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1040 low
= max_low
; /* Maximum. */
1043 /* Step 4. Store the result. */
1044 z
= (TO_INT_C_TYPE
) low
;
1045 #if TO_HAVE_PADDING_BITS
1046 z
= z
<< TO_PADDING_BITS
;
1047 z
= z
>> TO_PADDING_BITS
;
1049 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1052 #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
1054 /* Unsigned int -> Fixed. */
1055 #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4
1057 FRACTUNS (FROM_INT_C_TYPE a
)
1061 z
= (TO_INT_C_TYPE
) a
;
1062 #if TO_FIXED_WIDTH == TO_FBITS
1067 #if TO_HAVE_PADDING_BITS
1068 z
= z
<< TO_PADDING_BITS
;
1069 z
= z
>> TO_PADDING_BITS
;
1071 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1074 #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
1076 /* Unsigned int -> Fixed with saturation. */
1077 #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4
1079 SATFRACTUNS (FROM_INT_C_TYPE a
)
1083 FROM_INT_C_TYPE x
= a
;
1084 BIG_UINT_C_TYPE high
, low
;
1085 BIG_UINT_C_TYPE max_high
, max_low
;
1086 #if BIG_WIDTH != TO_FBITS
1087 BIG_UINT_C_TYPE utemp
;
1091 /* Step 1. We need to store x to {high, low}. */
1092 low
= (BIG_UINT_C_TYPE
) x
;
1095 /* Step 2. We need to left shift {high, low}. */
1096 #if BIG_WIDTH == TO_FBITS
1100 shift_amount
= TO_FBITS
;
1101 utemp
= (BIG_UINT_C_TYPE
) low
;
1102 utemp
= utemp
>> (BIG_WIDTH
- shift_amount
);
1103 high
= ((BIG_UINT_C_TYPE
)(high
<< shift_amount
)) | utemp
;
1104 low
= low
<< shift_amount
;
1107 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
1109 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1110 max_low
= (BIG_UINT_C_TYPE
)1 << TO_I_F_BITS
;
1111 max_low
= max_low
- 1;
1116 #if TO_MODE_UNSIGNED == 1
1117 /* Unigned -> Unsigned. */
1118 if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
1119 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
1120 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1121 low
= max_low
; /* Maximum. */
1123 /* Unsigned -> Signed. */
1124 if ((BIG_SINT_C_TYPE
) high
< 0)
1125 low
= max_low
; /* Maximum. */
1126 else if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
1127 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
1128 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1129 low
= max_low
; /* Maximum. */
1132 /* Step 4. Store the result. */
1133 z
= (TO_INT_C_TYPE
) low
;
1134 #if TO_HAVE_PADDING_BITS
1135 z
= z
<< TO_PADDING_BITS
;
1136 z
= z
>> TO_PADDING_BITS
;
1138 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1141 #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
1143 /* Fixed -> Float. */
1144 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3
1146 FRACT (FROM_FIXED_C_TYPE a
)
1150 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
1151 z
= (TO_FLOAT_C_TYPE
) x
;
1155 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3 */
1157 /* Float -> Fixed. */
1158 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4
1160 FRACT (FROM_FLOAT_C_TYPE a
)
1162 FROM_FLOAT_C_TYPE temp
;
1167 z
= (TO_INT_C_TYPE
) temp
;
1168 #if TO_HAVE_PADDING_BITS
1169 z
= z
<< TO_PADDING_BITS
;
1170 z
= z
>> TO_PADDING_BITS
;
1172 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1175 #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */
1177 /* Float -> Fixed with saturation. */
1178 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4
1180 SATFRACT (FROM_FLOAT_C_TYPE a
)
1182 FROM_FLOAT_C_TYPE temp
;
1188 #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1189 z
= (TO_INT_C_TYPE
)1 << TO_I_F_BITS
;
1195 else if (a
<= FIXED_MIN
)
1197 #if TO_MODE_UNSIGNED == 0
1198 z
= (TO_INT_C_TYPE
)1 << TO_I_F_BITS
;
1206 z
= (TO_INT_C_TYPE
) temp
;
1209 #if TO_HAVE_PADDING_BITS
1210 z
= z
<< TO_PADDING_BITS
;
1211 z
= z
>> TO_PADDING_BITS
;
1213 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1216 #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */