1 /* This is a software fixed-point library.
2 Copyright (C) 2007, 2009 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"
50 #ifndef MIN_UNITS_PER_WORD
51 #define MIN_UNITS_PER_WORD UNITS_PER_WORD
54 #include "fixed-bit.h"
56 #if defined(FIXED_ADD) && defined(L_add)
58 FIXED_ADD (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
62 memcpy (&x
, &a
, FIXED_SIZE
);
63 memcpy (&y
, &b
, FIXED_SIZE
);
66 z
= z
<< PADDING_BITS
;
67 z
= z
>> PADDING_BITS
;
69 memcpy (&c
, &z
, FIXED_SIZE
);
72 #endif /* FIXED_ADD */
74 #if defined(FIXED_SSADD) && defined(L_ssadd)
76 FIXED_SSADD (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
80 memcpy (&x
, &a
, FIXED_SIZE
);
81 memcpy (&y
, &b
, FIXED_SIZE
);
83 if ((((x
^ y
) >> I_F_BITS
) & 1) == 0)
85 if (((z
^ x
) >> I_F_BITS
) & 1)
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
);
155 if (((x
^ y
) >> I_F_BITS
) & 1)
157 if (((z
^ x
) >> I_F_BITS
) & 1)
165 #if HAVE_PADDING_BITS
166 z
= z
<< PADDING_BITS
;
167 z
= z
>> PADDING_BITS
;
169 memcpy (&c
, &z
, FIXED_SIZE
);
172 #endif /* FIXED_SSSUB */
174 #if defined(FIXED_USSUB) && defined(L_ussub)
176 FIXED_USSUB (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
180 memcpy (&x
, &a
, FIXED_SIZE
);
181 memcpy (&y
, &b
, FIXED_SIZE
);
185 #if HAVE_PADDING_BITS
186 z
= z
<< PADDING_BITS
;
187 z
= z
>> PADDING_BITS
;
189 memcpy (&c
, &z
, FIXED_SIZE
);
192 #endif /* FIXED_USSUB */
194 #if defined(FIXED_SATURATE1) && defined(L_saturate1)
196 FIXED_SATURATE1 (DINT_C_TYPE
*a
)
198 DINT_C_TYPE max
, min
;
199 max
= (DINT_C_TYPE
)1 << I_F_BITS
;
201 #if MODE_UNSIGNED == 0
202 min
= (DINT_C_TYPE
)1 << (2 * FIXED_WIDTH
- 1);
203 min
= min
>> (2 * FIXED_WIDTH
- 1 - I_F_BITS
);
212 #endif /* FIXED_SATURATE1 */
214 #if defined(FIXED_SATURATE2) && defined(L_saturate2)
216 FIXED_SATURATE2 (INT_C_TYPE
*high
, INT_C_TYPE
*low
)
218 INT_C_TYPE r_max
, s_max
, r_min
, s_min
;
220 #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS
221 s_max
= (INT_C_TYPE
)1 << I_F_BITS
;
226 #if MODE_UNSIGNED == 0
228 s_min
= (INT_C_TYPE
)1 << (FIXED_WIDTH
- 1);
229 s_min
= s_min
>> (FIXED_WIDTH
- 1 - I_F_BITS
);
236 || (*high
== r_max
&& (UINT_C_TYPE
)(*low
) > (UINT_C_TYPE
)s_max
))
241 else if (*high
< r_min
||
242 (*high
== r_min
&& (UINT_C_TYPE
)(*low
) < (UINT_C_TYPE
)s_min
))
248 #endif /* FIXED_SATURATE2 */
250 #if defined(FIXED_MULHELPER) && defined(L_mulhelper)
252 FIXED_MULHELPER (FIXED_C_TYPE a
, FIXED_C_TYPE b
, word_type satp
)
257 #if defined (DINT_C_TYPE)
259 DINT_C_TYPE dx
, dy
, dz
;
260 memcpy (&x
, &a
, FIXED_SIZE
);
261 memcpy (&y
, &b
, FIXED_SIZE
);
262 dx
= (DINT_C_TYPE
) x
;
263 dy
= (DINT_C_TYPE
) y
;
265 /* Round the result by adding (1 << (FBITS -1)). */
266 dz
+= ((DINT_C_TYPE
) 1 << (FBITS
- 1));
269 FIXED_SATURATE1 (&dz
);
272 #if HAVE_PADDING_BITS
273 z
= z
<< PADDING_BITS
;
274 z
= z
>> PADDING_BITS
;
276 memcpy (&c
, &z
, FIXED_SIZE
);
279 #else /* No DINT_C_TYPE */
280 /* The result of multiplication expands to two INT_C_TYPE. */
282 INTunion a_high
, a_low
, b_high
, b_low
;
283 INTunion high_high
, high_low
, low_high
, low_low
;
284 INTunion r
, s
, temp1
, temp2
;
285 INT_C_TYPE carry
= 0;
288 memcpy (&x
, &a
, FIXED_SIZE
);
289 memcpy (&y
, &b
, FIXED_SIZE
);
291 /* Decompose a and b. */
295 a_high
.s
.low
= aa
.s
.high
;
297 a_low
.s
.low
= aa
.s
.low
;
299 b_high
.s
.low
= bb
.s
.high
;
301 b_low
.s
.low
= bb
.s
.low
;
304 /* Perform four multiplications. */
305 low_low
.ll
= a_low
.ll
* b_low
.ll
;
306 low_high
.ll
= a_low
.ll
* b_high
.ll
;
307 high_low
.ll
= a_high
.ll
* b_low
.ll
;
308 high_high
.ll
= a_high
.ll
* b_high
.ll
;
310 /* Accumulate four results to {r, s}. */
311 temp1
.s
.high
= high_low
.s
.low
;
313 s
.ll
= low_low
.ll
+ temp1
.ll
;
314 if ((UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) low_low
.ll
315 || (UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp1
.ll
)
316 carry
++; /* Carry. */
318 temp2
.s
.high
= low_high
.s
.low
;
320 s
.ll
= temp1
.ll
+ temp2
.ll
;
321 if ((UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp1
.ll
322 || (UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp2
.ll
)
323 carry
++; /* Carry. */
325 temp1
.s
.low
= high_low
.s
.high
;
327 r
.ll
= high_high
.ll
+ temp1
.ll
;
328 temp1
.s
.low
= low_high
.s
.high
;
330 r
.ll
= r
.ll
+ temp1
.ll
+ carry
;
332 #if MODE_UNSIGNED == 0
333 /* For signed types, we need to add neg(y) to r, if x < 0. */
336 /* We need to add neg(x) to r, if y < 0. */
341 /* Round the result by adding (1 << (FBITS -1)). */
343 s
.ll
+= ((INT_C_TYPE
) 1 << (FBITS
-1));
344 if ((UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) temp1
.ll
345 || (UINT_C_TYPE
) s
.ll
< (UINT_C_TYPE
) ((INT_C_TYPE
) 1 << (FBITS
-1)))
348 /* Shift right the result by FBITS. */
349 #if FBITS == FIXED_WIDTH
350 /* This happens only for unsigned types without any padding bits.
351 So, it is safe to set r.ll to 0 as it is logically shifted right. */
355 s
.ll
= ((UINT_C_TYPE
)s
.ll
) >> FBITS
;
356 temp1
.ll
= r
.ll
<< (FIXED_WIDTH
- FBITS
);
357 s
.ll
= s
.ll
| temp1
.ll
;
358 r
.ll
= r
.ll
>> FBITS
;
362 FIXED_SATURATE2 (&r
.ll
, &s
.ll
);
364 z
= (INT_C_TYPE
) s
.ll
;
365 #if HAVE_PADDING_BITS
366 z
= z
<< PADDING_BITS
;
367 z
= z
>> PADDING_BITS
;
369 memcpy (&c
, &z
, FIXED_SIZE
);
373 #endif /* FIXED_MULHELPER */
375 #if defined(FIXED_MUL) && defined(L_mul)
377 FIXED_MUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
379 return FIXED_MULHELPER (a
, b
, 0);
381 #endif /* FIXED_MUL */
383 #if defined(FIXED_SSMUL) && defined(L_ssmul)
385 FIXED_SSMUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
387 return FIXED_MULHELPER (a
, b
, 1);
389 #endif /* FIXED_SSMUL */
391 #if defined(FIXED_USMUL) && defined(L_usmul)
393 FIXED_USMUL (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
395 return FIXED_MULHELPER (a
, b
, 1);
397 #endif /* FIXED_USMUL */
399 #if defined(FIXED_DIVHELPER) && defined(L_divhelper)
401 FIXED_DIVHELPER (FIXED_C_TYPE a
, FIXED_C_TYPE b
, word_type satp
)
407 #if defined (DINT_C_TYPE)
408 DINT_C_TYPE dx
, dy
, dz
;
409 memcpy (&x
, &a
, FIXED_SIZE
);
410 memcpy (&y
, &b
, FIXED_SIZE
);
411 dx
= (DINT_C_TYPE
) x
;
412 dy
= (DINT_C_TYPE
) y
;
416 FIXED_SATURATE1 (&dz
);
418 #if HAVE_PADDING_BITS
419 z
= z
<< PADDING_BITS
;
420 z
= z
>> PADDING_BITS
;
422 memcpy (&c
, &z
, FIXED_SIZE
);
425 #else /* No DINT_C_TYPE */
426 INT_C_TYPE pos_a
, pos_b
, r
, s
;
427 INT_C_TYPE quo_r
, quo_s
, mod
, temp
;
429 #if MODE_UNSIGNED == 0
430 word_type num_of_neg
= 0;
433 memcpy (&x
, &a
, FIXED_SIZE
);
434 memcpy (&y
, &b
, FIXED_SIZE
);
438 #if MODE_UNSIGNED == 0
439 /* If a < 0, negate a. */
445 /* If b < 0, negate b. */
453 /* Left shift pos_a to {r, s} by FBITS. */
454 #if FBITS == FIXED_WIDTH
455 /* This happens only for unsigned types without any padding bits. */
460 r
= pos_a
>> (FIXED_WIDTH
- FBITS
);
463 /* Unsigned divide r by pos_b to quo_r. The remainder is in mod. */
464 quo_r
= (UINT_C_TYPE
)r
/ (UINT_C_TYPE
)pos_b
;
465 mod
= (UINT_C_TYPE
)r
% (UINT_C_TYPE
)pos_b
;
468 for (i
= 0; i
< FIXED_WIDTH
; i
++)
470 /* Record the leftmost bit of mod. */
471 word_type leftmost_mode
= (mod
>> (FIXED_WIDTH
- 1)) & 1;
472 /* Shift left mod by 1 bit. */
474 /* Test the leftmost bit of s to add to mod. */
475 if ((s
>> (FIXED_WIDTH
- 1)) & 1)
477 /* Shift left quo_s by 1 bit. */
479 /* Try to calculate (mod - pos_b). */
481 if (leftmost_mode
|| (UINT_C_TYPE
)mod
>= (UINT_C_TYPE
)pos_b
)
486 /* Shift left s by 1 bit. */
490 #if MODE_UNSIGNED == 0
501 FIXED_SATURATE2 (&quo_r
, &quo_s
);
503 #if HAVE_PADDING_BITS
504 z
= z
<< PADDING_BITS
;
505 z
= z
>> PADDING_BITS
;
507 memcpy (&c
, &z
, FIXED_SIZE
);
511 #endif /* FIXED_DIVHELPER */
513 #if defined(FIXED_DIV) && defined(L_div)
515 FIXED_DIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
517 return FIXED_DIVHELPER (a
, b
, 0);
519 #endif /* FIXED_DIV */
522 #if defined(FIXED_UDIV) && defined(L_udiv)
524 FIXED_UDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
526 return FIXED_DIVHELPER (a
, b
, 0);
528 #endif /* FIXED_UDIV */
530 #if defined(FIXED_SSDIV) && defined(L_ssdiv)
532 FIXED_SSDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
534 return FIXED_DIVHELPER (a
, b
, 1);
536 #endif /* FIXED_SSDIV */
538 #if defined(FIXED_USDIV) && defined(L_usdiv)
540 FIXED_USDIV (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
542 return FIXED_DIVHELPER (a
, b
, 1);
544 #endif /* FIXED_USDIV */
546 #if defined(FIXED_NEG) && defined(L_neg)
548 FIXED_NEG (FIXED_C_TYPE a
)
552 memcpy (&x
, &a
, FIXED_SIZE
);
554 #if HAVE_PADDING_BITS
555 z
= z
<< PADDING_BITS
;
556 z
= z
>> PADDING_BITS
;
558 memcpy (&c
, &z
, FIXED_SIZE
);
561 #endif /* FIXED_NEG */
563 #if defined(FIXED_SSNEG) && defined(L_ssneg)
565 FIXED_SSNEG (FIXED_C_TYPE a
)
569 memcpy (&y
, &a
, FIXED_SIZE
);
572 if (((x
^ y
) >> I_F_BITS
) & 1)
574 if (((z
^ x
) >> I_F_BITS
) & 1)
582 #if HAVE_PADDING_BITS
583 z
= z
<< PADDING_BITS
;
584 z
= z
>> PADDING_BITS
;
586 memcpy (&c
, &z
, FIXED_SIZE
);
589 #endif /* FIXED_SSNEG */
591 #if defined(FIXED_USNEG) && defined(L_usneg)
593 FIXED_USNEG (FIXED_C_TYPE a
__attribute__ ((__unused__
)))
598 memcpy (&c
, &z
, FIXED_SIZE
);
601 #endif /* FIXED_USNEG */
603 #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper)
605 FIXED_ASHLHELPER (FIXED_C_TYPE a
, word_type b
, word_type satp
)
610 #if defined (DINT_C_TYPE)
612 memcpy (&x
, &a
, FIXED_SIZE
);
613 dx
= (DINT_C_TYPE
) x
;
614 if (b
>= FIXED_WIDTH
)
615 dz
= dx
<< FIXED_WIDTH
;
619 FIXED_SATURATE1 (&dz
);
621 #if HAVE_PADDING_BITS
622 z
= z
<< PADDING_BITS
;
623 z
= z
>> PADDING_BITS
;
625 memcpy (&c
, &z
, FIXED_SIZE
);
628 #else /* No DINT_C_TYPE */
630 memcpy (&x
, &a
, FIXED_SIZE
);
631 /* We need to shift left x by b bits to {r, s}. */
632 if (b
>= FIXED_WIDTH
)
640 r
= x
>> (FIXED_WIDTH
- b
);
643 FIXED_SATURATE2 (&r
, &s
);
645 #if HAVE_PADDING_BITS
646 z
= z
<< PADDING_BITS
;
647 z
= z
>> PADDING_BITS
;
649 memcpy (&c
, &z
, FIXED_SIZE
);
653 #endif /* FIXED_ASHLHELPER */
655 #if defined(FIXED_ASHL) && defined(L_ashl)
657 FIXED_ASHL (FIXED_C_TYPE a
, word_type b
)
659 return FIXED_ASHLHELPER (a
, b
, 0);
661 #endif /* FIXED_ASHL */
663 #if defined(FIXED_ASHR) && defined(L_ashr)
665 FIXED_ASHR (FIXED_C_TYPE a
, word_type b
)
669 memcpy (&x
, &a
, FIXED_SIZE
);
671 #if HAVE_PADDING_BITS
672 z
= z
<< PADDING_BITS
;
673 z
= z
>> PADDING_BITS
;
675 memcpy (&c
, &z
, FIXED_SIZE
);
678 #endif /* FIXED_ASHR */
680 #if defined(FIXED_LSHR) && defined(L_lshr)
682 FIXED_LSHR (FIXED_C_TYPE a
, word_type b
)
686 memcpy (&x
, &a
, FIXED_SIZE
);
688 #if HAVE_PADDING_BITS
689 z
= z
<< PADDING_BITS
;
690 z
= z
>> PADDING_BITS
;
692 memcpy (&c
, &z
, FIXED_SIZE
);
695 #endif /* FIXED_LSHR */
697 #if defined(FIXED_SSASHL) && defined(L_ssashl)
699 FIXED_SSASHL (FIXED_C_TYPE a
, word_type b
)
701 return FIXED_ASHLHELPER (a
, b
, 1);
703 #endif /* FIXED_SSASHL */
705 #if defined(FIXED_USASHL) && defined(L_usashl)
707 FIXED_USASHL (FIXED_C_TYPE a
, word_type b
)
709 return FIXED_ASHLHELPER (a
, b
, 1);
711 #endif /* FIXED_USASHL */
713 #if defined(FIXED_CMP) && defined(L_cmp)
715 FIXED_CMP (FIXED_C_TYPE a
, FIXED_C_TYPE b
)
718 memcpy (&x
, &a
, FIXED_SIZE
);
719 memcpy (&y
, &b
, FIXED_SIZE
);
728 #endif /* FIXED_CMP */
730 /* Fixed -> Fixed. */
731 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4
733 FRACT (FROM_FIXED_C_TYPE a
)
739 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
740 #if TO_FBITS > FROM_FBITS /* Need left shift. */
741 shift_amount
= TO_FBITS
- FROM_FBITS
;
742 z
= (TO_INT_C_TYPE
) x
;
743 z
= z
<< shift_amount
;
744 #else /* TO_FBITS <= FROM_FBITS. Need right Shift. */
745 shift_amount
= FROM_FBITS
- TO_FBITS
;
746 x
= x
>> shift_amount
;
747 z
= (TO_INT_C_TYPE
) x
;
748 #endif /* TO_FBITS > FROM_FBITS */
750 #if TO_HAVE_PADDING_BITS
751 z
= z
<< TO_PADDING_BITS
;
752 z
= z
>> TO_PADDING_BITS
;
754 memcpy (&c
, &z
, TO_FIXED_SIZE
);
757 #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4 */
759 /* Fixed -> Fixed with saturation. */
760 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4
762 SATFRACT (FROM_FIXED_C_TYPE a
)
767 #if FROM_MODE_UNSIGNED == 0
768 BIG_SINT_C_TYPE high
, low
;
769 BIG_SINT_C_TYPE max_high
, max_low
;
770 BIG_SINT_C_TYPE min_high
, min_low
;
772 BIG_UINT_C_TYPE high
, low
;
773 BIG_UINT_C_TYPE max_high
, max_low
;
774 BIG_UINT_C_TYPE min_high
, min_low
;
776 #if TO_FBITS > FROM_FBITS
777 BIG_UINT_C_TYPE utemp
;
779 #if TO_MODE_UNSIGNED == 0
780 BIG_SINT_C_TYPE stemp
;
782 #if TO_FBITS != FROM_FBITS
785 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
787 /* Step 1. We need to store x to {high, low}. */
788 #if FROM_MODE_UNSIGNED == 0
789 low
= (BIG_SINT_C_TYPE
) x
;
795 low
= (BIG_UINT_C_TYPE
) x
;
799 /* Step 2. We need to shift {high, low}. */
800 #if TO_FBITS > FROM_FBITS /* Left shift. */
801 shift_amount
= TO_FBITS
- FROM_FBITS
;
802 utemp
= (BIG_UINT_C_TYPE
) low
;
803 utemp
= utemp
>> (BIG_WIDTH
- shift_amount
);
804 high
= ((BIG_UINT_C_TYPE
)(high
<< shift_amount
)) | utemp
;
805 low
= low
<< shift_amount
;
806 #elif TO_FBITS < FROM_FBITS /* Right shift. */
807 shift_amount
= FROM_FBITS
- TO_FBITS
;
808 low
= low
>> shift_amount
;
811 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
813 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
814 max_low
= (BIG_UINT_C_TYPE
)1 << TO_I_F_BITS
;
815 max_low
= max_low
- 1;
820 #if TO_MODE_UNSIGNED == 0
822 stemp
= (BIG_SINT_C_TYPE
)1 << (BIG_WIDTH
- 1);
823 stemp
= stemp
>> (BIG_WIDTH
- 1 - TO_I_F_BITS
);
830 #if FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 0
831 /* Signed -> Signed. */
832 if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
833 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
834 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
835 low
= max_low
; /* Maximum. */
836 else if ((BIG_SINT_C_TYPE
) high
< (BIG_SINT_C_TYPE
) min_high
837 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) min_high
838 && (BIG_UINT_C_TYPE
) low
< (BIG_UINT_C_TYPE
) min_low
))
839 low
= min_low
; /* Minimum. */
840 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 1
841 /* Unigned -> Unsigned. */
842 if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
843 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
844 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
845 low
= max_low
; /* Maximum. */
846 #elif FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 1
847 /* Signed -> Unsigned. */
849 low
= 0; /* Minimum. */
850 else if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
851 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
852 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
853 low
= max_low
; /* Maximum. */
854 #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 0
855 /* Unsigned -> Signed. */
856 if ((BIG_SINT_C_TYPE
) high
< 0)
857 low
= max_low
; /* Maximum. */
858 else if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
859 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
860 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
861 low
= max_low
; /* Maximum. */
864 /* Step 4. Store the result. */
865 z
= (TO_INT_C_TYPE
) low
;
866 #if TO_HAVE_PADDING_BITS
867 z
= z
<< TO_PADDING_BITS
;
868 z
= z
>> TO_PADDING_BITS
;
870 memcpy (&c
, &z
, TO_FIXED_SIZE
);
873 #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4 */
876 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1
878 FRACT (FROM_FIXED_C_TYPE a
)
882 FROM_INT_C_TYPE i
= 0;
883 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
885 #if FROM_MODE_UNSIGNED == 0
888 #if FROM_FIXED_WIDTH == FROM_FBITS
892 if (((FROM_INT_C_TYPE
)(x
<< (FROM_FIXED_WIDTH
- FROM_FBITS
))) != 0)
898 #if FROM_FIXED_WIDTH == FROM_FBITS
904 z
= (TO_INT_C_TYPE
) x
;
907 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1 */
909 /* Fixed -> Unsigned int. */
910 #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2
912 FRACTUNS (FROM_FIXED_C_TYPE a
)
916 FROM_INT_C_TYPE i
= 0;
917 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
919 #if FROM_MODE_UNSIGNED == 0
922 #if FROM_FIXED_WIDTH == FROM_FBITS
926 if (((FROM_INT_C_TYPE
)(x
<< (FROM_FIXED_WIDTH
- FROM_FBITS
))) != 0)
932 #if FROM_FIXED_WIDTH == FROM_FBITS
938 z
= (TO_INT_C_TYPE
) x
;
941 #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2 */
944 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4
946 FRACT (FROM_INT_C_TYPE a
)
950 z
= (TO_INT_C_TYPE
) a
;
951 #if TO_FIXED_WIDTH == TO_FBITS
956 #if TO_HAVE_PADDING_BITS
957 z
= z
<< TO_PADDING_BITS
;
958 z
= z
>> TO_PADDING_BITS
;
960 memcpy (&c
, &z
, TO_FIXED_SIZE
);
963 #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
965 /* Signed int -> Fixed with saturation. */
966 #if defined(SATFRACT) && defined(L_satfract) &&FROM_TYPE == 1 && TO_TYPE == 4
968 SATFRACT (FROM_INT_C_TYPE a
)
972 FROM_INT_C_TYPE x
= a
;
973 BIG_SINT_C_TYPE high
, low
;
974 BIG_SINT_C_TYPE max_high
, max_low
;
975 BIG_SINT_C_TYPE min_high
, min_low
;
976 #if TO_MODE_UNSIGNED == 0
977 BIG_SINT_C_TYPE stemp
;
979 #if BIG_WIDTH != TO_FBITS
980 BIG_UINT_C_TYPE utemp
;
984 /* Step 1. We need to store x to {high, low}. */
985 low
= (BIG_SINT_C_TYPE
) x
;
991 /* Step 2. We need to left shift {high, low}. */
992 #if BIG_WIDTH == TO_FBITS
996 shift_amount
= TO_FBITS
;
997 utemp
= (BIG_UINT_C_TYPE
) low
;
998 utemp
= utemp
>> (BIG_WIDTH
- shift_amount
);
999 high
= ((BIG_UINT_C_TYPE
)(high
<< shift_amount
)) | utemp
;
1000 low
= low
<< shift_amount
;
1003 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
1005 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1006 max_low
= (BIG_UINT_C_TYPE
)1 << TO_I_F_BITS
;
1007 max_low
= max_low
- 1;
1012 #if TO_MODE_UNSIGNED == 0
1014 stemp
= (BIG_SINT_C_TYPE
)1 << (BIG_WIDTH
- 1);
1015 stemp
= stemp
>> (BIG_WIDTH
- 1 - TO_I_F_BITS
);
1022 #if TO_MODE_UNSIGNED == 0
1023 /* Signed -> Signed. */
1024 if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
1025 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
1026 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1027 low
= max_low
; /* Maximum. */
1028 else if ((BIG_SINT_C_TYPE
) high
< (BIG_SINT_C_TYPE
) min_high
1029 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) min_high
1030 && (BIG_UINT_C_TYPE
) low
< (BIG_UINT_C_TYPE
) min_low
))
1031 low
= min_low
; /* Minimum. */
1033 /* Signed -> Unsigned. */
1035 low
= 0; /* Minimum. */
1036 else if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
1037 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
1038 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1039 low
= max_low
; /* Maximum. */
1042 /* Step 4. Store the result. */
1043 z
= (TO_INT_C_TYPE
) low
;
1044 #if TO_HAVE_PADDING_BITS
1045 z
= z
<< TO_PADDING_BITS
;
1046 z
= z
>> TO_PADDING_BITS
;
1048 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1051 #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
1053 /* Unsigned int -> Fixed. */
1054 #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4
1056 FRACTUNS (FROM_INT_C_TYPE a
)
1060 z
= (TO_INT_C_TYPE
) a
;
1061 #if TO_FIXED_WIDTH == TO_FBITS
1066 #if TO_HAVE_PADDING_BITS
1067 z
= z
<< TO_PADDING_BITS
;
1068 z
= z
>> TO_PADDING_BITS
;
1070 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1073 #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
1075 /* Unsigned int -> Fixed with saturation. */
1076 #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4
1078 SATFRACTUNS (FROM_INT_C_TYPE a
)
1082 FROM_INT_C_TYPE x
= a
;
1083 BIG_UINT_C_TYPE high
, low
;
1084 BIG_UINT_C_TYPE max_high
, max_low
;
1085 #if BIG_WIDTH != TO_FBITS
1086 BIG_UINT_C_TYPE utemp
;
1090 /* Step 1. We need to store x to {high, low}. */
1091 low
= (BIG_UINT_C_TYPE
) x
;
1094 /* Step 2. We need to left shift {high, low}. */
1095 #if BIG_WIDTH == TO_FBITS
1099 shift_amount
= TO_FBITS
;
1100 utemp
= (BIG_UINT_C_TYPE
) low
;
1101 utemp
= utemp
>> (BIG_WIDTH
- shift_amount
);
1102 high
= ((BIG_UINT_C_TYPE
)(high
<< shift_amount
)) | utemp
;
1103 low
= low
<< shift_amount
;
1106 /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
1108 #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1109 max_low
= (BIG_UINT_C_TYPE
)1 << TO_I_F_BITS
;
1110 max_low
= max_low
- 1;
1115 #if TO_MODE_UNSIGNED == 1
1116 /* Unigned -> Unsigned. */
1117 if ((BIG_UINT_C_TYPE
) high
> (BIG_UINT_C_TYPE
) max_high
1118 || ((BIG_UINT_C_TYPE
) high
== (BIG_UINT_C_TYPE
) max_high
1119 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1120 low
= max_low
; /* Maximum. */
1122 /* Unsigned -> Signed. */
1123 if ((BIG_SINT_C_TYPE
) high
< 0)
1124 low
= max_low
; /* Maximum. */
1125 else if ((BIG_SINT_C_TYPE
) high
> (BIG_SINT_C_TYPE
) max_high
1126 || ((BIG_SINT_C_TYPE
) high
== (BIG_SINT_C_TYPE
) max_high
1127 && (BIG_UINT_C_TYPE
) low
> (BIG_UINT_C_TYPE
) max_low
))
1128 low
= max_low
; /* Maximum. */
1131 /* Step 4. Store the result. */
1132 z
= (TO_INT_C_TYPE
) low
;
1133 #if TO_HAVE_PADDING_BITS
1134 z
= z
<< TO_PADDING_BITS
;
1135 z
= z
>> TO_PADDING_BITS
;
1137 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1140 #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
1142 /* Fixed -> Float. */
1143 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3
1145 FRACT (FROM_FIXED_C_TYPE a
)
1149 memcpy (&x
, &a
, FROM_FIXED_SIZE
);
1150 z
= (TO_FLOAT_C_TYPE
) x
;
1154 #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3 */
1156 /* Float -> Fixed. */
1157 #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4
1159 FRACT (FROM_FLOAT_C_TYPE a
)
1161 FROM_FLOAT_C_TYPE temp
;
1166 z
= (TO_INT_C_TYPE
) temp
;
1167 #if TO_HAVE_PADDING_BITS
1168 z
= z
<< TO_PADDING_BITS
;
1169 z
= z
>> TO_PADDING_BITS
;
1171 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1174 #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */
1176 /* Float -> Fixed with saturation. */
1177 #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4
1179 SATFRACT (FROM_FLOAT_C_TYPE a
)
1181 FROM_FLOAT_C_TYPE temp
;
1187 #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
1188 z
= (TO_INT_C_TYPE
)1 << TO_I_F_BITS
;
1194 else if (a
<= FIXED_MIN
)
1196 #if TO_MODE_UNSIGNED == 0
1197 z
= (TO_INT_C_TYPE
)1 << TO_I_F_BITS
;
1205 z
= (TO_INT_C_TYPE
) temp
;
1208 #if TO_HAVE_PADDING_BITS
1209 z
= z
<< TO_PADDING_BITS
;
1210 z
= z
>> TO_PADDING_BITS
;
1212 memcpy (&c
, &z
, TO_FIXED_SIZE
);
1215 #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */