xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/fixed-bit.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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