1 /* This is a software fixed-point library.
2 Copyright (C) 2007-2018 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
);
83 z
= x
+ (UINT_C_TYPE
) y
;
84 if ((((x
^ y
) >> I_F_BITS
) & 1) == 0)
86 if (((z
^ x
) >> I_F_BITS
) & 1)
88 z
= ((UINT_C_TYPE
) 1) << I_F_BITS
;
94 z
= z
<< PADDING_BITS
;
95 z
= z
>> PADDING_BITS
;
97 memcpy (&c
, &z
, FIXED_SIZE
);
100 #endif /* FIXED_SSADD */
102 #if defined(FIXED_USADD) && defined(L_usadd)
104 FIXED_USADD (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
108 memcpy (&x
, &a
, FIXED_SIZE
);
109 memcpy (&y
, &b
, FIXED_SIZE
);
111 #if HAVE_PADDING_BITS
112 z
= z
<< PADDING_BITS
;
113 z
= z
>> PADDING_BITS
;
115 if (z
< x
|| z
< y
) /* max */
118 #if HAVE_PADDING_BITS
119 z
= z
<< PADDING_BITS
;
120 z
= z
>> PADDING_BITS
;
123 memcpy (&c
, &z
, FIXED_SIZE
);
126 #endif /* FIXED_USADD */
128 #if defined(FIXED_SUB) && defined(L_sub)
130 FIXED_SUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
134 memcpy (&x
, &a
, FIXED_SIZE
);
135 memcpy (&y
, &b
, FIXED_SIZE
);
137 #if HAVE_PADDING_BITS
138 z
= z
<< PADDING_BITS
;
139 z
= z
>> PADDING_BITS
;
141 memcpy (&c
, &z
, FIXED_SIZE
);
144 #endif /* FIXED_SUB */
146 #if defined(FIXED_SSSUB) && defined(L_sssub)
148 FIXED_SSSUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
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)
157 if (((z
^ x
) >> I_F_BITS
) & 1)
159 z
= ((UINT_C_TYPE
) 1) << I_F_BITS
;
161 z
-= (UINT_C_TYPE
) 1;
164 #if HAVE_PADDING_BITS
165 z
= z
<< PADDING_BITS
;
166 z
= z
>> PADDING_BITS
;
168 memcpy (&c
, &z
, FIXED_SIZE
);
171 #endif /* FIXED_SSSUB */
173 #if defined(FIXED_USSUB) && defined(L_ussub)
175 FIXED_USSUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
179 memcpy (&x
, &a
, FIXED_SIZE
);
180 memcpy (&y
, &b
, FIXED_SIZE
);
184 #if HAVE_PADDING_BITS
185 z
= z
<< PADDING_BITS
;
186 z
= z
>> PADDING_BITS
;
188 memcpy (&c
, &z
, FIXED_SIZE
);
191 #endif /* FIXED_USSUB */
193 #if defined(FIXED_SATURATE1) && defined(L_saturate1)
195 FIXED_SATURATE1 (DINT_C_TYPE
*a
)
197 DINT_C_TYPE max
, min
;
198 max
= (DINT_C_TYPE
)1 << I_F_BITS
;
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
);
211 #endif /* FIXED_SATURATE1 */
213 #if defined(FIXED_SATURATE2) && defined(L_saturate2)
215 FIXED_SATURATE2 (INT_C_TYPE
*high
, INT_C_TYPE
*low
)
217 INT_C_TYPE r_max
, s_max
, r_min
, s_min
;
219 #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS
220 s_max
= (INT_C_TYPE
)1 << I_F_BITS
;
225 #if MODE_UNSIGNED == 0
227 s_min
= (INT_C_TYPE
)1 << (FIXED_WIDTH
- 1);
228 s_min
= s_min
>> (FIXED_WIDTH
- 1 - I_F_BITS
);
235 || (*high
== r_max
&& (UINT_C_TYPE
)(*low
) > (UINT_C_TYPE
)s_max
))
240 else if (*high
< r_min
||
241 (*high
== r_min
&& (UINT_C_TYPE
)(*low
) < (UINT_C_TYPE
)s_min
))
247 #endif /* FIXED_SATURATE2 */
249 #if defined(FIXED_MULHELPER) && defined(L_mulhelper)
251 FIXED_MULHELPER (FIXED_C_TYPE a
, FIXED_C_TYPE b
, word_type satp
)
256 #if defined (DINT_C_TYPE)
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
;
264 /* Round the result by adding (1 << (FBITS -1)). */
265 dz
+= ((DINT_C_TYPE
) 1 << (FBITS
- 1));
268 FIXED_SATURATE1 (&dz
);
271 #if HAVE_PADDING_BITS
272 z
= z
<< PADDING_BITS
;
273 z
= z
>> PADDING_BITS
;
275 memcpy (&c
, &z
, FIXED_SIZE
);
278 #else /* No DINT_C_TYPE */
279 /* The result of multiplication expands to two INT_C_TYPE. */
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;
287 memcpy (&x
, &a
, FIXED_SIZE
);
288 memcpy (&y
, &b
, FIXED_SIZE
);
290 /* Decompose a and b. */
294 a_high
.s
.low
= aa
.s
.high
;
296 a_low
.s
.low
= aa
.s
.low
;
298 b_high
.s
.low
= bb
.s
.high
;
300 b_low
.s
.low
= bb
.s
.low
;
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
;
309 /* Accumulate four results to {r, s}. */
310 temp1
.s
.high
= high_low
.s
.low
;
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. */
317 temp2
.s
.high
= low_high
.s
.low
;
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. */
324 temp1
.s
.low
= high_low
.s
.high
;
326 r
.ll
= high_high
.ll
+ temp1
.ll
;
327 temp1
.s
.low
= low_high
.s
.high
;
329 r
.ll
= r
.ll
+ temp1
.ll
+ carry
;
331 #if MODE_UNSIGNED == 0
332 /* For signed types, we need to add neg(y) to r, if x < 0. */
335 /* We need to add neg(x) to r, if y < 0. */
340 /* Round the result by adding (1 << (FBITS -1)). */
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)))
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. */
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
;
361 FIXED_SATURATE2 (&r
.ll
, &s
.ll
);
363 z
= (INT_C_TYPE
) s
.ll
;
364 #if HAVE_PADDING_BITS
365 z
= z
<< PADDING_BITS
;
366 z
= z
>> PADDING_BITS
;
368 memcpy (&c
, &z
, FIXED_SIZE
);
372 #endif /* FIXED_MULHELPER */
374 #if defined(FIXED_MUL) && defined(L_mul)
376 FIXED_MUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
378 return FIXED_MULHELPER (a
, b
, 0);
380 #endif /* FIXED_MUL */
382 #if defined(FIXED_SSMUL) && defined(L_ssmul)
384 FIXED_SSMUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
386 return FIXED_MULHELPER (a
, b
, 1);
388 #endif /* FIXED_SSMUL */
390 #if defined(FIXED_USMUL) && defined(L_usmul)
392 FIXED_USMUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
394 return FIXED_MULHELPER (a
, b
, 1);
396 #endif /* FIXED_USMUL */
398 #if defined(FIXED_DIVHELPER) && defined(L_divhelper)
400 FIXED_DIVHELPER (FIXED_C_TYPE a
, FIXED_C_TYPE b
, word_type satp
)
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
;
415 FIXED_SATURATE1 (&dz
);
417 #if HAVE_PADDING_BITS
418 z
= z
<< PADDING_BITS
;
419 z
= z
>> PADDING_BITS
;
421 memcpy (&c
, &z
, FIXED_SIZE
);
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
;
428 #if MODE_UNSIGNED == 0
429 word_type num_of_neg
= 0;
432 memcpy (&x
, &a
, FIXED_SIZE
);
433 memcpy (&y
, &b
, FIXED_SIZE
);
437 #if MODE_UNSIGNED == 0
438 /* If a < 0, negate a. */
444 /* If b < 0, negate b. */
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. */
459 r
= pos_a
>> (FIXED_WIDTH
- FBITS
);
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
;
467 for (i
= 0; i
< FIXED_WIDTH
; i
++)
469 /* Record the leftmost bit of mod. */
470 word_type leftmost_mode
= (mod
>> (FIXED_WIDTH
- 1)) & 1;
471 /* Shift left mod by 1 bit. */
473 /* Test the leftmost bit of s to add to mod. */
474 if ((s
>> (FIXED_WIDTH
- 1)) & 1)
476 /* Shift left quo_s by 1 bit. */
478 /* Try to calculate (mod - pos_b). */
480 if (leftmost_mode
|| (UINT_C_TYPE
)mod
>= (UINT_C_TYPE
)pos_b
)
485 /* Shift left s by 1 bit. */
489 #if MODE_UNSIGNED == 0
500 FIXED_SATURATE2 (&quo_r
, &quo_s
);
502 #if HAVE_PADDING_BITS
503 z
= z
<< PADDING_BITS
;
504 z
= z
>> PADDING_BITS
;
506 memcpy (&c
, &z
, FIXED_SIZE
);
510 #endif /* FIXED_DIVHELPER */
512 #if defined(FIXED_DIV) && defined(L_div)
514 FIXED_DIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
516 return FIXED_DIVHELPER (a
, b
, 0);
518 #endif /* FIXED_DIV */
521 #if defined(FIXED_UDIV) && defined(L_udiv)
523 FIXED_UDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
525 return FIXED_DIVHELPER (a
, b
, 0);
527 #endif /* FIXED_UDIV */
529 #if defined(FIXED_SSDIV) && defined(L_ssdiv)
531 FIXED_SSDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
533 return FIXED_DIVHELPER (a
, b
, 1);
535 #endif /* FIXED_SSDIV */
537 #if defined(FIXED_USDIV) && defined(L_usdiv)
539 FIXED_USDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
541 return FIXED_DIVHELPER (a
, b
, 1);
543 #endif /* FIXED_USDIV */
545 #if defined(FIXED_NEG) && defined(L_neg)
547 FIXED_NEG (FIXED_C_TYPE a
)
551 memcpy (&x
, &a
, FIXED_SIZE
);
553 #if HAVE_PADDING_BITS
554 z
= z
<< PADDING_BITS
;
555 z
= z
>> PADDING_BITS
;
557 memcpy (&c
, &z
, FIXED_SIZE
);
560 #endif /* FIXED_NEG */
562 #if defined(FIXED_SSNEG) && defined(L_ssneg)
564 FIXED_SSNEG (FIXED_C_TYPE a
)
568 memcpy (&y
, &a
, FIXED_SIZE
);
570 z
= x
- (UINT_C_TYPE
) y
;
571 if (((x
^ y
) >> I_F_BITS
) & 1)
573 if (((z
^ x
) >> I_F_BITS
) & 1)
574 z
= (((UINT_C_TYPE
) 1) << I_F_BITS
) - 1;
576 #if HAVE_PADDING_BITS
577 z
= z
<< PADDING_BITS
;
578 z
= z
>> PADDING_BITS
;
580 memcpy (&c
, &z
, FIXED_SIZE
);
583 #endif /* FIXED_SSNEG */
585 #if defined(FIXED_USNEG) && defined(L_usneg)
587 FIXED_USNEG (FIXED_C_TYPE a
__attribute__ ((__unused__
)))
592 memcpy (&c
, &z
, FIXED_SIZE
);
595 #endif /* FIXED_USNEG */
597 #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper)
599 FIXED_ASHLHELPER (FIXED_C_TYPE a
, word_type b
, word_type satp
)
604 #if defined (DINT_C_TYPE)
606 memcpy (&x
, &a
, FIXED_SIZE
);
607 dx
= (DINT_C_TYPE
) x
;
608 if (b
>= FIXED_WIDTH
)
609 dz
= dx
<< FIXED_WIDTH
;
613 FIXED_SATURATE1 (&dz
);
615 #if HAVE_PADDING_BITS
616 z
= z
<< PADDING_BITS
;
617 z
= z
>> PADDING_BITS
;
619 memcpy (&c
, &z
, FIXED_SIZE
);
622 #else /* No DINT_C_TYPE */
624 memcpy (&x
, &a
, FIXED_SIZE
);
625 /* We need to shift left x by b bits to {r, s}. */
626 if (b
>= FIXED_WIDTH
)
634 r
= x
>> (FIXED_WIDTH
- b
);
637 FIXED_SATURATE2 (&r
, &s
);
639 #if HAVE_PADDING_BITS
640 z
= z
<< PADDING_BITS
;
641 z
= z
>> PADDING_BITS
;
643 memcpy (&c
, &z
, FIXED_SIZE
);
647 #endif /* FIXED_ASHLHELPER */
649 #if defined(FIXED_ASHL) && defined(L_ashl)
651 FIXED_ASHL (FIXED_C_TYPE a
, word_type b
)
653 return FIXED_ASHLHELPER (a
, b
, 0);
655 #endif /* FIXED_ASHL */
657 #if defined(FIXED_ASHR) && defined(L_ashr)
659 FIXED_ASHR (FIXED_C_TYPE a
, word_type b
)
663 memcpy (&x
, &a
, FIXED_SIZE
);
665 #if HAVE_PADDING_BITS
666 z
= z
<< PADDING_BITS
;
667 z
= z
>> PADDING_BITS
;
669 memcpy (&c
, &z
, FIXED_SIZE
);
672 #endif /* FIXED_ASHR */
674 #if defined(FIXED_LSHR) && defined(L_lshr)
676 FIXED_LSHR (FIXED_C_TYPE a
, word_type b
)
680 memcpy (&x
, &a
, FIXED_SIZE
);
682 #if HAVE_PADDING_BITS
683 z
= z
<< PADDING_BITS
;
684 z
= z
>> PADDING_BITS
;
686 memcpy (&c
, &z
, FIXED_SIZE
);
689 #endif /* FIXED_LSHR */
691 #if defined(FIXED_SSASHL) && defined(L_ssashl)
693 FIXED_SSASHL (FIXED_C_TYPE a
, word_type b
)
695 return FIXED_ASHLHELPER (a
, b
, 1);
697 #endif /* FIXED_SSASHL */
699 #if defined(FIXED_USASHL) && defined(L_usashl)
701 FIXED_USASHL (FIXED_C_TYPE a
, word_type b
)
703 return FIXED_ASHLHELPER (a
, b
, 1);
705 #endif /* FIXED_USASHL */
707 #if defined(FIXED_CMP) && defined(L_cmp)
709 FIXED_CMP (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
712 memcpy (&x
, &a
, FIXED_SIZE
);
713 memcpy (&y
, &b
, FIXED_SIZE
);
722 #endif /* FIXED_CMP */
724 /* Fixed -> Fixed. */
725 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4
727 FRACT (FROM_FIXED_C_TYPE a
)
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 */
744 #if TO_HAVE_PADDING_BITS
745 z
= z
<< TO_PADDING_BITS
;
746 z
= z
>> TO_PADDING_BITS
;
748 memcpy (&c
, &z
, TO_FIXED_SIZE
);
751 #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4 */
753 /* Fixed -> Fixed with saturation. */
754 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4
756 SATFRACT (FROM_FIXED_C_TYPE a
)
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
;
768 BIG_UINT_C_TYPE high
, low
;
769 BIG_UINT_C_TYPE max_high
, max_low
;
771 #if TO_FBITS > FROM_FBITS
772 BIG_UINT_C_TYPE utemp
;
774 #if TO_MODE_UNSIGNED == 0
775 BIG_SINT_C_TYPE stemp
;
777 #if TO_FBITS != FROM_FBITS
780 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
782 /* Step 1. We need to store x to {high, low}. */
783 #if FROM_MODE_UNSIGNED == 0
784 low
= (BIG_SINT_C_TYPE
) x
;
790 low
= (BIG_UINT_C_TYPE
) x
;
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
;
806 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
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;
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
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. */
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. */
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
;
864 memcpy (&c
, &z
, TO_FIXED_SIZE
);
867 #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4 */
870 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1
872 FRACT (FROM_FIXED_C_TYPE a
)
876 FROM_INT_C_TYPE i
= 0;
877 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
879 #if FROM_MODE_UNSIGNED == 0
882 #if FROM_FIXED_WIDTH == FROM_FBITS
886 if (((FROM_INT_C_TYPE
)(x
<< (FROM_FIXED_WIDTH
- FROM_FBITS
))) != 0)
892 #if FROM_FIXED_WIDTH == FROM_FBITS
898 z
= (TO_INT_C_TYPE
) x
;
901 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1 */
903 /* Fixed -> Unsigned int. */
904 #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2
906 FRACTUNS (FROM_FIXED_C_TYPE a
)
910 FROM_INT_C_TYPE i
= 0;
911 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
913 #if FROM_MODE_UNSIGNED == 0
916 #if FROM_FIXED_WIDTH == FROM_FBITS
920 if (((FROM_INT_C_TYPE
)(x
<< (FROM_FIXED_WIDTH
- FROM_FBITS
))) != 0)
926 #if FROM_FIXED_WIDTH == FROM_FBITS
932 z
= (TO_INT_C_TYPE
) x
;
935 #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2 */
938 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4
940 FRACT (FROM_INT_C_TYPE a
)
944 z
= (TO_INT_C_TYPE
) a
;
945 #if TO_FIXED_WIDTH == TO_FBITS
950 #if TO_HAVE_PADDING_BITS
951 z
= z
<< TO_PADDING_BITS
;
952 z
= z
>> TO_PADDING_BITS
;
954 memcpy (&c
, &z
, TO_FIXED_SIZE
);
957 #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
959 /* Signed int -> Fixed with saturation. */
960 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 1 && TO_TYPE == 4
962 SATFRACT (FROM_INT_C_TYPE a
)
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
;
973 #if BIG_WIDTH != TO_FBITS
974 BIG_UINT_C_TYPE utemp
;
978 /* Step 1. We need to store x to {high, low}. */
979 low
= (BIG_SINT_C_TYPE
) x
;
985 /* Step 2. We need to left shift {high, low}. */
986 #if BIG_WIDTH == TO_FBITS
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
;
997 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
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;
1006 #if TO_MODE_UNSIGNED == 0
1008 stemp
= (BIG_SINT_C_TYPE
)1 << (BIG_WIDTH
- 1);
1009 stemp
= stemp
>> (BIG_WIDTH
- 1 - TO_I_F_BITS
);
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. */
1022 /* Signed -> Unsigned. */
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. */
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
;
1037 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1040 #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
1042 /* Unsigned int -> Fixed. */
1043 #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4
1045 FRACTUNS (FROM_INT_C_TYPE a
)
1049 z
= (TO_INT_C_TYPE
) a
;
1050 #if TO_FIXED_WIDTH == TO_FBITS
1055 #if TO_HAVE_PADDING_BITS
1056 z
= z
<< TO_PADDING_BITS
;
1057 z
= z
>> TO_PADDING_BITS
;
1059 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1062 #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
1064 /* Unsigned int -> Fixed with saturation. */
1065 #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4
1067 SATFRACTUNS (FROM_INT_C_TYPE a
)
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
;
1079 /* Step 1. We need to store x to {high, low}. */
1080 low
= (BIG_UINT_C_TYPE
) x
;
1083 /* Step 2. We need to left shift {high, low}. */
1084 #if BIG_WIDTH == TO_FBITS
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
;
1095 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
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;
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. */
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. */
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
;
1126 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1129 #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
1131 /* Fixed -> Float. */
1132 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3
1134 FRACT (FROM_FIXED_C_TYPE a
)
1138 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
1139 z
= (TO_FLOAT_C_TYPE
) x
;
1143 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3 */
1145 /* Float -> Fixed. */
1146 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4
1148 FRACT (FROM_FLOAT_C_TYPE a
)
1150 FROM_FLOAT_C_TYPE temp
;
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
;
1160 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1163 #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */
1165 /* Float -> Fixed with saturation. */
1166 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4
1168 SATFRACT (FROM_FLOAT_C_TYPE a
)
1170 FROM_FLOAT_C_TYPE temp
;
1176 #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1177 z
= (TO_INT_C_TYPE
)1 << TO_I_F_BITS
;
1183 else if (a
<= FIXED_MIN
)
1185 #if TO_MODE_UNSIGNED == 0
1186 z
= (TO_INT_C_TYPE
)1 << TO_I_F_BITS
;
1194 z
= (TO_INT_C_TYPE
) temp
;
1197 #if TO_HAVE_PADDING_BITS
1198 z
= z
<< TO_PADDING_BITS
;
1199 z
= z
>> TO_PADDING_BITS
;
1201 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1204 #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */