11debfc3dSmrg /* This is a software fixed-point library.
2*8feb0f0bSmrg Copyright (C) 2007-2020 Free Software Foundation, Inc.
31debfc3dSmrg
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
71debfc3dSmrg the terms of the GNU General Public License as published by the Free
81debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
91debfc3dSmrg version.
101debfc3dSmrg
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
121debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
131debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
141debfc3dSmrg for more details.
151debfc3dSmrg
161debfc3dSmrg Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg You should have received a copy of the GNU General Public License and
211debfc3dSmrg a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
231debfc3dSmrg <http://www.gnu.org/licenses/>. */
241debfc3dSmrg
251debfc3dSmrg /* This implements fixed-point arithmetic.
261debfc3dSmrg
271debfc3dSmrg Contributed by Chao-ying Fu <fu@mips.com>. */
281debfc3dSmrg
291debfc3dSmrg /* To use this file, we need to define one of the following:
301debfc3dSmrg QQ_MODE, UQQ_MODE, HQ_MODE, UHQ_MODE, SQ_MODE, USQ_MODE, DQ_MODE, UDQ_MODE,
311debfc3dSmrg TQ_MODE, UTQ_MODE, HA_MODE, UHA_MODE, SA_MODE, USA_MODE, DA_MODE, UDA_MODE,
321debfc3dSmrg TA_MODE, UTA_MODE.
331debfc3dSmrg Then, all operators for this machine mode will be created.
341debfc3dSmrg
351debfc3dSmrg Or, we need to define FROM_* TO_* for conversions from one mode to another
361debfc3dSmrg mode. The mode could be one of the following:
371debfc3dSmrg Fract: QQ, UQQ, HQ, UHQ, SQ, USQ, DQ, UDQ, TQ, UTQ
381debfc3dSmrg Accum: HA, UHA, SA, USA, DA, UDA, TA, UTA
391debfc3dSmrg Signed integer: QI, HI, SI, DI, TI
401debfc3dSmrg Unsigned integer: UQI, UHI, USI, UDI, UTI
411debfc3dSmrg Floating-point: SF, DF
421debfc3dSmrg Ex: If we define FROM_QQ and TO_SI, the conversion from QQ to SI is
431debfc3dSmrg generated. */
441debfc3dSmrg
451debfc3dSmrg #include "tconfig.h"
461debfc3dSmrg #include "tsystem.h"
471debfc3dSmrg #include "coretypes.h"
481debfc3dSmrg #include "tm.h"
491debfc3dSmrg #include "libgcc_tm.h"
501debfc3dSmrg
511debfc3dSmrg #ifndef MIN_UNITS_PER_WORD
521debfc3dSmrg #define MIN_UNITS_PER_WORD UNITS_PER_WORD
531debfc3dSmrg #endif
541debfc3dSmrg
551debfc3dSmrg #include "fixed-bit.h"
561debfc3dSmrg
571debfc3dSmrg #if defined(FIXED_ADD) && defined(L_add)
581debfc3dSmrg FIXED_C_TYPE
FIXED_ADD(FIXED_C_TYPE a,FIXED_C_TYPE b)591debfc3dSmrg FIXED_ADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
601debfc3dSmrg {
611debfc3dSmrg FIXED_C_TYPE c;
621debfc3dSmrg INT_C_TYPE x, y, z;
631debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
641debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
651debfc3dSmrg z = x + y;
661debfc3dSmrg #if HAVE_PADDING_BITS
671debfc3dSmrg z = z << PADDING_BITS;
681debfc3dSmrg z = z >> PADDING_BITS;
691debfc3dSmrg #endif
701debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
711debfc3dSmrg return c;
721debfc3dSmrg }
731debfc3dSmrg #endif /* FIXED_ADD */
741debfc3dSmrg
751debfc3dSmrg #if defined(FIXED_SSADD) && defined(L_ssadd)
761debfc3dSmrg FIXED_C_TYPE
FIXED_SSADD(FIXED_C_TYPE a,FIXED_C_TYPE b)771debfc3dSmrg FIXED_SSADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
781debfc3dSmrg {
791debfc3dSmrg FIXED_C_TYPE c;
801debfc3dSmrg INT_C_TYPE x, y, z;
811debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
821debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
831debfc3dSmrg z = x + (UINT_C_TYPE) y;
841debfc3dSmrg if ((((x ^ y) >> I_F_BITS) & 1) == 0)
851debfc3dSmrg {
861debfc3dSmrg if (((z ^ x) >> I_F_BITS) & 1)
871debfc3dSmrg {
881debfc3dSmrg z = ((UINT_C_TYPE) 1) << I_F_BITS;
891debfc3dSmrg if (x >= 0)
901debfc3dSmrg z -= (UINT_C_TYPE) 1;
911debfc3dSmrg }
921debfc3dSmrg }
931debfc3dSmrg #if HAVE_PADDING_BITS
941debfc3dSmrg z = z << PADDING_BITS;
951debfc3dSmrg z = z >> PADDING_BITS;
961debfc3dSmrg #endif
971debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
981debfc3dSmrg return c;
991debfc3dSmrg }
1001debfc3dSmrg #endif /* FIXED_SSADD */
1011debfc3dSmrg
1021debfc3dSmrg #if defined(FIXED_USADD) && defined(L_usadd)
1031debfc3dSmrg FIXED_C_TYPE
FIXED_USADD(FIXED_C_TYPE a,FIXED_C_TYPE b)1041debfc3dSmrg FIXED_USADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
1051debfc3dSmrg {
1061debfc3dSmrg FIXED_C_TYPE c;
1071debfc3dSmrg INT_C_TYPE x, y, z;
1081debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
1091debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
1101debfc3dSmrg z = x + y;
1111debfc3dSmrg #if HAVE_PADDING_BITS
1121debfc3dSmrg z = z << PADDING_BITS;
1131debfc3dSmrg z = z >> PADDING_BITS;
1141debfc3dSmrg #endif
1151debfc3dSmrg if (z < x || z < y) /* max */
1161debfc3dSmrg {
1171debfc3dSmrg z = -1;
1181debfc3dSmrg #if HAVE_PADDING_BITS
1191debfc3dSmrg z = z << PADDING_BITS;
1201debfc3dSmrg z = z >> PADDING_BITS;
1211debfc3dSmrg #endif
1221debfc3dSmrg }
1231debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
1241debfc3dSmrg return c;
1251debfc3dSmrg }
1261debfc3dSmrg #endif /* FIXED_USADD */
1271debfc3dSmrg
1281debfc3dSmrg #if defined(FIXED_SUB) && defined(L_sub)
1291debfc3dSmrg FIXED_C_TYPE
FIXED_SUB(FIXED_C_TYPE a,FIXED_C_TYPE b)1301debfc3dSmrg FIXED_SUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
1311debfc3dSmrg {
1321debfc3dSmrg FIXED_C_TYPE c;
1331debfc3dSmrg INT_C_TYPE x, y, z;
1341debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
1351debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
1361debfc3dSmrg z = x - y;
1371debfc3dSmrg #if HAVE_PADDING_BITS
1381debfc3dSmrg z = z << PADDING_BITS;
1391debfc3dSmrg z = z >> PADDING_BITS;
1401debfc3dSmrg #endif
1411debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
1421debfc3dSmrg return c;
1431debfc3dSmrg }
1441debfc3dSmrg #endif /* FIXED_SUB */
1451debfc3dSmrg
1461debfc3dSmrg #if defined(FIXED_SSSUB) && defined(L_sssub)
1471debfc3dSmrg FIXED_C_TYPE
FIXED_SSSUB(FIXED_C_TYPE a,FIXED_C_TYPE b)1481debfc3dSmrg FIXED_SSSUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
1491debfc3dSmrg {
1501debfc3dSmrg FIXED_C_TYPE c;
1511debfc3dSmrg INT_C_TYPE x, y, z;
1521debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
1531debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
1541debfc3dSmrg z = x - (UINT_C_TYPE) y;
1551debfc3dSmrg if (((x ^ y) >> I_F_BITS) & 1)
1561debfc3dSmrg {
1571debfc3dSmrg if (((z ^ x) >> I_F_BITS) & 1)
1581debfc3dSmrg {
1591debfc3dSmrg z = ((UINT_C_TYPE) 1) << I_F_BITS;
1601debfc3dSmrg if (x >= 0)
1611debfc3dSmrg z -= (UINT_C_TYPE) 1;
1621debfc3dSmrg }
1631debfc3dSmrg }
1641debfc3dSmrg #if HAVE_PADDING_BITS
1651debfc3dSmrg z = z << PADDING_BITS;
1661debfc3dSmrg z = z >> PADDING_BITS;
1671debfc3dSmrg #endif
1681debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
1691debfc3dSmrg return c;
1701debfc3dSmrg }
1711debfc3dSmrg #endif /* FIXED_SSSUB */
1721debfc3dSmrg
1731debfc3dSmrg #if defined(FIXED_USSUB) && defined(L_ussub)
1741debfc3dSmrg FIXED_C_TYPE
FIXED_USSUB(FIXED_C_TYPE a,FIXED_C_TYPE b)1751debfc3dSmrg FIXED_USSUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
1761debfc3dSmrg {
1771debfc3dSmrg FIXED_C_TYPE c;
1781debfc3dSmrg INT_C_TYPE x, y, z;
1791debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
1801debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
1811debfc3dSmrg z = x - y;
1821debfc3dSmrg if (x < y)
1831debfc3dSmrg z = 0;
1841debfc3dSmrg #if HAVE_PADDING_BITS
1851debfc3dSmrg z = z << PADDING_BITS;
1861debfc3dSmrg z = z >> PADDING_BITS;
1871debfc3dSmrg #endif
1881debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
1891debfc3dSmrg return c;
1901debfc3dSmrg }
1911debfc3dSmrg #endif /* FIXED_USSUB */
1921debfc3dSmrg
1931debfc3dSmrg #if defined(FIXED_SATURATE1) && defined(L_saturate1)
1941debfc3dSmrg void
FIXED_SATURATE1(DINT_C_TYPE * a)1951debfc3dSmrg FIXED_SATURATE1 (DINT_C_TYPE *a)
1961debfc3dSmrg {
1971debfc3dSmrg DINT_C_TYPE max, min;
1981debfc3dSmrg max = (DINT_C_TYPE)1 << I_F_BITS;
1991debfc3dSmrg max = max - 1;
2001debfc3dSmrg #if MODE_UNSIGNED == 0
2011debfc3dSmrg min = (DINT_C_TYPE)1 << (2 * FIXED_WIDTH - 1);
2021debfc3dSmrg min = min >> (2 * FIXED_WIDTH - 1 - I_F_BITS);
2031debfc3dSmrg #else
2041debfc3dSmrg min = 0;
2051debfc3dSmrg #endif
2061debfc3dSmrg if (*a > max)
2071debfc3dSmrg *a = max;
2081debfc3dSmrg else if (*a < min)
2091debfc3dSmrg *a = min;
2101debfc3dSmrg }
2111debfc3dSmrg #endif /* FIXED_SATURATE1 */
2121debfc3dSmrg
2131debfc3dSmrg #if defined(FIXED_SATURATE2) && defined(L_saturate2)
2141debfc3dSmrg void
FIXED_SATURATE2(INT_C_TYPE * high,INT_C_TYPE * low)2151debfc3dSmrg FIXED_SATURATE2 (INT_C_TYPE *high, INT_C_TYPE *low)
2161debfc3dSmrg {
2171debfc3dSmrg INT_C_TYPE r_max, s_max, r_min, s_min;
2181debfc3dSmrg r_max = 0;
2191debfc3dSmrg #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS
2201debfc3dSmrg s_max = (INT_C_TYPE)1 << I_F_BITS;
2211debfc3dSmrg s_max = s_max - 1;
2221debfc3dSmrg #else
2231debfc3dSmrg s_max = -1;
2241debfc3dSmrg #endif
2251debfc3dSmrg #if MODE_UNSIGNED == 0
2261debfc3dSmrg r_min = -1;
2271debfc3dSmrg s_min = (INT_C_TYPE)1 << (FIXED_WIDTH - 1);
2281debfc3dSmrg s_min = s_min >> (FIXED_WIDTH - 1 - I_F_BITS);
2291debfc3dSmrg #else
2301debfc3dSmrg r_min = 0;
2311debfc3dSmrg s_min = 0;
2321debfc3dSmrg #endif
2331debfc3dSmrg
2341debfc3dSmrg if (*high > r_max
2351debfc3dSmrg || (*high == r_max && (UINT_C_TYPE)(*low) > (UINT_C_TYPE)s_max))
2361debfc3dSmrg {
2371debfc3dSmrg *high = r_max;
2381debfc3dSmrg *low = s_max;
2391debfc3dSmrg }
2401debfc3dSmrg else if (*high < r_min ||
2411debfc3dSmrg (*high == r_min && (UINT_C_TYPE)(*low) < (UINT_C_TYPE)s_min))
2421debfc3dSmrg {
2431debfc3dSmrg *high = r_min;
2441debfc3dSmrg *low = s_min;
2451debfc3dSmrg }
2461debfc3dSmrg }
2471debfc3dSmrg #endif /* FIXED_SATURATE2 */
2481debfc3dSmrg
2491debfc3dSmrg #if defined(FIXED_MULHELPER) && defined(L_mulhelper)
2501debfc3dSmrg FIXED_C_TYPE
FIXED_MULHELPER(FIXED_C_TYPE a,FIXED_C_TYPE b,word_type satp)2511debfc3dSmrg FIXED_MULHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp)
2521debfc3dSmrg {
2531debfc3dSmrg FIXED_C_TYPE c;
2541debfc3dSmrg INT_C_TYPE x, y;
2551debfc3dSmrg
2561debfc3dSmrg #if defined (DINT_C_TYPE)
2571debfc3dSmrg INT_C_TYPE z;
2581debfc3dSmrg DINT_C_TYPE dx, dy, dz;
2591debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
2601debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
2611debfc3dSmrg dx = (DINT_C_TYPE) x;
2621debfc3dSmrg dy = (DINT_C_TYPE) y;
2631debfc3dSmrg dz = dx * dy;
2641debfc3dSmrg /* Round the result by adding (1 << (FBITS -1)). */
2651debfc3dSmrg dz += ((DINT_C_TYPE) 1 << (FBITS - 1));
2661debfc3dSmrg dz = dz >> FBITS;
2671debfc3dSmrg if (satp)
2681debfc3dSmrg FIXED_SATURATE1 (&dz);
2691debfc3dSmrg
2701debfc3dSmrg z = (INT_C_TYPE) dz;
2711debfc3dSmrg #if HAVE_PADDING_BITS
2721debfc3dSmrg z = z << PADDING_BITS;
2731debfc3dSmrg z = z >> PADDING_BITS;
2741debfc3dSmrg #endif
2751debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
2761debfc3dSmrg return c;
2771debfc3dSmrg
2781debfc3dSmrg #else /* No DINT_C_TYPE */
2791debfc3dSmrg /* The result of multiplication expands to two INT_C_TYPE. */
2801debfc3dSmrg INTunion aa, bb;
2811debfc3dSmrg INTunion a_high, a_low, b_high, b_low;
2821debfc3dSmrg INTunion high_high, high_low, low_high, low_low;
2831debfc3dSmrg INTunion r, s, temp1, temp2;
2841debfc3dSmrg INT_C_TYPE carry = 0;
2851debfc3dSmrg INT_C_TYPE z;
2861debfc3dSmrg
2871debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
2881debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
2891debfc3dSmrg
2901debfc3dSmrg /* Decompose a and b. */
2911debfc3dSmrg aa.ll = x;
2921debfc3dSmrg bb.ll = y;
2931debfc3dSmrg
2941debfc3dSmrg a_high.s.low = aa.s.high;
2951debfc3dSmrg a_high.s.high = 0;
2961debfc3dSmrg a_low.s.low = aa.s.low;
2971debfc3dSmrg a_low.s.high = 0;
2981debfc3dSmrg b_high.s.low = bb.s.high;
2991debfc3dSmrg b_high.s.high = 0;
3001debfc3dSmrg b_low.s.low = bb.s.low;
3011debfc3dSmrg b_low.s.high = 0;
3021debfc3dSmrg
3031debfc3dSmrg /* Perform four multiplications. */
3041debfc3dSmrg low_low.ll = a_low.ll * b_low.ll;
3051debfc3dSmrg low_high.ll = a_low.ll * b_high.ll;
3061debfc3dSmrg high_low.ll = a_high.ll * b_low.ll;
3071debfc3dSmrg high_high.ll = a_high.ll * b_high.ll;
3081debfc3dSmrg
3091debfc3dSmrg /* Accumulate four results to {r, s}. */
3101debfc3dSmrg temp1.s.high = high_low.s.low;
3111debfc3dSmrg temp1.s.low = 0;
3121debfc3dSmrg s.ll = low_low.ll + temp1.ll;
3131debfc3dSmrg if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) low_low.ll
3141debfc3dSmrg || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll)
3151debfc3dSmrg carry ++; /* Carry. */
3161debfc3dSmrg temp1.ll = s.ll;
3171debfc3dSmrg temp2.s.high = low_high.s.low;
3181debfc3dSmrg temp2.s.low = 0;
3191debfc3dSmrg s.ll = temp1.ll + temp2.ll;
3201debfc3dSmrg if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll
3211debfc3dSmrg || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp2.ll)
3221debfc3dSmrg carry ++; /* Carry. */
3231debfc3dSmrg
3241debfc3dSmrg temp1.s.low = high_low.s.high;
3251debfc3dSmrg temp1.s.high = 0;
3261debfc3dSmrg r.ll = high_high.ll + temp1.ll;
3271debfc3dSmrg temp1.s.low = low_high.s.high;
3281debfc3dSmrg temp1.s.high = 0;
3291debfc3dSmrg r.ll = r.ll + temp1.ll + carry;
3301debfc3dSmrg
3311debfc3dSmrg #if MODE_UNSIGNED == 0
3321debfc3dSmrg /* For signed types, we need to add neg(y) to r, if x < 0. */
3331debfc3dSmrg if (x < 0)
3341debfc3dSmrg r.ll = r.ll - y;
3351debfc3dSmrg /* We need to add neg(x) to r, if y < 0. */
3361debfc3dSmrg if (y < 0)
3371debfc3dSmrg r.ll = r.ll - x;
3381debfc3dSmrg #endif
3391debfc3dSmrg
3401debfc3dSmrg /* Round the result by adding (1 << (FBITS -1)). */
3411debfc3dSmrg temp1.ll = s.ll;
3421debfc3dSmrg s.ll += ((INT_C_TYPE) 1 << (FBITS -1));
3431debfc3dSmrg if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll
3441debfc3dSmrg || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) ((INT_C_TYPE) 1 << (FBITS -1)))
3451debfc3dSmrg r.ll += 1;
3461debfc3dSmrg
3471debfc3dSmrg /* Shift right the result by FBITS. */
3481debfc3dSmrg #if FBITS == FIXED_WIDTH
3491debfc3dSmrg /* This happens only for unsigned types without any padding bits.
3501debfc3dSmrg So, it is safe to set r.ll to 0 as it is logically shifted right. */
3511debfc3dSmrg s.ll = r.ll;
3521debfc3dSmrg r.ll = 0;
3531debfc3dSmrg #else
3541debfc3dSmrg s.ll = ((UINT_C_TYPE)s.ll) >> FBITS;
3551debfc3dSmrg temp1.ll = r.ll << (FIXED_WIDTH - FBITS);
3561debfc3dSmrg s.ll = s.ll | temp1.ll;
3571debfc3dSmrg r.ll = r.ll >> FBITS;
3581debfc3dSmrg #endif
3591debfc3dSmrg
3601debfc3dSmrg if (satp)
3611debfc3dSmrg FIXED_SATURATE2 (&r.ll, &s.ll);
3621debfc3dSmrg
3631debfc3dSmrg z = (INT_C_TYPE) s.ll;
3641debfc3dSmrg #if HAVE_PADDING_BITS
3651debfc3dSmrg z = z << PADDING_BITS;
3661debfc3dSmrg z = z >> PADDING_BITS;
3671debfc3dSmrg #endif
3681debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
3691debfc3dSmrg return c;
3701debfc3dSmrg #endif
3711debfc3dSmrg }
3721debfc3dSmrg #endif /* FIXED_MULHELPER */
3731debfc3dSmrg
3741debfc3dSmrg #if defined(FIXED_MUL) && defined(L_mul)
3751debfc3dSmrg FIXED_C_TYPE
FIXED_MUL(FIXED_C_TYPE a,FIXED_C_TYPE b)3761debfc3dSmrg FIXED_MUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
3771debfc3dSmrg {
3781debfc3dSmrg return FIXED_MULHELPER (a, b, 0);
3791debfc3dSmrg }
3801debfc3dSmrg #endif /* FIXED_MUL */
3811debfc3dSmrg
3821debfc3dSmrg #if defined(FIXED_SSMUL) && defined(L_ssmul)
3831debfc3dSmrg FIXED_C_TYPE
FIXED_SSMUL(FIXED_C_TYPE a,FIXED_C_TYPE b)3841debfc3dSmrg FIXED_SSMUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
3851debfc3dSmrg {
3861debfc3dSmrg return FIXED_MULHELPER (a, b, 1);
3871debfc3dSmrg }
3881debfc3dSmrg #endif /* FIXED_SSMUL */
3891debfc3dSmrg
3901debfc3dSmrg #if defined(FIXED_USMUL) && defined(L_usmul)
3911debfc3dSmrg FIXED_C_TYPE
FIXED_USMUL(FIXED_C_TYPE a,FIXED_C_TYPE b)3921debfc3dSmrg FIXED_USMUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
3931debfc3dSmrg {
3941debfc3dSmrg return FIXED_MULHELPER (a, b, 1);
3951debfc3dSmrg }
3961debfc3dSmrg #endif /* FIXED_USMUL */
3971debfc3dSmrg
3981debfc3dSmrg #if defined(FIXED_DIVHELPER) && defined(L_divhelper)
3991debfc3dSmrg FIXED_C_TYPE
FIXED_DIVHELPER(FIXED_C_TYPE a,FIXED_C_TYPE b,word_type satp)4001debfc3dSmrg FIXED_DIVHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp)
4011debfc3dSmrg {
4021debfc3dSmrg FIXED_C_TYPE c;
4031debfc3dSmrg INT_C_TYPE x, y;
4041debfc3dSmrg INT_C_TYPE z;
4051debfc3dSmrg
4061debfc3dSmrg #if defined (DINT_C_TYPE)
4071debfc3dSmrg DINT_C_TYPE dx, dy, dz;
4081debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
4091debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
4101debfc3dSmrg dx = (DINT_C_TYPE) x;
4111debfc3dSmrg dy = (DINT_C_TYPE) y;
4121debfc3dSmrg dx = dx << FBITS;
4131debfc3dSmrg dz = dx / dy;
4141debfc3dSmrg if (satp)
4151debfc3dSmrg FIXED_SATURATE1 (&dz);
4161debfc3dSmrg z = (INT_C_TYPE) dz;
4171debfc3dSmrg #if HAVE_PADDING_BITS
4181debfc3dSmrg z = z << PADDING_BITS;
4191debfc3dSmrg z = z >> PADDING_BITS;
4201debfc3dSmrg #endif
4211debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
4221debfc3dSmrg return c;
4231debfc3dSmrg
4241debfc3dSmrg #else /* No DINT_C_TYPE */
4251debfc3dSmrg INT_C_TYPE pos_a, pos_b, r, s;
4261debfc3dSmrg INT_C_TYPE quo_r, quo_s, mod, temp;
4271debfc3dSmrg word_type i;
4281debfc3dSmrg #if MODE_UNSIGNED == 0
4291debfc3dSmrg word_type num_of_neg = 0;
4301debfc3dSmrg #endif
4311debfc3dSmrg
4321debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
4331debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
4341debfc3dSmrg pos_a = x;
4351debfc3dSmrg pos_b = y;
4361debfc3dSmrg
4371debfc3dSmrg #if MODE_UNSIGNED == 0
4381debfc3dSmrg /* If a < 0, negate a. */
4391debfc3dSmrg if (pos_a < 0)
4401debfc3dSmrg {
4411debfc3dSmrg pos_a = -pos_a;
4421debfc3dSmrg num_of_neg ++;
4431debfc3dSmrg }
4441debfc3dSmrg /* If b < 0, negate b. */
4451debfc3dSmrg if (pos_b < 0)
4461debfc3dSmrg {
4471debfc3dSmrg pos_b = -pos_b;
4481debfc3dSmrg num_of_neg ++;
4491debfc3dSmrg }
4501debfc3dSmrg #endif
4511debfc3dSmrg
4521debfc3dSmrg /* Left shift pos_a to {r, s} by FBITS. */
4531debfc3dSmrg #if FBITS == FIXED_WIDTH
4541debfc3dSmrg /* This happens only for unsigned types without any padding bits. */
4551debfc3dSmrg r = pos_a;
4561debfc3dSmrg s = 0;
4571debfc3dSmrg #else
4581debfc3dSmrg s = pos_a << FBITS;
4591debfc3dSmrg r = pos_a >> (FIXED_WIDTH - FBITS);
4601debfc3dSmrg #endif
4611debfc3dSmrg
4621debfc3dSmrg /* Unsigned divide r by pos_b to quo_r. The remainder is in mod. */
4631debfc3dSmrg quo_r = (UINT_C_TYPE)r / (UINT_C_TYPE)pos_b;
4641debfc3dSmrg mod = (UINT_C_TYPE)r % (UINT_C_TYPE)pos_b;
4651debfc3dSmrg quo_s = 0;
4661debfc3dSmrg
4671debfc3dSmrg for (i = 0; i < FIXED_WIDTH; i++)
4681debfc3dSmrg {
4691debfc3dSmrg /* Record the leftmost bit of mod. */
4701debfc3dSmrg word_type leftmost_mode = (mod >> (FIXED_WIDTH - 1)) & 1;
4711debfc3dSmrg /* Shift left mod by 1 bit. */
4721debfc3dSmrg mod = mod << 1;
4731debfc3dSmrg /* Test the leftmost bit of s to add to mod. */
4741debfc3dSmrg if ((s >> (FIXED_WIDTH - 1)) & 1)
4751debfc3dSmrg mod ++;
4761debfc3dSmrg /* Shift left quo_s by 1 bit. */
4771debfc3dSmrg quo_s = quo_s << 1;
4781debfc3dSmrg /* Try to calculate (mod - pos_b). */
4791debfc3dSmrg temp = mod - pos_b;
4801debfc3dSmrg if (leftmost_mode || (UINT_C_TYPE)mod >= (UINT_C_TYPE)pos_b)
4811debfc3dSmrg {
4821debfc3dSmrg quo_s ++;
4831debfc3dSmrg mod = temp;
4841debfc3dSmrg }
4851debfc3dSmrg /* Shift left s by 1 bit. */
4861debfc3dSmrg s = s << 1;
4871debfc3dSmrg }
4881debfc3dSmrg
4891debfc3dSmrg #if MODE_UNSIGNED == 0
4901debfc3dSmrg if (num_of_neg == 1)
4911debfc3dSmrg {
4921debfc3dSmrg quo_s = -quo_s;
4931debfc3dSmrg if (quo_s == 0)
4941debfc3dSmrg quo_r = -quo_r;
4951debfc3dSmrg else
4961debfc3dSmrg quo_r = ~quo_r;
4971debfc3dSmrg }
4981debfc3dSmrg #endif
4991debfc3dSmrg if (satp)
5001debfc3dSmrg FIXED_SATURATE2 (&quo_r, &quo_s);
5011debfc3dSmrg z = quo_s;
5021debfc3dSmrg #if HAVE_PADDING_BITS
5031debfc3dSmrg z = z << PADDING_BITS;
5041debfc3dSmrg z = z >> PADDING_BITS;
5051debfc3dSmrg #endif
5061debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
5071debfc3dSmrg return c;
5081debfc3dSmrg #endif
5091debfc3dSmrg }
5101debfc3dSmrg #endif /* FIXED_DIVHELPER */
5111debfc3dSmrg
5121debfc3dSmrg #if defined(FIXED_DIV) && defined(L_div)
5131debfc3dSmrg FIXED_C_TYPE
FIXED_DIV(FIXED_C_TYPE a,FIXED_C_TYPE b)5141debfc3dSmrg FIXED_DIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
5151debfc3dSmrg {
5161debfc3dSmrg return FIXED_DIVHELPER (a, b, 0);
5171debfc3dSmrg }
5181debfc3dSmrg #endif /* FIXED_DIV */
5191debfc3dSmrg
5201debfc3dSmrg
5211debfc3dSmrg #if defined(FIXED_UDIV) && defined(L_udiv)
5221debfc3dSmrg FIXED_C_TYPE
FIXED_UDIV(FIXED_C_TYPE a,FIXED_C_TYPE b)5231debfc3dSmrg FIXED_UDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
5241debfc3dSmrg {
5251debfc3dSmrg return FIXED_DIVHELPER (a, b, 0);
5261debfc3dSmrg }
5271debfc3dSmrg #endif /* FIXED_UDIV */
5281debfc3dSmrg
5291debfc3dSmrg #if defined(FIXED_SSDIV) && defined(L_ssdiv)
5301debfc3dSmrg FIXED_C_TYPE
FIXED_SSDIV(FIXED_C_TYPE a,FIXED_C_TYPE b)5311debfc3dSmrg FIXED_SSDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
5321debfc3dSmrg {
5331debfc3dSmrg return FIXED_DIVHELPER (a, b, 1);
5341debfc3dSmrg }
5351debfc3dSmrg #endif /* FIXED_SSDIV */
5361debfc3dSmrg
5371debfc3dSmrg #if defined(FIXED_USDIV) && defined(L_usdiv)
5381debfc3dSmrg FIXED_C_TYPE
FIXED_USDIV(FIXED_C_TYPE a,FIXED_C_TYPE b)5391debfc3dSmrg FIXED_USDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
5401debfc3dSmrg {
5411debfc3dSmrg return FIXED_DIVHELPER (a, b, 1);
5421debfc3dSmrg }
5431debfc3dSmrg #endif /* FIXED_USDIV */
5441debfc3dSmrg
5451debfc3dSmrg #if defined(FIXED_NEG) && defined(L_neg)
5461debfc3dSmrg FIXED_C_TYPE
FIXED_NEG(FIXED_C_TYPE a)5471debfc3dSmrg FIXED_NEG (FIXED_C_TYPE a)
5481debfc3dSmrg {
5491debfc3dSmrg FIXED_C_TYPE c;
5501debfc3dSmrg INT_C_TYPE x, z;
5511debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
5521debfc3dSmrg z = -x;
5531debfc3dSmrg #if HAVE_PADDING_BITS
5541debfc3dSmrg z = z << PADDING_BITS;
5551debfc3dSmrg z = z >> PADDING_BITS;
5561debfc3dSmrg #endif
5571debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
5581debfc3dSmrg return c;
5591debfc3dSmrg }
5601debfc3dSmrg #endif /* FIXED_NEG */
5611debfc3dSmrg
5621debfc3dSmrg #if defined(FIXED_SSNEG) && defined(L_ssneg)
5631debfc3dSmrg FIXED_C_TYPE
FIXED_SSNEG(FIXED_C_TYPE a)5641debfc3dSmrg FIXED_SSNEG (FIXED_C_TYPE a)
5651debfc3dSmrg {
5661debfc3dSmrg FIXED_C_TYPE c;
5671debfc3dSmrg INT_C_TYPE x, y, z;
5681debfc3dSmrg memcpy (&y, &a, FIXED_SIZE);
5691debfc3dSmrg x = 0;
5701debfc3dSmrg z = x - (UINT_C_TYPE) y;
5711debfc3dSmrg if (((x ^ y) >> I_F_BITS) & 1)
5721debfc3dSmrg {
5731debfc3dSmrg if (((z ^ x) >> I_F_BITS) & 1)
5741debfc3dSmrg z = (((UINT_C_TYPE) 1) << I_F_BITS) - 1;
5751debfc3dSmrg }
5761debfc3dSmrg #if HAVE_PADDING_BITS
5771debfc3dSmrg z = z << PADDING_BITS;
5781debfc3dSmrg z = z >> PADDING_BITS;
5791debfc3dSmrg #endif
5801debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
5811debfc3dSmrg return c;
5821debfc3dSmrg }
5831debfc3dSmrg #endif /* FIXED_SSNEG */
5841debfc3dSmrg
5851debfc3dSmrg #if defined(FIXED_USNEG) && defined(L_usneg)
5861debfc3dSmrg FIXED_C_TYPE
FIXED_USNEG(FIXED_C_TYPE a)5871debfc3dSmrg FIXED_USNEG (FIXED_C_TYPE a __attribute__ ((__unused__)))
5881debfc3dSmrg {
5891debfc3dSmrg FIXED_C_TYPE c;
5901debfc3dSmrg INT_C_TYPE z;
5911debfc3dSmrg z = 0;
5921debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
5931debfc3dSmrg return c;
5941debfc3dSmrg }
5951debfc3dSmrg #endif /* FIXED_USNEG */
5961debfc3dSmrg
5971debfc3dSmrg #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper)
5981debfc3dSmrg FIXED_C_TYPE
FIXED_ASHLHELPER(FIXED_C_TYPE a,word_type b,word_type satp)5991debfc3dSmrg FIXED_ASHLHELPER (FIXED_C_TYPE a, word_type b, word_type satp)
6001debfc3dSmrg {
6011debfc3dSmrg FIXED_C_TYPE c;
6021debfc3dSmrg INT_C_TYPE x, z;
6031debfc3dSmrg
6041debfc3dSmrg #if defined (DINT_C_TYPE)
6051debfc3dSmrg DINT_C_TYPE dx, dz;
6061debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
6071debfc3dSmrg dx = (DINT_C_TYPE) x;
6081debfc3dSmrg if (b >= FIXED_WIDTH)
6091debfc3dSmrg dz = dx << FIXED_WIDTH;
6101debfc3dSmrg else
6111debfc3dSmrg dz = dx << b;
6121debfc3dSmrg if (satp)
6131debfc3dSmrg FIXED_SATURATE1 (&dz);
6141debfc3dSmrg z = (INT_C_TYPE) dz;
6151debfc3dSmrg #if HAVE_PADDING_BITS
6161debfc3dSmrg z = z << PADDING_BITS;
6171debfc3dSmrg z = z >> PADDING_BITS;
6181debfc3dSmrg #endif
6191debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
6201debfc3dSmrg return c;
6211debfc3dSmrg
6221debfc3dSmrg #else /* No DINT_C_TYPE */
6231debfc3dSmrg INT_C_TYPE r, s;
6241debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
6251debfc3dSmrg /* We need to shift left x by b bits to {r, s}. */
6261debfc3dSmrg if (b >= FIXED_WIDTH)
6271debfc3dSmrg {
6281debfc3dSmrg r = b;
6291debfc3dSmrg s = 0;
6301debfc3dSmrg }
6311debfc3dSmrg else
6321debfc3dSmrg {
6331debfc3dSmrg s = x << b;
6341debfc3dSmrg r = x >> (FIXED_WIDTH - b);
6351debfc3dSmrg }
6361debfc3dSmrg if (satp)
6371debfc3dSmrg FIXED_SATURATE2 (&r, &s);
6381debfc3dSmrg z = s;
6391debfc3dSmrg #if HAVE_PADDING_BITS
6401debfc3dSmrg z = z << PADDING_BITS;
6411debfc3dSmrg z = z >> PADDING_BITS;
6421debfc3dSmrg #endif
6431debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
6441debfc3dSmrg return c;
6451debfc3dSmrg #endif
6461debfc3dSmrg }
6471debfc3dSmrg #endif /* FIXED_ASHLHELPER */
6481debfc3dSmrg
6491debfc3dSmrg #if defined(FIXED_ASHL) && defined(L_ashl)
6501debfc3dSmrg FIXED_C_TYPE
FIXED_ASHL(FIXED_C_TYPE a,word_type b)6511debfc3dSmrg FIXED_ASHL (FIXED_C_TYPE a, word_type b)
6521debfc3dSmrg {
6531debfc3dSmrg return FIXED_ASHLHELPER (a, b, 0);
6541debfc3dSmrg }
6551debfc3dSmrg #endif /* FIXED_ASHL */
6561debfc3dSmrg
6571debfc3dSmrg #if defined(FIXED_ASHR) && defined(L_ashr)
6581debfc3dSmrg FIXED_C_TYPE
FIXED_ASHR(FIXED_C_TYPE a,word_type b)6591debfc3dSmrg FIXED_ASHR (FIXED_C_TYPE a, word_type b)
6601debfc3dSmrg {
6611debfc3dSmrg FIXED_C_TYPE c;
6621debfc3dSmrg INT_C_TYPE x, z;
6631debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
6641debfc3dSmrg z = x >> b;
6651debfc3dSmrg #if HAVE_PADDING_BITS
6661debfc3dSmrg z = z << PADDING_BITS;
6671debfc3dSmrg z = z >> PADDING_BITS;
6681debfc3dSmrg #endif
6691debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
6701debfc3dSmrg return c;
6711debfc3dSmrg }
6721debfc3dSmrg #endif /* FIXED_ASHR */
6731debfc3dSmrg
6741debfc3dSmrg #if defined(FIXED_LSHR) && defined(L_lshr)
6751debfc3dSmrg FIXED_C_TYPE
FIXED_LSHR(FIXED_C_TYPE a,word_type b)6761debfc3dSmrg FIXED_LSHR (FIXED_C_TYPE a, word_type b)
6771debfc3dSmrg {
6781debfc3dSmrg FIXED_C_TYPE c;
6791debfc3dSmrg INT_C_TYPE x, z;
6801debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
6811debfc3dSmrg z = x >> b;
6821debfc3dSmrg #if HAVE_PADDING_BITS
6831debfc3dSmrg z = z << PADDING_BITS;
6841debfc3dSmrg z = z >> PADDING_BITS;
6851debfc3dSmrg #endif
6861debfc3dSmrg memcpy (&c, &z, FIXED_SIZE);
6871debfc3dSmrg return c;
6881debfc3dSmrg }
6891debfc3dSmrg #endif /* FIXED_LSHR */
6901debfc3dSmrg
6911debfc3dSmrg #if defined(FIXED_SSASHL) && defined(L_ssashl)
6921debfc3dSmrg FIXED_C_TYPE
FIXED_SSASHL(FIXED_C_TYPE a,word_type b)6931debfc3dSmrg FIXED_SSASHL (FIXED_C_TYPE a, word_type b)
6941debfc3dSmrg {
6951debfc3dSmrg return FIXED_ASHLHELPER (a, b, 1);
6961debfc3dSmrg }
6971debfc3dSmrg #endif /* FIXED_SSASHL */
6981debfc3dSmrg
6991debfc3dSmrg #if defined(FIXED_USASHL) && defined(L_usashl)
7001debfc3dSmrg FIXED_C_TYPE
FIXED_USASHL(FIXED_C_TYPE a,word_type b)7011debfc3dSmrg FIXED_USASHL (FIXED_C_TYPE a, word_type b)
7021debfc3dSmrg {
7031debfc3dSmrg return FIXED_ASHLHELPER (a, b, 1);
7041debfc3dSmrg }
7051debfc3dSmrg #endif /* FIXED_USASHL */
7061debfc3dSmrg
7071debfc3dSmrg #if defined(FIXED_CMP) && defined(L_cmp)
7081debfc3dSmrg word_type
FIXED_CMP(FIXED_C_TYPE a,FIXED_C_TYPE b)7091debfc3dSmrg FIXED_CMP (FIXED_C_TYPE a, FIXED_C_TYPE b)
7101debfc3dSmrg {
7111debfc3dSmrg INT_C_TYPE x, y;
7121debfc3dSmrg memcpy (&x, &a, FIXED_SIZE);
7131debfc3dSmrg memcpy (&y, &b, FIXED_SIZE);
7141debfc3dSmrg
7151debfc3dSmrg if (x < y)
7161debfc3dSmrg return 0;
7171debfc3dSmrg else if (x > y)
7181debfc3dSmrg return 2;
7191debfc3dSmrg
7201debfc3dSmrg return 1;
7211debfc3dSmrg }
7221debfc3dSmrg #endif /* FIXED_CMP */
7231debfc3dSmrg
7241debfc3dSmrg /* Fixed -> Fixed. */
7251debfc3dSmrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4
7261debfc3dSmrg TO_FIXED_C_TYPE
FRACT(FROM_FIXED_C_TYPE a)7271debfc3dSmrg FRACT (FROM_FIXED_C_TYPE a)
7281debfc3dSmrg {
7291debfc3dSmrg TO_FIXED_C_TYPE c;
7301debfc3dSmrg FROM_INT_C_TYPE x;
7311debfc3dSmrg TO_INT_C_TYPE z;
7321debfc3dSmrg int shift_amount;
7331debfc3dSmrg memcpy (&x, &a, FROM_FIXED_SIZE);
7341debfc3dSmrg #if TO_FBITS > FROM_FBITS /* Need left shift. */
7351debfc3dSmrg shift_amount = TO_FBITS - FROM_FBITS;
7361debfc3dSmrg z = (TO_INT_C_TYPE) x;
7371debfc3dSmrg z = z << shift_amount;
7381debfc3dSmrg #else /* TO_FBITS <= FROM_FBITS. Need right Shift. */
7391debfc3dSmrg shift_amount = FROM_FBITS - TO_FBITS;
7401debfc3dSmrg x = x >> shift_amount;
7411debfc3dSmrg z = (TO_INT_C_TYPE) x;
7421debfc3dSmrg #endif /* TO_FBITS > FROM_FBITS */
7431debfc3dSmrg
7441debfc3dSmrg #if TO_HAVE_PADDING_BITS
7451debfc3dSmrg z = z << TO_PADDING_BITS;
7461debfc3dSmrg z = z >> TO_PADDING_BITS;
7471debfc3dSmrg #endif
7481debfc3dSmrg memcpy (&c, &z, TO_FIXED_SIZE);
7491debfc3dSmrg return c;
7501debfc3dSmrg }
7511debfc3dSmrg #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4 */
7521debfc3dSmrg
7531debfc3dSmrg /* Fixed -> Fixed with saturation. */
7541debfc3dSmrg #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4
7551debfc3dSmrg TO_FIXED_C_TYPE
SATFRACT(FROM_FIXED_C_TYPE a)7561debfc3dSmrg SATFRACT (FROM_FIXED_C_TYPE a)
7571debfc3dSmrg {
7581debfc3dSmrg TO_FIXED_C_TYPE c;
7591debfc3dSmrg TO_INT_C_TYPE z;
7601debfc3dSmrg FROM_INT_C_TYPE x;
7611debfc3dSmrg #if FROM_MODE_UNSIGNED == 0
7621debfc3dSmrg BIG_SINT_C_TYPE high, low;
7631debfc3dSmrg BIG_SINT_C_TYPE max_high, max_low;
7641debfc3dSmrg #if TO_MODE_UNSIGNED == 0
7651debfc3dSmrg BIG_SINT_C_TYPE min_high, min_low;
7661debfc3dSmrg #endif
7671debfc3dSmrg #else
7681debfc3dSmrg BIG_UINT_C_TYPE high, low;
7691debfc3dSmrg BIG_UINT_C_TYPE max_high, max_low;
7701debfc3dSmrg #endif
7711debfc3dSmrg #if TO_FBITS > FROM_FBITS
7721debfc3dSmrg BIG_UINT_C_TYPE utemp;
7731debfc3dSmrg #endif
7741debfc3dSmrg #if TO_MODE_UNSIGNED == 0
7751debfc3dSmrg BIG_SINT_C_TYPE stemp;
7761debfc3dSmrg #endif
7771debfc3dSmrg #if TO_FBITS != FROM_FBITS
7781debfc3dSmrg int shift_amount;
7791debfc3dSmrg #endif
7801debfc3dSmrg memcpy (&x, &a, FROM_FIXED_SIZE);
7811debfc3dSmrg
7821debfc3dSmrg /* Step 1. We need to store x to {high, low}. */
7831debfc3dSmrg #if FROM_MODE_UNSIGNED == 0
7841debfc3dSmrg low = (BIG_SINT_C_TYPE) x;
7851debfc3dSmrg if (x < 0)
7861debfc3dSmrg high = -1;
7871debfc3dSmrg else
7881debfc3dSmrg high = 0;
7891debfc3dSmrg #else
7901debfc3dSmrg low = (BIG_UINT_C_TYPE) x;
7911debfc3dSmrg high = 0;
7921debfc3dSmrg #endif
7931debfc3dSmrg
7941debfc3dSmrg /* Step 2. We need to shift {high, low}. */
7951debfc3dSmrg #if TO_FBITS > FROM_FBITS /* Left shift. */
7961debfc3dSmrg shift_amount = TO_FBITS - FROM_FBITS;
7971debfc3dSmrg utemp = (BIG_UINT_C_TYPE) low;
7981debfc3dSmrg utemp = utemp >> (BIG_WIDTH - shift_amount);
7991debfc3dSmrg high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
8001debfc3dSmrg low = low << shift_amount;
8011debfc3dSmrg #elif TO_FBITS < FROM_FBITS /* Right shift. */
8021debfc3dSmrg shift_amount = FROM_FBITS - TO_FBITS;
8031debfc3dSmrg low = low >> shift_amount;
8041debfc3dSmrg #endif
8051debfc3dSmrg
8061debfc3dSmrg /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
8071debfc3dSmrg max_high = 0;
8081debfc3dSmrg #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
8091debfc3dSmrg max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
8101debfc3dSmrg max_low = max_low - 1;
8111debfc3dSmrg #else
8121debfc3dSmrg max_low = -1;
8131debfc3dSmrg #endif
8141debfc3dSmrg
8151debfc3dSmrg #if TO_MODE_UNSIGNED == 0
8161debfc3dSmrg stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1);
8171debfc3dSmrg stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS);
8181debfc3dSmrg #if FROM_MODE_UNSIGNED == 0
8191debfc3dSmrg min_high = -1;
8201debfc3dSmrg min_low = stemp;
8211debfc3dSmrg #endif
8221debfc3dSmrg #endif
8231debfc3dSmrg
8241debfc3dSmrg #if FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 0
8251debfc3dSmrg /* Signed -> Signed. */
8261debfc3dSmrg if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
8271debfc3dSmrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
8281debfc3dSmrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
8291debfc3dSmrg low = max_low; /* Maximum. */
8301debfc3dSmrg else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high
8311debfc3dSmrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high
8321debfc3dSmrg && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low))
8331debfc3dSmrg low = min_low; /* Minimum. */
8341debfc3dSmrg #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 1
8351debfc3dSmrg /* Unigned -> Unsigned. */
8361debfc3dSmrg if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
8371debfc3dSmrg || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
8381debfc3dSmrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
8391debfc3dSmrg low = max_low; /* Maximum. */
8401debfc3dSmrg #elif FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 1
8411debfc3dSmrg /* Signed -> Unsigned. */
8421debfc3dSmrg if (x < 0)
8431debfc3dSmrg low = 0; /* Minimum. */
8441debfc3dSmrg else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
8451debfc3dSmrg || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
8461debfc3dSmrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
8471debfc3dSmrg low = max_low; /* Maximum. */
8481debfc3dSmrg #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 0
8491debfc3dSmrg /* Unsigned -> Signed. */
8501debfc3dSmrg if ((BIG_SINT_C_TYPE) high < 0)
8511debfc3dSmrg low = max_low; /* Maximum. */
8521debfc3dSmrg else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
8531debfc3dSmrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
8541debfc3dSmrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
8551debfc3dSmrg low = max_low; /* Maximum. */
8561debfc3dSmrg #endif
8571debfc3dSmrg
8581debfc3dSmrg /* Step 4. Store the result. */
8591debfc3dSmrg z = (TO_INT_C_TYPE) low;
8601debfc3dSmrg #if TO_HAVE_PADDING_BITS
8611debfc3dSmrg z = z << TO_PADDING_BITS;
8621debfc3dSmrg z = z >> TO_PADDING_BITS;
8631debfc3dSmrg #endif
8641debfc3dSmrg memcpy (&c, &z, TO_FIXED_SIZE);
8651debfc3dSmrg return c;
8661debfc3dSmrg }
8671debfc3dSmrg #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4 */
8681debfc3dSmrg
8691debfc3dSmrg /* Fixed -> Int. */
8701debfc3dSmrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1
8711debfc3dSmrg TO_INT_C_TYPE
FRACT(FROM_FIXED_C_TYPE a)8721debfc3dSmrg FRACT (FROM_FIXED_C_TYPE a)
8731debfc3dSmrg {
8741debfc3dSmrg FROM_INT_C_TYPE x;
8751debfc3dSmrg TO_INT_C_TYPE z;
8761debfc3dSmrg FROM_INT_C_TYPE i = 0;
8771debfc3dSmrg memcpy (&x, &a, FROM_FIXED_SIZE);
8781debfc3dSmrg
8791debfc3dSmrg #if FROM_MODE_UNSIGNED == 0
8801debfc3dSmrg if (x < 0)
8811debfc3dSmrg {
8821debfc3dSmrg #if FROM_FIXED_WIDTH == FROM_FBITS
8831debfc3dSmrg if (x != 0)
8841debfc3dSmrg i = 1;
8851debfc3dSmrg #else
8861debfc3dSmrg if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0)
8871debfc3dSmrg i = 1;
8881debfc3dSmrg #endif
8891debfc3dSmrg }
8901debfc3dSmrg #endif
8911debfc3dSmrg
8921debfc3dSmrg #if FROM_FIXED_WIDTH == FROM_FBITS
8931debfc3dSmrg x = 0;
8941debfc3dSmrg #else
8951debfc3dSmrg x = x >> FROM_FBITS;
8961debfc3dSmrg #endif
8971debfc3dSmrg x = x + i;
8981debfc3dSmrg z = (TO_INT_C_TYPE) x;
8991debfc3dSmrg return z;
9001debfc3dSmrg }
9011debfc3dSmrg #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1 */
9021debfc3dSmrg
9031debfc3dSmrg /* Fixed -> Unsigned int. */
9041debfc3dSmrg #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2
9051debfc3dSmrg TO_INT_C_TYPE
FRACTUNS(FROM_FIXED_C_TYPE a)9061debfc3dSmrg FRACTUNS (FROM_FIXED_C_TYPE a)
9071debfc3dSmrg {
9081debfc3dSmrg FROM_INT_C_TYPE x;
9091debfc3dSmrg TO_INT_C_TYPE z;
9101debfc3dSmrg FROM_INT_C_TYPE i = 0;
9111debfc3dSmrg memcpy (&x, &a, FROM_FIXED_SIZE);
9121debfc3dSmrg
9131debfc3dSmrg #if FROM_MODE_UNSIGNED == 0
9141debfc3dSmrg if (x < 0)
9151debfc3dSmrg {
9161debfc3dSmrg #if FROM_FIXED_WIDTH == FROM_FBITS
9171debfc3dSmrg if (x != 0)
9181debfc3dSmrg i = 1;
9191debfc3dSmrg #else
9201debfc3dSmrg if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0)
9211debfc3dSmrg i = 1;
9221debfc3dSmrg #endif
9231debfc3dSmrg }
9241debfc3dSmrg #endif
9251debfc3dSmrg
9261debfc3dSmrg #if FROM_FIXED_WIDTH == FROM_FBITS
9271debfc3dSmrg x = 0;
9281debfc3dSmrg #else
9291debfc3dSmrg x = x >> FROM_FBITS;
9301debfc3dSmrg #endif
9311debfc3dSmrg x = x + i;
9321debfc3dSmrg z = (TO_INT_C_TYPE) x;
9331debfc3dSmrg return z;
9341debfc3dSmrg }
9351debfc3dSmrg #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2 */
9361debfc3dSmrg
9371debfc3dSmrg /* Int -> Fixed. */
9381debfc3dSmrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4
9391debfc3dSmrg TO_FIXED_C_TYPE
FRACT(FROM_INT_C_TYPE a)9401debfc3dSmrg FRACT (FROM_INT_C_TYPE a)
9411debfc3dSmrg {
9421debfc3dSmrg TO_FIXED_C_TYPE c;
9431debfc3dSmrg TO_INT_C_TYPE z;
9441debfc3dSmrg z = (TO_INT_C_TYPE) a;
9451debfc3dSmrg #if TO_FIXED_WIDTH == TO_FBITS
9461debfc3dSmrg z = 0;
9471debfc3dSmrg #else
9481debfc3dSmrg z = z << TO_FBITS;
9491debfc3dSmrg #endif
9501debfc3dSmrg #if TO_HAVE_PADDING_BITS
9511debfc3dSmrg z = z << TO_PADDING_BITS;
9521debfc3dSmrg z = z >> TO_PADDING_BITS;
9531debfc3dSmrg #endif
9541debfc3dSmrg memcpy (&c, &z, TO_FIXED_SIZE);
9551debfc3dSmrg return c;
9561debfc3dSmrg }
9571debfc3dSmrg #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
9581debfc3dSmrg
9591debfc3dSmrg /* Signed int -> Fixed with saturation. */
9601debfc3dSmrg #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 1 && TO_TYPE == 4
9611debfc3dSmrg TO_FIXED_C_TYPE
SATFRACT(FROM_INT_C_TYPE a)9621debfc3dSmrg SATFRACT (FROM_INT_C_TYPE a)
9631debfc3dSmrg {
9641debfc3dSmrg TO_FIXED_C_TYPE c;
9651debfc3dSmrg TO_INT_C_TYPE z;
9661debfc3dSmrg FROM_INT_C_TYPE x = a;
9671debfc3dSmrg BIG_SINT_C_TYPE high, low;
9681debfc3dSmrg BIG_SINT_C_TYPE max_high, max_low;
9691debfc3dSmrg #if TO_MODE_UNSIGNED == 0
9701debfc3dSmrg BIG_SINT_C_TYPE min_high, min_low;
9711debfc3dSmrg BIG_SINT_C_TYPE stemp;
9721debfc3dSmrg #endif
9731debfc3dSmrg #if BIG_WIDTH != TO_FBITS
9741debfc3dSmrg BIG_UINT_C_TYPE utemp;
9751debfc3dSmrg int shift_amount;
9761debfc3dSmrg #endif
9771debfc3dSmrg
9781debfc3dSmrg /* Step 1. We need to store x to {high, low}. */
9791debfc3dSmrg low = (BIG_SINT_C_TYPE) x;
9801debfc3dSmrg if (x < 0)
9811debfc3dSmrg high = -1;
9821debfc3dSmrg else
9831debfc3dSmrg high = 0;
9841debfc3dSmrg
9851debfc3dSmrg /* Step 2. We need to left shift {high, low}. */
9861debfc3dSmrg #if BIG_WIDTH == TO_FBITS
9871debfc3dSmrg high = low;
9881debfc3dSmrg low = 0;
9891debfc3dSmrg #else
9901debfc3dSmrg shift_amount = TO_FBITS;
9911debfc3dSmrg utemp = (BIG_UINT_C_TYPE) low;
9921debfc3dSmrg utemp = utemp >> (BIG_WIDTH - shift_amount);
9931debfc3dSmrg high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
9941debfc3dSmrg low = low << shift_amount;
9951debfc3dSmrg #endif
9961debfc3dSmrg
9971debfc3dSmrg /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
9981debfc3dSmrg max_high = 0;
9991debfc3dSmrg #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
10001debfc3dSmrg max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
10011debfc3dSmrg max_low = max_low - 1;
10021debfc3dSmrg #else
10031debfc3dSmrg max_low = -1;
10041debfc3dSmrg #endif
10051debfc3dSmrg
10061debfc3dSmrg #if TO_MODE_UNSIGNED == 0
10071debfc3dSmrg min_high = -1;
10081debfc3dSmrg stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1);
10091debfc3dSmrg stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS);
10101debfc3dSmrg min_low = stemp;
10111debfc3dSmrg
10121debfc3dSmrg /* Signed -> Signed. */
10131debfc3dSmrg if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
10141debfc3dSmrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
10151debfc3dSmrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
10161debfc3dSmrg low = max_low; /* Maximum. */
10171debfc3dSmrg else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high
10181debfc3dSmrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high
10191debfc3dSmrg && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low))
10201debfc3dSmrg low = min_low; /* Minimum. */
10211debfc3dSmrg #else
10221debfc3dSmrg /* Signed -> Unsigned. */
10231debfc3dSmrg if (x < 0)
10241debfc3dSmrg low = 0; /* Minimum. */
10251debfc3dSmrg else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
10261debfc3dSmrg || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
10271debfc3dSmrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
10281debfc3dSmrg low = max_low; /* Maximum. */
10291debfc3dSmrg #endif
10301debfc3dSmrg
10311debfc3dSmrg /* Step 4. Store the result. */
10321debfc3dSmrg z = (TO_INT_C_TYPE) low;
10331debfc3dSmrg #if TO_HAVE_PADDING_BITS
10341debfc3dSmrg z = z << TO_PADDING_BITS;
10351debfc3dSmrg z = z >> TO_PADDING_BITS;
10361debfc3dSmrg #endif
10371debfc3dSmrg memcpy (&c, &z, TO_FIXED_SIZE);
10381debfc3dSmrg return c;
10391debfc3dSmrg }
10401debfc3dSmrg #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4 */
10411debfc3dSmrg
10421debfc3dSmrg /* Unsigned int -> Fixed. */
10431debfc3dSmrg #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4
10441debfc3dSmrg TO_FIXED_C_TYPE
FRACTUNS(FROM_INT_C_TYPE a)10451debfc3dSmrg FRACTUNS (FROM_INT_C_TYPE a)
10461debfc3dSmrg {
10471debfc3dSmrg TO_FIXED_C_TYPE c;
10481debfc3dSmrg TO_INT_C_TYPE z;
10491debfc3dSmrg z = (TO_INT_C_TYPE) a;
10501debfc3dSmrg #if TO_FIXED_WIDTH == TO_FBITS
10511debfc3dSmrg z = 0;
10521debfc3dSmrg #else
10531debfc3dSmrg z = z << TO_FBITS;
10541debfc3dSmrg #endif
10551debfc3dSmrg #if TO_HAVE_PADDING_BITS
10561debfc3dSmrg z = z << TO_PADDING_BITS;
10571debfc3dSmrg z = z >> TO_PADDING_BITS;
10581debfc3dSmrg #endif
10591debfc3dSmrg memcpy (&c, &z, TO_FIXED_SIZE);
10601debfc3dSmrg return c;
10611debfc3dSmrg }
10621debfc3dSmrg #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
10631debfc3dSmrg
10641debfc3dSmrg /* Unsigned int -> Fixed with saturation. */
10651debfc3dSmrg #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4
10661debfc3dSmrg TO_FIXED_C_TYPE
SATFRACTUNS(FROM_INT_C_TYPE a)10671debfc3dSmrg SATFRACTUNS (FROM_INT_C_TYPE a)
10681debfc3dSmrg {
10691debfc3dSmrg TO_FIXED_C_TYPE c;
10701debfc3dSmrg TO_INT_C_TYPE z;
10711debfc3dSmrg FROM_INT_C_TYPE x = a;
10721debfc3dSmrg BIG_UINT_C_TYPE high, low;
10731debfc3dSmrg BIG_UINT_C_TYPE max_high, max_low;
10741debfc3dSmrg #if BIG_WIDTH != TO_FBITS
10751debfc3dSmrg BIG_UINT_C_TYPE utemp;
10761debfc3dSmrg int shift_amount;
10771debfc3dSmrg #endif
10781debfc3dSmrg
10791debfc3dSmrg /* Step 1. We need to store x to {high, low}. */
10801debfc3dSmrg low = (BIG_UINT_C_TYPE) x;
10811debfc3dSmrg high = 0;
10821debfc3dSmrg
10831debfc3dSmrg /* Step 2. We need to left shift {high, low}. */
10841debfc3dSmrg #if BIG_WIDTH == TO_FBITS
10851debfc3dSmrg high = low;
10861debfc3dSmrg low = 0;
10871debfc3dSmrg #else
10881debfc3dSmrg shift_amount = TO_FBITS;
10891debfc3dSmrg utemp = (BIG_UINT_C_TYPE) low;
10901debfc3dSmrg utemp = utemp >> (BIG_WIDTH - shift_amount);
10911debfc3dSmrg high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
10921debfc3dSmrg low = low << shift_amount;
10931debfc3dSmrg #endif
10941debfc3dSmrg
10951debfc3dSmrg /* Step 3. Compare {high, low} with max and min of TO_FIXED_C_TYPE. */
10961debfc3dSmrg max_high = 0;
10971debfc3dSmrg #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
10981debfc3dSmrg max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
10991debfc3dSmrg max_low = max_low - 1;
11001debfc3dSmrg #else
11011debfc3dSmrg max_low = -1;
11021debfc3dSmrg #endif
11031debfc3dSmrg
11041debfc3dSmrg #if TO_MODE_UNSIGNED == 1
11051debfc3dSmrg /* Unigned -> Unsigned. */
11061debfc3dSmrg if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
11071debfc3dSmrg || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
11081debfc3dSmrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
11091debfc3dSmrg low = max_low; /* Maximum. */
11101debfc3dSmrg #else
11111debfc3dSmrg /* Unsigned -> Signed. */
11121debfc3dSmrg if ((BIG_SINT_C_TYPE) high < 0)
11131debfc3dSmrg low = max_low; /* Maximum. */
11141debfc3dSmrg else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
11151debfc3dSmrg || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
11161debfc3dSmrg && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
11171debfc3dSmrg low = max_low; /* Maximum. */
11181debfc3dSmrg #endif
11191debfc3dSmrg
11201debfc3dSmrg /* Step 4. Store the result. */
11211debfc3dSmrg z = (TO_INT_C_TYPE) low;
11221debfc3dSmrg #if TO_HAVE_PADDING_BITS
11231debfc3dSmrg z = z << TO_PADDING_BITS;
11241debfc3dSmrg z = z >> TO_PADDING_BITS;
11251debfc3dSmrg #endif
11261debfc3dSmrg memcpy (&c, &z, TO_FIXED_SIZE);
11271debfc3dSmrg return c;
11281debfc3dSmrg }
11291debfc3dSmrg #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4 */
11301debfc3dSmrg
11311debfc3dSmrg /* Fixed -> Float. */
11321debfc3dSmrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3
11331debfc3dSmrg TO_FLOAT_C_TYPE
FRACT(FROM_FIXED_C_TYPE a)11341debfc3dSmrg FRACT (FROM_FIXED_C_TYPE a)
11351debfc3dSmrg {
11361debfc3dSmrg FROM_INT_C_TYPE x;
11371debfc3dSmrg TO_FLOAT_C_TYPE z;
11381debfc3dSmrg memcpy (&x, &a, FROM_FIXED_SIZE);
11391debfc3dSmrg z = (TO_FLOAT_C_TYPE) x;
11401debfc3dSmrg z = z / BASE;
11411debfc3dSmrg return z;
11421debfc3dSmrg }
11431debfc3dSmrg #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3 */
11441debfc3dSmrg
11451debfc3dSmrg /* Float -> Fixed. */
11461debfc3dSmrg #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4
11471debfc3dSmrg TO_FIXED_C_TYPE
FRACT(FROM_FLOAT_C_TYPE a)11481debfc3dSmrg FRACT (FROM_FLOAT_C_TYPE a)
11491debfc3dSmrg {
11501debfc3dSmrg FROM_FLOAT_C_TYPE temp;
11511debfc3dSmrg TO_INT_C_TYPE z;
11521debfc3dSmrg TO_FIXED_C_TYPE c;
11531debfc3dSmrg
11541debfc3dSmrg temp = a * BASE;
11551debfc3dSmrg z = (TO_INT_C_TYPE) temp;
11561debfc3dSmrg #if TO_HAVE_PADDING_BITS
11571debfc3dSmrg z = z << TO_PADDING_BITS;
11581debfc3dSmrg z = z >> TO_PADDING_BITS;
11591debfc3dSmrg #endif
11601debfc3dSmrg memcpy (&c, &z, TO_FIXED_SIZE);
11611debfc3dSmrg return c;
11621debfc3dSmrg }
11631debfc3dSmrg #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */
11641debfc3dSmrg
11651debfc3dSmrg /* Float -> Fixed with saturation. */
11661debfc3dSmrg #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4
11671debfc3dSmrg TO_FIXED_C_TYPE
SATFRACT(FROM_FLOAT_C_TYPE a)11681debfc3dSmrg SATFRACT (FROM_FLOAT_C_TYPE a)
11691debfc3dSmrg {
11701debfc3dSmrg FROM_FLOAT_C_TYPE temp;
11711debfc3dSmrg TO_INT_C_TYPE z;
11721debfc3dSmrg TO_FIXED_C_TYPE c;
11731debfc3dSmrg
11741debfc3dSmrg if (a >= FIXED_MAX)
11751debfc3dSmrg {
11761debfc3dSmrg #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
11771debfc3dSmrg z = (TO_INT_C_TYPE)1 << TO_I_F_BITS;
11781debfc3dSmrg z = z - 1;
11791debfc3dSmrg #else
11801debfc3dSmrg z = -1;
11811debfc3dSmrg #endif
11821debfc3dSmrg }
11831debfc3dSmrg else if (a <= FIXED_MIN)
11841debfc3dSmrg {
11851debfc3dSmrg #if TO_MODE_UNSIGNED == 0
11861debfc3dSmrg z = (TO_INT_C_TYPE)1 << TO_I_F_BITS;
11871debfc3dSmrg #else
11881debfc3dSmrg z = 0;
11891debfc3dSmrg #endif
11901debfc3dSmrg }
11911debfc3dSmrg else
11921debfc3dSmrg {
11931debfc3dSmrg temp = a * BASE;
11941debfc3dSmrg z = (TO_INT_C_TYPE) temp;
11951debfc3dSmrg }
11961debfc3dSmrg
11971debfc3dSmrg #if TO_HAVE_PADDING_BITS
11981debfc3dSmrg z = z << TO_PADDING_BITS;
11991debfc3dSmrg z = z >> TO_PADDING_BITS;
12001debfc3dSmrg #endif
12011debfc3dSmrg memcpy (&c, &z, TO_FIXED_SIZE);
12021debfc3dSmrg return c;
12031debfc3dSmrg }
12041debfc3dSmrg #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4 */
12051debfc3dSmrg
1206