1 /* This is a software fixed-point library.
2 Copyright (C) 2007 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 2, or (at your option) any later
11 In addition to the permissions in the GNU General Public License, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of this file into combinations with other programs,
14 and to distribute those combinations without any restriction coming
15 from the use of this file. (The General Public License restrictions
16 do apply in other respects; for example, they cover modification of
17 the file, and distribution when not linked into a combine
20 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
21 WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 You should have received a copy of the GNU General Public License
26 along with GCC; see the file COPYING. If not, write to the Free
27 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
30 /* This implements fixed-point arithmetic.
32 Contributed by Chao-ying Fu <fu@mips.com>. */
34 /* To use this file, we need to define one of the following:
35 QQ_MODE, UQQ_MODE, HQ_MODE, UHQ_MODE, SQ_MODE, USQ_MODE, DQ_MODE, UDQ_MODE,
36 TQ_MODE, UTQ_MODE, HA_MODE, UHA_MODE, SA_MODE, USA_MODE, DA_MODE, UDA_MODE,
38 Then, all operators for this machine mode will be created.
40 Or, we need to define FROM_* TO_* for conversions from one mode to another
41 mode. The mode could be one of the following:
42 Fract: QQ, UQQ, HQ, UHQ, SQ, USQ, DQ, UDQ, TQ, UTQ
43 Accum: HA, UHA, SA, USA, DA, UDA, TA, UTA
44 Signed integer: QI, HI, SI, DI, TI
45 Unsigned integer: UQI, UHI, USI, UDI, UTI
46 Floating-point: SF, DF
47 Ex: If we define FROM_QQ and TO_SI, the conversion from QQ to SI is
52 #include "coretypes.h"
55 #ifndef MIN_UNITS_PER_WORD
56 #define MIN_UNITS_PER_WORD UNITS_PER_WORD
59 #include "config/fixed-bit.h"
61 #if defined(FIXED_ADD) && defined(L_add)
63 FIXED_ADD (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
67 memcpy (&x
, &a
, FIXED_SIZE
);
68 memcpy (&y
, &b
, FIXED_SIZE
);
71 z
= z
<< PADDING_BITS
;
72 z
= z
>> PADDING_BITS
;
74 memcpy (&c
, &z
, FIXED_SIZE
);
77 #endif /* FIXED_ADD */
79 #if defined(FIXED_SSADD) && defined(L_ssadd)
81 FIXED_SSADD (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
85 memcpy (&x
, &a
, FIXED_SIZE
);
86 memcpy (&y
, &b
, FIXED_SIZE
);
88 if ((((x
^ y
) >> I_F_BITS
) & 1) == 0)
90 if (((z
^ x
) >> I_F_BITS
) & 1)
99 z
= z
<< PADDING_BITS
;
100 z
= z
>> PADDING_BITS
;
102 memcpy (&c
, &z
, FIXED_SIZE
);
105 #endif /* FIXED_SSADD */
107 #if defined(FIXED_USADD) && defined(L_usadd)
109 FIXED_USADD (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
113 memcpy (&x
, &a
, FIXED_SIZE
);
114 memcpy (&y
, &b
, FIXED_SIZE
);
116 #if HAVE_PADDING_BITS
117 z
= z
<< PADDING_BITS
;
118 z
= z
>> PADDING_BITS
;
120 if (z
< x
|| z
< y
) /* max */
123 #if HAVE_PADDING_BITS
124 z
= z
<< PADDING_BITS
;
125 z
= z
>> PADDING_BITS
;
128 memcpy (&c
, &z
, FIXED_SIZE
);
131 #endif /* FIXED_USADD */
133 #if defined(FIXED_SUB) && defined(L_sub)
135 FIXED_SUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
139 memcpy (&x
, &a
, FIXED_SIZE
);
140 memcpy (&y
, &b
, FIXED_SIZE
);
142 #if HAVE_PADDING_BITS
143 z
= z
<< PADDING_BITS
;
144 z
= z
>> PADDING_BITS
;
146 memcpy (&c
, &z
, FIXED_SIZE
);
149 #endif /* FIXED_SUB */
151 #if defined(FIXED_SSSUB) && defined(L_sssub)
153 FIXED_SSSUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
157 memcpy (&x
, &a
, FIXED_SIZE
);
158 memcpy (&y
, &b
, FIXED_SIZE
);
160 if (((x
^ y
) >> I_F_BITS
) & 1)
162 if (((z
^ x
) >> I_F_BITS
) & 1)
170 #if HAVE_PADDING_BITS
171 z
= z
<< PADDING_BITS
;
172 z
= z
>> PADDING_BITS
;
174 memcpy (&c
, &z
, FIXED_SIZE
);
177 #endif /* FIXED_SSSUB */
179 #if defined(FIXED_USSUB) && defined(L_ussub)
181 FIXED_USSUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
185 memcpy (&x
, &a
, FIXED_SIZE
);
186 memcpy (&y
, &b
, FIXED_SIZE
);
190 #if HAVE_PADDING_BITS
191 z
= z
<< PADDING_BITS
;
192 z
= z
>> PADDING_BITS
;
194 memcpy (&c
, &z
, FIXED_SIZE
);
197 #endif /* FIXED_USSUB */
199 #if defined(FIXED_SATURATE1) && defined(L_saturate1)
201 FIXED_SATURATE1 (DINT_C_TYPE
*a
)
203 DINT_C_TYPE max
, min
;
204 max
= (DINT_C_TYPE
)1 << I_F_BITS
;
206 #if MODE_UNSIGNED == 0
207 min
= (DINT_C_TYPE
)1 << (2 * FIXED_WIDTH
- 1);
208 min
= min
>> (2 * FIXED_WIDTH
- 1 - I_F_BITS
);
217 #endif /* FIXED_SATURATE1 */
219 #if defined(FIXED_SATURATE2) && defined(L_saturate2)
221 FIXED_SATURATE2 (INT_C_TYPE
*high
, INT_C_TYPE
*low
)
223 INT_C_TYPE r_max
, s_max
, r_min
, s_min
;
225 #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS
226 s_max
= (INT_C_TYPE
)1 << I_F_BITS
;
231 #if MODE_UNSIGNED == 0
233 s_min
= (INT_C_TYPE
)1 << (FIXED_WIDTH
- 1);
234 s_min
= s_min
>> (FIXED_WIDTH
- 1 - I_F_BITS
);
241 || (*high
== r_max
&& (UINT_C_TYPE
)(*low
) > (UINT_C_TYPE
)s_max
))
246 else if (*high
< r_min
||
247 (*high
== r_min
&& (UINT_C_TYPE
)(*low
) < (UINT_C_TYPE
)s_min
))
253 #endif /* FIXED_SATURATE2 */
255 #if defined(FIXED_MULHELPER) && defined(L_mulhelper)
257 FIXED_MULHELPER (FIXED_C_TYPE a
, FIXED_C_TYPE b
, word_type satp
)
262 #if defined (DINT_C_TYPE)
264 DINT_C_TYPE dx
, dy
, dz
;
265 memcpy (&x
, &a
, FIXED_SIZE
);
266 memcpy (&y
, &b
, FIXED_SIZE
);
267 dx
= (DINT_C_TYPE
) x
;
268 dy
= (DINT_C_TYPE
) y
;
270 /* Round the result by adding (1 << (FBITS -1)). */
271 dz
+= ((DINT_C_TYPE
) 1 << (FBITS
- 1));
274 FIXED_SATURATE1 (&dz
);
277 #if HAVE_PADDING_BITS
278 z
= z
<< PADDING_BITS
;
279 z
= z
>> PADDING_BITS
;
281 memcpy (&c
, &z
, FIXED_SIZE
);
284 #else /* No DINT_C_TYPE */
285 /* The result of multiplication expands to two INT_C_TYPE. */
287 INTunion a_high
, a_low
, b_high
, b_low
;
288 INTunion high_high
, high_low
, low_high
, low_low
;
289 INTunion r
, s
, temp1
, temp2
;
290 INT_C_TYPE carry
= 0;
293 memcpy (&x
, &a
, FIXED_SIZE
);
294 memcpy (&y
, &b
, FIXED_SIZE
);
296 /* Decompose a and b. */
300 a_high
.s
.low
= aa
.s
.high
;
302 a_low
.s
.low
= aa
.s
.low
;
304 b_high
.s
.low
= bb
.s
.high
;
306 b_low
.s
.low
= bb
.s
.low
;
309 /* Perform four multiplications. */
310 low_low
.ll
= a_low
.ll
* b_low
.ll
;
311 low_high
.ll
= a_low
.ll
* b_high
.ll
;
312 high_low
.ll
= a_high
.ll
* b_low
.ll
;
313 high_high
.ll
= a_high
.ll
* b_high
.ll
;
315 /* Accumulate four results to {r, s}. */
316 temp1
.s
.high
= high_low
.s
.low
;
318 s
.ll
= low_low
.ll
+ temp1
.ll
;
319 if ((UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) low_low
.ll
320 || (UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp1
.ll
)
321 carry
++; /* Carry. */
323 temp2
.s
.high
= low_high
.s
.low
;
325 s
.ll
= temp1
.ll
+ temp2
.ll
;
326 if ((UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp1
.ll
327 || (UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp2
.ll
)
328 carry
++; /* Carry. */
330 temp1
.s
.low
= high_low
.s
.high
;
332 r
.ll
= high_high
.ll
+ temp1
.ll
;
333 temp1
.s
.low
= low_high
.s
.high
;
335 r
.ll
= r
.ll
+ temp1
.ll
+ carry
;
337 #if MODE_UNSIGNED == 0
338 /* For signed types, we need to add neg(y) to r, if x < 0. */
341 /* We need to add neg(x) to r, if y < 0. */
346 /* Round the result by adding (1 << (FBITS -1)). */
348 s
.ll
+= ((INT_C_TYPE
) 1 << (FBITS
-1));
349 if ((UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp1
.ll
350 || (UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) ((INT_C_TYPE
) 1 << (FBITS
-1)))
353 /* Shift right the result by FBITS. */
354 #if FBITS == FIXED_WIDTH
355 /* This happens only for unsigned types without any padding bits.
356 So, it is safe to set r.ll to 0 as it is logically shifted right. */
360 s
.ll
= ((UINT_C_TYPE
)s
.ll
) >> FBITS
;
361 temp1
.ll
= r
.ll
<< (FIXED_WIDTH
- FBITS
);
362 s
.ll
= s
.ll
| temp1
.ll
;
363 r
.ll
= r
.ll
>> FBITS
;
367 FIXED_SATURATE2 (&r
.ll
, &s
.ll
);
369 z
= (INT_C_TYPE
) s
.ll
;
370 #if HAVE_PADDING_BITS
371 z
= z
<< PADDING_BITS
;
372 z
= z
>> PADDING_BITS
;
374 memcpy (&c
, &z
, FIXED_SIZE
);
378 #endif /* FIXED_MULHELPER */
380 #if defined(FIXED_MUL) && defined(L_mul)
382 FIXED_MUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
384 return FIXED_MULHELPER (a
, b
, 0);
386 #endif /* FIXED_MUL */
388 #if defined(FIXED_SSMUL) && defined(L_ssmul)
390 FIXED_SSMUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
392 return FIXED_MULHELPER (a
, b
, 1);
394 #endif /* FIXED_SSMUL */
396 #if defined(FIXED_USMUL) && defined(L_usmul)
398 FIXED_USMUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
400 return FIXED_MULHELPER (a
, b
, 1);
402 #endif /* FIXED_USMUL */
404 #if defined(FIXED_DIVHELPER) && defined(L_divhelper)
406 FIXED_DIVHELPER (FIXED_C_TYPE a
, FIXED_C_TYPE b
, word_type satp
)
412 #if defined (DINT_C_TYPE)
413 DINT_C_TYPE dx
, dy
, dz
;
414 memcpy (&x
, &a
, FIXED_SIZE
);
415 memcpy (&y
, &b
, FIXED_SIZE
);
416 dx
= (DINT_C_TYPE
) x
;
417 dy
= (DINT_C_TYPE
) y
;
421 FIXED_SATURATE1 (&dz
);
423 #if HAVE_PADDING_BITS
424 z
= z
<< PADDING_BITS
;
425 z
= z
>> PADDING_BITS
;
427 memcpy (&c
, &z
, FIXED_SIZE
);
430 #else /* No DINT_C_TYPE */
431 INT_C_TYPE pos_a
, pos_b
, r
, s
;
432 INT_C_TYPE quo_r
, quo_s
, mod
, temp
;
434 #if MODE_UNSIGNED == 0
435 word_type num_of_neg
= 0;
438 memcpy (&x
, &a
, FIXED_SIZE
);
439 memcpy (&y
, &b
, FIXED_SIZE
);
443 #if MODE_UNSIGNED == 0
444 /* If a < 0, negate a. */
450 /* If b < 0, negate b. */
458 /* Left shift pos_a to {r, s} by FBITS. */
459 #if FBITS == FIXED_WIDTH
460 /* This happens only for unsigned types without any padding bits. */
465 r
= pos_a
>> (FIXED_WIDTH
- FBITS
);
468 /* Unsigned divide r by pos_b to quo_r. The remainder is in mod. */
469 quo_r
= (UINT_C_TYPE
)r
/ (UINT_C_TYPE
)pos_b
;
470 mod
= (UINT_C_TYPE
)r
% (UINT_C_TYPE
)pos_b
;
473 for (i
= 0; i
< FIXED_WIDTH
; i
++)
475 /* Record the leftmost bit of mod. */
476 word_type leftmost_mode
= (mod
>> (FIXED_WIDTH
- 1)) & 1;
477 /* Shift left mod by 1 bit. */
479 /* Test the leftmost bit of s to add to mod. */
480 if ((s
>> (FIXED_WIDTH
- 1)) & 1)
482 /* Shift left quo_s by 1 bit. */
484 /* Try to calculate (mod - pos_b). */
486 if (leftmost_mode
|| (UINT_C_TYPE
)mod
>= (UINT_C_TYPE
)pos_b
)
491 /* Shift left s by 1 bit. */
495 #if MODE_UNSIGNED == 0
506 FIXED_SATURATE2 (&quo_r
, &quo_s
);
508 #if HAVE_PADDING_BITS
509 z
= z
<< PADDING_BITS
;
510 z
= z
>> PADDING_BITS
;
512 memcpy (&c
, &z
, FIXED_SIZE
);
516 #endif /* FIXED_DIVHELPER */
518 #if defined(FIXED_DIV) && defined(L_div)
520 FIXED_DIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
522 return FIXED_DIVHELPER (a
, b
, 0);
524 #endif /* FIXED_DIV */
527 #if defined(FIXED_UDIV) && defined(L_udiv)
529 FIXED_UDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
531 return FIXED_DIVHELPER (a
, b
, 0);
533 #endif /* FIXED_UDIV */
535 #if defined(FIXED_SSDIV) && defined(L_ssdiv)
537 FIXED_SSDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
539 return FIXED_DIVHELPER (a
, b
, 1);
541 #endif /* FIXED_SSDIV */
543 #if defined(FIXED_USDIV) && defined(L_usdiv)
545 FIXED_USDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
547 return FIXED_DIVHELPER (a
, b
, 1);
549 #endif /* FIXED_USDIV */
551 #if defined(FIXED_NEG) && defined(L_neg)
553 FIXED_NEG (FIXED_C_TYPE a
)
557 memcpy (&x
, &a
, FIXED_SIZE
);
559 #if HAVE_PADDING_BITS
560 z
= z
<< PADDING_BITS
;
561 z
= z
>> PADDING_BITS
;
563 memcpy (&c
, &z
, FIXED_SIZE
);
566 #endif /* FIXED_NEG */
568 #if defined(FIXED_SSNEG) && defined(L_ssneg)
570 FIXED_SSNEG (FIXED_C_TYPE a
)
574 memcpy (&y
, &a
, FIXED_SIZE
);
577 if (((x
^ y
) >> I_F_BITS
) & 1)
579 if (((z
^ x
) >> I_F_BITS
) & 1)
587 #if HAVE_PADDING_BITS
588 z
= z
<< PADDING_BITS
;
589 z
= z
>> PADDING_BITS
;
591 memcpy (&c
, &z
, FIXED_SIZE
);
594 #endif /* FIXED_SSNEG */
596 #if defined(FIXED_USNEG) && defined(L_usneg)
598 FIXED_USNEG (FIXED_C_TYPE a
__attribute__ ((__unused__
)))
603 memcpy (&c
, &z
, FIXED_SIZE
);
606 #endif /* FIXED_USNEG */
608 #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper)
610 FIXED_ASHLHELPER (FIXED_C_TYPE a
, word_type b
, word_type satp
)
615 #if defined (DINT_C_TYPE)
617 memcpy (&x
, &a
, FIXED_SIZE
);
618 dx
= (DINT_C_TYPE
) x
;
619 if (b
>= FIXED_WIDTH
)
620 dz
= dx
<< FIXED_WIDTH
;
624 FIXED_SATURATE1 (&dz
);
626 #if HAVE_PADDING_BITS
627 z
= z
<< PADDING_BITS
;
628 z
= z
>> PADDING_BITS
;
630 memcpy (&c
, &z
, FIXED_SIZE
);
633 #else /* No DINT_C_TYPE */
635 memcpy (&x
, &a
, FIXED_SIZE
);
636 /* We need to shift left x by b bits to {r, s}. */
637 if (b
>= FIXED_WIDTH
)
645 r
= x
>> (FIXED_WIDTH
- b
);
648 FIXED_SATURATE2 (&r
, &s
);
650 #if HAVE_PADDING_BITS
651 z
= z
<< PADDING_BITS
;
652 z
= z
>> PADDING_BITS
;
654 memcpy (&c
, &z
, FIXED_SIZE
);
658 #endif /* FIXED_ASHLHELPER */
660 #if defined(FIXED_ASHL) && defined(L_ashl)
662 FIXED_ASHL (FIXED_C_TYPE a
, word_type b
)
664 return FIXED_ASHLHELPER (a
, b
, 0);
666 #endif /* FIXED_ASHL */
668 #if defined(FIXED_ASHR) && defined(L_ashr)
670 FIXED_ASHR (FIXED_C_TYPE a
, word_type b
)
674 memcpy (&x
, &a
, FIXED_SIZE
);
676 #if HAVE_PADDING_BITS
677 z
= z
<< PADDING_BITS
;
678 z
= z
>> PADDING_BITS
;
680 memcpy (&c
, &z
, FIXED_SIZE
);
683 #endif /* FIXED_ASHR */
685 #if defined(FIXED_LSHR) && defined(L_lshr)
687 FIXED_LSHR (FIXED_C_TYPE a
, word_type b
)
691 memcpy (&x
, &a
, FIXED_SIZE
);
693 #if HAVE_PADDING_BITS
694 z
= z
<< PADDING_BITS
;
695 z
= z
>> PADDING_BITS
;
697 memcpy (&c
, &z
, FIXED_SIZE
);
700 #endif /* FIXED_LSHR */
702 #if defined(FIXED_SSASHL) && defined(L_ssashl)
704 FIXED_SSASHL (FIXED_C_TYPE a
, word_type b
)
706 return FIXED_ASHLHELPER (a
, b
, 1);
708 #endif /* FIXED_SSASHL */
710 #if defined(FIXED_USASHL) && defined(L_usashl)
712 FIXED_USASHL (FIXED_C_TYPE a
, word_type b
)
714 return FIXED_ASHLHELPER (a
, b
, 1);
716 #endif /* FIXED_USASHL */
718 #if defined(FIXED_CMP) && defined(L_cmp)
720 FIXED_CMP (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
723 memcpy (&x
, &a
, FIXED_SIZE
);
724 memcpy (&y
, &b
, FIXED_SIZE
);
733 #endif /* FIXED_CMP */
735 /* Fixed -> Fixed. */
736 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4
738 FRACT (FROM_FIXED_C_TYPE a
)
744 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
745 #if TO_FBITS > FROM_FBITS /* Need left shift. */
746 shift_amount
= TO_FBITS
- FROM_FBITS
;
747 z
= (TO_INT_C_TYPE
) x
;
748 z
= z
<< shift_amount
;
749 #else /* TO_FBITS <= FROM_FBITS. Need right Shift. */
750 shift_amount
= FROM_FBITS
- TO_FBITS
;
751 x
= x
>> shift_amount
;
752 z
= (TO_INT_C_TYPE
) x
;
753 #endif /* TO_FBITS > FROM_FBITS */
755 #if TO_HAVE_PADDING_BITS
756 z
= z
<< TO_PADDING_BITS
;
757 z
= z
>> TO_PADDING_BITS
;
759 memcpy (&c
, &z
, TO_FIXED_SIZE
);
762 #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4 */
764 /* Fixed -> Fixed with saturation. */
765 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4
767 SATFRACT (FROM_FIXED_C_TYPE a
)
772 #if FROM_MODE_UNSIGNED == 0
773 BIG_SINT_C_TYPE high
, low
;
774 BIG_SINT_C_TYPE max_high
, max_low
;
775 BIG_SINT_C_TYPE min_high
, min_low
;
777 BIG_UINT_C_TYPE high
, low
;
778 BIG_UINT_C_TYPE max_high
, max_low
;
779 BIG_UINT_C_TYPE min_high
, min_low
;
781 #if TO_FBITS > FROM_FBITS
782 BIG_UINT_C_TYPE utemp
;
784 #if TO_MODE_UNSIGNED == 0
785 BIG_SINT_C_TYPE stemp
;
787 #if TO_FBITS != FROM_FBITS
790 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
792 /* Step 1. We need to store x to {high, low}. */
793 #if FROM_MODE_UNSIGNED == 0
794 low
= (BIG_SINT_C_TYPE
) x
;
800 low
= (BIG_UINT_C_TYPE
) x
;
804 /* Step 2. We need to shift {high, low}. */
805 #if TO_FBITS > FROM_FBITS /* Left shift. */
806 shift_amount
= TO_FBITS
- FROM_FBITS
;
807 utemp
= (BIG_UINT_C_TYPE
) low
;
808 utemp
= utemp
>> (BIG_WIDTH
- shift_amount
);
809 high
= ((BIG_UINT_C_TYPE
)(high
<< shift_amount
)) | utemp
;
810 low
= low
<< shift_amount
;
811 #elif TO_FBITS < FROM_FBITS /* Right shift. */
812 shift_amount
= FROM_FBITS
- TO_FBITS
;
813 low
= low
>> shift_amount
;
816 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
818 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
819 max_low
= (BIG_UINT_C_TYPE
)1 << TO_I_F_BITS
;
820 max_low
= max_low
- 1;
825 #if TO_MODE_UNSIGNED == 0
827 stemp
= (BIG_SINT_C_TYPE
)1 << (BIG_WIDTH
- 1);
828 stemp
= stemp
>> (BIG_WIDTH
- 1 - TO_I_F_BITS
);
835 #if FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 0
836 /* Signed -> Signed. */
837 if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
838 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
839 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
840 low
= max_low
; /* Maximum. */
841 else if ((BIG_SINT_C_TYPE
) high
< (BIG_SINT_C_TYPE
) min_high
842 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) min_high
843 && (BIG_UINT_C_TYPE
) low
< (BIG_UINT_C_TYPE
) min_low
))
844 low
= min_low
; /* Minimum. */
845 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 1
846 /* Unigned -> Unsigned. */
847 if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
848 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
849 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
850 low
= max_low
; /* Maximum. */
851 #elif FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 1
852 /* Signed -> Unsigned. */
854 low
= 0; /* Minimum. */
855 else if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
856 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
857 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
858 low
= max_low
; /* Maximum. */
859 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 0
860 /* Unsigned -> Signed. */
861 if ((BIG_SINT_C_TYPE
) high
< 0)
862 low
= max_low
; /* Maximum. */
863 else if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
864 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
865 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
866 low
= max_low
; /* Maximum. */
869 /* Step 4. Store the result. */
870 z
= (TO_INT_C_TYPE
) low
;
871 #if TO_HAVE_PADDING_BITS
872 z
= z
<< TO_PADDING_BITS
;
873 z
= z
>> TO_PADDING_BITS
;
875 memcpy (&c
, &z
, TO_FIXED_SIZE
);
878 #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4 */
881 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1
883 FRACT (FROM_FIXED_C_TYPE a
)
887 FROM_INT_C_TYPE i
= 0;
888 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
890 #if FROM_MODE_UNSIGNED == 0
893 #if FROM_FIXED_WIDTH == FROM_FBITS
897 if (((FROM_INT_C_TYPE
)(x
<< (FROM_FIXED_WIDTH
- FROM_FBITS
))) != 0)
903 #if FROM_FIXED_WIDTH == FROM_FBITS
909 z
= (TO_INT_C_TYPE
) x
;
912 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1 */
914 /* Fixed -> Unsigned int. */
915 #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2
917 FRACTUNS (FROM_FIXED_C_TYPE a
)
921 FROM_INT_C_TYPE i
= 0;
922 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
924 #if FROM_MODE_UNSIGNED == 0
927 #if FROM_FIXED_WIDTH == FROM_FBITS
931 if (((FROM_INT_C_TYPE
)(x
<< (FROM_FIXED_WIDTH
- FROM_FBITS
))) != 0)
937 #if FROM_FIXED_WIDTH == FROM_FBITS
943 z
= (TO_INT_C_TYPE
) x
;
946 #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2 */
949 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4
951 FRACT (FROM_INT_C_TYPE a
)
955 z
= (TO_INT_C_TYPE
) a
;
956 #if TO_FIXED_WIDTH == TO_FBITS
961 #if TO_HAVE_PADDING_BITS
962 z
= z
<< TO_PADDING_BITS
;
963 z
= z
>> TO_PADDING_BITS
;
965 memcpy (&c
, &z
, TO_FIXED_SIZE
);
968 #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
970 /* Signed int -> Fixed with saturation. */
971 #if defined(SATFRACT) && defined(L_satfract) &&FROM_TYPE == 1 && TO_TYPE == 4
973 SATFRACT (FROM_INT_C_TYPE a
)
977 FROM_INT_C_TYPE x
= a
;
978 BIG_SINT_C_TYPE high
, low
;
979 BIG_SINT_C_TYPE max_high
, max_low
;
980 BIG_SINT_C_TYPE min_high
, min_low
;
981 #if TO_MODE_UNSIGNED == 0
982 BIG_SINT_C_TYPE stemp
;
984 #if BIG_WIDTH != TO_FBITS
985 BIG_UINT_C_TYPE utemp
;
989 /* Step 1. We need to store x to {high, low}. */
990 low
= (BIG_SINT_C_TYPE
) x
;
996 /* Step 2. We need to left shift {high, low}. */
997 #if BIG_WIDTH == TO_FBITS
1001 shift_amount
= TO_FBITS
;
1002 utemp
= (BIG_UINT_C_TYPE
) low
;
1003 utemp
= utemp
>> (BIG_WIDTH
- shift_amount
);
1004 high
= ((BIG_UINT_C_TYPE
)(high
<< shift_amount
)) | utemp
;
1005 low
= low
<< shift_amount
;
1008 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
1010 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1011 max_low
= (BIG_UINT_C_TYPE
)1 << TO_I_F_BITS
;
1012 max_low
= max_low
- 1;
1017 #if TO_MODE_UNSIGNED == 0
1019 stemp
= (BIG_SINT_C_TYPE
)1 << (BIG_WIDTH
- 1);
1020 stemp
= stemp
>> (BIG_WIDTH
- 1 - TO_I_F_BITS
);
1027 #if TO_MODE_UNSIGNED == 0
1028 /* Signed -> Signed. */
1029 if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
1030 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
1031 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1032 low
= max_low
; /* Maximum. */
1033 else if ((BIG_SINT_C_TYPE
) high
< (BIG_SINT_C_TYPE
) min_high
1034 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) min_high
1035 && (BIG_UINT_C_TYPE
) low
< (BIG_UINT_C_TYPE
) min_low
))
1036 low
= min_low
; /* Minimum. */
1038 /* Signed -> Unsigned. */
1040 low
= 0; /* Minimum. */
1041 else if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
1042 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
1043 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1044 low
= max_low
; /* Maximum. */
1047 /* Step 4. Store the result. */
1048 z
= (TO_INT_C_TYPE
) low
;
1049 #if TO_HAVE_PADDING_BITS
1050 z
= z
<< TO_PADDING_BITS
;
1051 z
= z
>> TO_PADDING_BITS
;
1053 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1056 #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
1058 /* Unsigned int -> Fixed. */
1059 #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4
1061 FRACTUNS (FROM_INT_C_TYPE a
)
1065 z
= (TO_INT_C_TYPE
) a
;
1066 #if TO_FIXED_WIDTH == TO_FBITS
1071 #if TO_HAVE_PADDING_BITS
1072 z
= z
<< TO_PADDING_BITS
;
1073 z
= z
>> TO_PADDING_BITS
;
1075 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1078 #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
1080 /* Unsigned int -> Fixed with saturation. */
1081 #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4
1083 SATFRACTUNS (FROM_INT_C_TYPE a
)
1087 FROM_INT_C_TYPE x
= a
;
1088 BIG_UINT_C_TYPE high
, low
;
1089 BIG_UINT_C_TYPE max_high
, max_low
;
1090 #if BIG_WIDTH != TO_FBITS
1091 BIG_UINT_C_TYPE utemp
;
1095 /* Step 1. We need to store x to {high, low}. */
1096 low
= (BIG_UINT_C_TYPE
) x
;
1099 /* Step 2. We need to left shift {high, low}. */
1100 #if BIG_WIDTH == TO_FBITS
1104 shift_amount
= TO_FBITS
;
1105 utemp
= (BIG_UINT_C_TYPE
) low
;
1106 utemp
= utemp
>> (BIG_WIDTH
- shift_amount
);
1107 high
= ((BIG_UINT_C_TYPE
)(high
<< shift_amount
)) | utemp
;
1108 low
= low
<< shift_amount
;
1111 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
1113 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1114 max_low
= (BIG_UINT_C_TYPE
)1 << TO_I_F_BITS
;
1115 max_low
= max_low
- 1;
1120 #if TO_MODE_UNSIGNED == 1
1121 /* Unigned -> Unsigned. */
1122 if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
1123 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
1124 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1125 low
= max_low
; /* Maximum. */
1127 /* Unsigned -> Signed. */
1128 if ((BIG_SINT_C_TYPE
) high
< 0)
1129 low
= max_low
; /* Maximum. */
1130 else if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
1131 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
1132 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1133 low
= max_low
; /* Maximum. */
1136 /* Step 4. Store the result. */
1137 z
= (TO_INT_C_TYPE
) low
;
1138 #if TO_HAVE_PADDING_BITS
1139 z
= z
<< TO_PADDING_BITS
;
1140 z
= z
>> TO_PADDING_BITS
;
1142 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1145 #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
1147 /* Fixed -> Float. */
1148 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3
1150 FRACT (FROM_FIXED_C_TYPE a
)
1154 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
1155 z
= (TO_FLOAT_C_TYPE
) x
;
1159 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3 */
1161 /* Float -> Fixed. */
1162 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4
1164 FRACT (FROM_FLOAT_C_TYPE a
)
1166 FROM_FLOAT_C_TYPE temp
;
1171 z
= (TO_INT_C_TYPE
) temp
;
1172 #if TO_HAVE_PADDING_BITS
1173 z
= z
<< TO_PADDING_BITS
;
1174 z
= z
>> TO_PADDING_BITS
;
1176 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1179 #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */
1181 /* Float -> Fixed with saturation. */
1182 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4
1184 SATFRACT (FROM_FLOAT_C_TYPE a
)
1186 FROM_FLOAT_C_TYPE temp
;
1192 #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1193 z
= (TO_INT_C_TYPE
)1 << TO_I_F_BITS
;
1199 else if (a
<= FIXED_MIN
)
1201 #if TO_MODE_UNSIGNED == 0
1202 z
= (TO_INT_C_TYPE
)1 << TO_I_F_BITS
;
1210 z
= (TO_INT_C_TYPE
) temp
;
1213 #if TO_HAVE_PADDING_BITS
1214 z
= z
<< TO_PADDING_BITS
;
1215 z
= z
>> TO_PADDING_BITS
;
1217 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1220 #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */