(root)/
gcc-13.2.0/
libgcc/
fixed-bit.c
       1  /* This is a software fixed-point library.
       2     Copyright (C) 2007-2023 Free Software Foundation, Inc.
       3  
       4  This file is part of GCC.
       5  
       6  GCC is free software; you can redistribute it and/or modify it under
       7  the terms of the GNU General Public License as published by the Free
       8  Software Foundation; either version 3, or (at your option) any later
       9  version.
      10  
      11  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12  WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14  for more details.
      15  
      16  Under Section 7 of GPL version 3, you are granted additional
      17  permissions described in the GCC Runtime Library Exception, version
      18  3.1, as published by the Free Software Foundation.
      19  
      20  You should have received a copy of the GNU General Public License and
      21  a copy of the GCC Runtime Library Exception along with this program;
      22  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  <http://www.gnu.org/licenses/>.  */
      24  
      25  /* This implements fixed-point arithmetic.
      26  
      27     Contributed by Chao-ying Fu  <fu@mips.com>.  */
      28  
      29  /* To use this file, we need to define one of the following:
      30     QQ_MODE, UQQ_MODE, HQ_MODE, UHQ_MODE, SQ_MODE, USQ_MODE, DQ_MODE, UDQ_MODE,
      31     TQ_MODE, UTQ_MODE, HA_MODE, UHA_MODE, SA_MODE, USA_MODE, DA_MODE, UDA_MODE,
      32     TA_MODE, UTA_MODE.
      33     Then, all operators for this machine mode will be created.
      34  
      35     Or, we need to define FROM_* TO_* for conversions from one mode to another
      36     mode.  The mode could be one of the following:
      37     Fract: QQ, UQQ, HQ, UHQ, SQ, USQ, DQ, UDQ, TQ, UTQ
      38     Accum: HA, UHA, SA, USA, DA, UDA, TA, UTA
      39     Signed integer: QI, HI, SI, DI, TI
      40     Unsigned integer: UQI, UHI, USI, UDI, UTI
      41     Floating-point: SF, DF
      42     Ex: If we define FROM_QQ and TO_SI, the conversion from QQ to SI is
      43     generated.  */
      44  
      45  #include "tconfig.h"
      46  #include "tsystem.h"
      47  #include "coretypes.h"
      48  #include "tm.h"
      49  #include "libgcc_tm.h"
      50  
      51  #ifndef MIN_UNITS_PER_WORD
      52  #define MIN_UNITS_PER_WORD UNITS_PER_WORD
      53  #endif
      54  
      55  #include "fixed-bit.h"
      56  
      57  #if defined(FIXED_ADD) && defined(L_add)
      58  FIXED_C_TYPE
      59  FIXED_ADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
      60  {
      61    FIXED_C_TYPE c;
      62    INT_C_TYPE x, y, z;
      63    memcpy (&x, &a, FIXED_SIZE);
      64    memcpy (&y, &b, FIXED_SIZE);
      65    z = x + y;
      66  #if HAVE_PADDING_BITS
      67    z = z << PADDING_BITS;
      68    z = z >> PADDING_BITS;
      69  #endif
      70    memcpy (&c, &z, FIXED_SIZE);
      71    return c;
      72  }
      73  #endif /* FIXED_ADD */
      74  
      75  #if defined(FIXED_SSADD) && defined(L_ssadd)
      76  FIXED_C_TYPE
      77  FIXED_SSADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
      78  {
      79    FIXED_C_TYPE c;
      80    INT_C_TYPE x, y, z;
      81    memcpy (&x, &a, FIXED_SIZE);
      82    memcpy (&y, &b, FIXED_SIZE);
      83    z = x + (UINT_C_TYPE) y;
      84    if ((((x ^ y) >> I_F_BITS) & 1) == 0)
      85      {
      86        if (((z ^ x) >> I_F_BITS) & 1)
      87          {
      88  	  z = ((UINT_C_TYPE) 1) << I_F_BITS;
      89  	  if (x >= 0)
      90  	    z -= (UINT_C_TYPE) 1;
      91          }
      92      }
      93  #if HAVE_PADDING_BITS
      94    z = z << PADDING_BITS;
      95    z = z >> PADDING_BITS;
      96  #endif
      97    memcpy (&c, &z, FIXED_SIZE);
      98    return c;
      99  }
     100  #endif /* FIXED_SSADD */
     101  
     102  #if defined(FIXED_USADD) && defined(L_usadd)
     103  FIXED_C_TYPE
     104  FIXED_USADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
     105  {
     106    FIXED_C_TYPE c;
     107    INT_C_TYPE x, y, z;
     108    memcpy (&x, &a, FIXED_SIZE);
     109    memcpy (&y, &b, FIXED_SIZE);
     110    z = x + y;
     111  #if HAVE_PADDING_BITS
     112    z = z << PADDING_BITS;
     113    z = z >> PADDING_BITS;
     114  #endif
     115    if (z < x || z < y) /* max */
     116      {
     117         z = -1;
     118  #if HAVE_PADDING_BITS
     119         z = z << PADDING_BITS;
     120         z = z >> PADDING_BITS;
     121  #endif
     122      }
     123    memcpy (&c, &z, FIXED_SIZE);
     124    return c;
     125  }
     126  #endif /* FIXED_USADD */
     127  
     128  #if defined(FIXED_SUB) && defined(L_sub)
     129  FIXED_C_TYPE
     130  FIXED_SUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
     131  {
     132    FIXED_C_TYPE c;
     133    INT_C_TYPE x, y, z;
     134    memcpy (&x, &a, FIXED_SIZE);
     135    memcpy (&y, &b, FIXED_SIZE);
     136    z = x - y;
     137  #if HAVE_PADDING_BITS
     138    z = z << PADDING_BITS;
     139    z = z >> PADDING_BITS;
     140  #endif
     141    memcpy (&c, &z, FIXED_SIZE);
     142    return c;
     143  }
     144  #endif /* FIXED_SUB */
     145  
     146  #if defined(FIXED_SSSUB) && defined(L_sssub)
     147  FIXED_C_TYPE
     148  FIXED_SSSUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
     149  {
     150    FIXED_C_TYPE c;
     151    INT_C_TYPE x, y, z;
     152    memcpy (&x, &a, FIXED_SIZE);
     153    memcpy (&y, &b, FIXED_SIZE);
     154    z = x - (UINT_C_TYPE) y;
     155    if (((x ^ y) >> I_F_BITS) & 1)
     156      {
     157        if (((z ^ x) >> I_F_BITS) & 1)
     158          {
     159  	  z = ((UINT_C_TYPE) 1) << I_F_BITS;
     160  	  if (x >= 0)
     161  	    z -= (UINT_C_TYPE) 1;
     162          }
     163      }
     164  #if HAVE_PADDING_BITS
     165    z = z << PADDING_BITS;
     166    z = z >> PADDING_BITS;
     167  #endif
     168    memcpy (&c, &z, FIXED_SIZE);
     169    return c;
     170  }
     171  #endif /* FIXED_SSSUB */
     172  
     173  #if defined(FIXED_USSUB) && defined(L_ussub)
     174  FIXED_C_TYPE
     175  FIXED_USSUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
     176  {
     177    FIXED_C_TYPE c;
     178    INT_C_TYPE x, y, z;
     179    memcpy (&x, &a, FIXED_SIZE);
     180    memcpy (&y, &b, FIXED_SIZE);
     181    z = x - y;
     182    if (x < y)
     183      z = 0;
     184  #if HAVE_PADDING_BITS
     185    z = z << PADDING_BITS;
     186    z = z >> PADDING_BITS;
     187  #endif
     188    memcpy (&c, &z, FIXED_SIZE);
     189    return c;
     190  }
     191  #endif /* FIXED_USSUB */
     192  
     193  #if defined(FIXED_SATURATE1) && defined(L_saturate1)
     194  void
     195  FIXED_SATURATE1 (DINT_C_TYPE *a)
     196  {
     197    DINT_C_TYPE max, min;
     198    max = (DINT_C_TYPE)1 << I_F_BITS;
     199    max = max - 1;
     200  #if MODE_UNSIGNED == 0
     201    min = (DINT_C_TYPE)1 << (2 * FIXED_WIDTH - 1);
     202    min = min >> (2 * FIXED_WIDTH - 1 - I_F_BITS);
     203  #else
     204    min = 0;
     205  #endif
     206    if (*a > max)
     207      *a = max;
     208    else if (*a < min)
     209      *a = min;
     210  }
     211  #endif /* FIXED_SATURATE1 */
     212  
     213  #if defined(FIXED_SATURATE2) && defined(L_saturate2)
     214  void
     215  FIXED_SATURATE2 (INT_C_TYPE *high, INT_C_TYPE *low)
     216  {
     217    INT_C_TYPE r_max, s_max, r_min, s_min;
     218    r_max = 0;
     219  #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS
     220    s_max = (INT_C_TYPE)1 << I_F_BITS;
     221    s_max = s_max - 1;
     222  #else
     223    s_max = -1;
     224  #endif
     225  #if MODE_UNSIGNED == 0
     226    r_min = -1;
     227    s_min = (INT_C_TYPE)1 << (FIXED_WIDTH - 1);
     228    s_min = s_min >> (FIXED_WIDTH - 1 - I_F_BITS);
     229  #else
     230    r_min = 0;
     231    s_min = 0;
     232  #endif
     233  
     234    if (*high > r_max
     235        || (*high == r_max && (UINT_C_TYPE)(*low) > (UINT_C_TYPE)s_max))
     236      {
     237        *high = r_max;
     238        *low = s_max;
     239      }
     240    else if (*high < r_min ||
     241  	   (*high == r_min && (UINT_C_TYPE)(*low) < (UINT_C_TYPE)s_min))
     242      {
     243        *high = r_min;
     244        *low = s_min;
     245      }
     246  }
     247  #endif /* FIXED_SATURATE2 */
     248  
     249  #if defined(FIXED_MULHELPER) && defined(L_mulhelper)
     250  FIXED_C_TYPE
     251  FIXED_MULHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp)
     252  {
     253    FIXED_C_TYPE c;
     254    INT_C_TYPE x, y;
     255  
     256  #if defined (DINT_C_TYPE)
     257    INT_C_TYPE z;
     258    DINT_C_TYPE dx, dy, dz;
     259    memcpy (&x, &a, FIXED_SIZE);
     260    memcpy (&y, &b, FIXED_SIZE);
     261    dx = (DINT_C_TYPE) x;
     262    dy = (DINT_C_TYPE) y;
     263    dz = dx * dy;
     264    /* Round the result by adding (1 << (FBITS -1)).  */
     265    dz += ((DINT_C_TYPE) 1 << (FBITS - 1));
     266    dz = dz >> FBITS;
     267    if (satp)
     268      FIXED_SATURATE1 (&dz);
     269  
     270    z = (INT_C_TYPE) dz;
     271  #if HAVE_PADDING_BITS
     272    z = z << PADDING_BITS;
     273    z = z >> PADDING_BITS;
     274  #endif
     275    memcpy (&c, &z, FIXED_SIZE);
     276    return c;
     277  
     278  #else /* No DINT_C_TYPE */
     279    /* The result of multiplication expands to two INT_C_TYPE.  */
     280    INTunion aa, bb;
     281    INTunion a_high, a_low, b_high, b_low;
     282    INTunion high_high, high_low, low_high, low_low;
     283    INTunion r, s, temp1, temp2;
     284    INT_C_TYPE carry = 0;
     285    INT_C_TYPE z;
     286  
     287    memcpy (&x, &a, FIXED_SIZE);
     288    memcpy (&y, &b, FIXED_SIZE);
     289  
     290    /* Decompose a and b.  */
     291    aa.ll = x;
     292    bb.ll = y;
     293  
     294    a_high.s.low = aa.s.high;
     295    a_high.s.high = 0;
     296    a_low.s.low = aa.s.low;
     297    a_low.s.high = 0;
     298    b_high.s.low = bb.s.high;
     299    b_high.s.high = 0;
     300    b_low.s.low = bb.s.low;
     301    b_low.s.high = 0;
     302  
     303    /* Perform four multiplications.  */
     304    low_low.ll = a_low.ll * b_low.ll;
     305    low_high.ll = a_low.ll * b_high.ll;
     306    high_low.ll = a_high.ll * b_low.ll;
     307    high_high.ll = a_high.ll * b_high.ll;
     308  
     309    /* Accumulate four results to {r, s}.  */
     310    temp1.s.high = high_low.s.low;
     311    temp1.s.low = 0;
     312    s.ll = low_low.ll + temp1.ll;
     313    if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) low_low.ll
     314        || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll)
     315      carry ++; /* Carry.  */
     316    temp1.ll = s.ll;
     317    temp2.s.high = low_high.s.low;
     318    temp2.s.low = 0;
     319    s.ll = temp1.ll + temp2.ll;
     320    if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll
     321        || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp2.ll)
     322      carry ++; /* Carry.  */
     323  
     324    temp1.s.low = high_low.s.high;
     325    temp1.s.high = 0;
     326    r.ll = high_high.ll + temp1.ll;
     327    temp1.s.low = low_high.s.high;
     328    temp1.s.high = 0;
     329    r.ll = r.ll + temp1.ll + carry;
     330  
     331  #if MODE_UNSIGNED == 0
     332    /* For signed types, we need to add neg(y) to r, if x < 0.  */
     333    if (x < 0)
     334      r.ll = r.ll - y;
     335    /* We need to add neg(x) to r, if y < 0.  */
     336    if (y < 0)
     337      r.ll = r.ll - x;
     338  #endif
     339  
     340    /* Round the result by adding (1 << (FBITS -1)).  */
     341    temp1.ll = s.ll;
     342    s.ll += ((INT_C_TYPE) 1 << (FBITS -1));
     343    if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll
     344        || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) ((INT_C_TYPE) 1 << (FBITS -1)))
     345      r.ll += 1;
     346  
     347    /* Shift right the result by FBITS.  */
     348  #if FBITS == FIXED_WIDTH
     349    /* This happens only for unsigned types without any padding bits.
     350       So, it is safe to set r.ll to 0 as it is logically shifted right.  */
     351    s.ll = r.ll;
     352    r.ll = 0;
     353  #else
     354    s.ll = ((UINT_C_TYPE)s.ll) >> FBITS;
     355    temp1.ll = r.ll << (FIXED_WIDTH - FBITS);
     356    s.ll = s.ll | temp1.ll;
     357    r.ll = r.ll >> FBITS;
     358  #endif
     359  
     360    if (satp)
     361      FIXED_SATURATE2 (&r.ll, &s.ll);
     362  
     363    z = (INT_C_TYPE) s.ll;
     364  #if HAVE_PADDING_BITS
     365    z = z << PADDING_BITS;
     366    z = z >> PADDING_BITS;
     367  #endif
     368    memcpy (&c, &z, FIXED_SIZE);
     369    return c;
     370  #endif
     371  }
     372  #endif /* FIXED_MULHELPER */
     373  
     374  #if defined(FIXED_MUL) && defined(L_mul)
     375  FIXED_C_TYPE
     376  FIXED_MUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
     377  {
     378    return FIXED_MULHELPER (a, b, 0);
     379  }
     380  #endif /* FIXED_MUL */
     381  
     382  #if defined(FIXED_SSMUL) && defined(L_ssmul)
     383  FIXED_C_TYPE
     384  FIXED_SSMUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
     385  {
     386    return FIXED_MULHELPER (a, b, 1);
     387  }
     388  #endif /* FIXED_SSMUL */
     389  
     390  #if defined(FIXED_USMUL) && defined(L_usmul)
     391  FIXED_C_TYPE
     392  FIXED_USMUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
     393  {
     394    return FIXED_MULHELPER (a, b, 1);
     395  }
     396  #endif /* FIXED_USMUL */
     397  
     398  #if defined(FIXED_DIVHELPER) && defined(L_divhelper)
     399  FIXED_C_TYPE
     400  FIXED_DIVHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp)
     401  {
     402    FIXED_C_TYPE c;
     403    INT_C_TYPE x, y;
     404    INT_C_TYPE z;
     405  
     406  #if defined (DINT_C_TYPE)
     407    DINT_C_TYPE dx, dy, dz;
     408    memcpy (&x, &a, FIXED_SIZE);
     409    memcpy (&y, &b, FIXED_SIZE);
     410    dx = (DINT_C_TYPE) x;
     411    dy = (DINT_C_TYPE) y;
     412    dx = dx << FBITS;
     413    dz = dx / dy;
     414    if (satp)
     415      FIXED_SATURATE1 (&dz);
     416    z = (INT_C_TYPE) dz;
     417  #if HAVE_PADDING_BITS
     418    z = z << PADDING_BITS;
     419    z = z >> PADDING_BITS;
     420  #endif
     421    memcpy (&c, &z, FIXED_SIZE);
     422    return c;
     423  
     424  #else /* No DINT_C_TYPE */
     425    INT_C_TYPE pos_a, pos_b, r, s;
     426    INT_C_TYPE quo_r, quo_s, mod, temp;
     427    word_type i;
     428  #if MODE_UNSIGNED == 0
     429    word_type num_of_neg = 0;
     430  #endif
     431  
     432    memcpy (&x, &a, FIXED_SIZE);
     433    memcpy (&y, &b, FIXED_SIZE);
     434    pos_a = x;
     435    pos_b = y;
     436  
     437  #if MODE_UNSIGNED == 0
     438    /* If a < 0, negate a.  */
     439    if (pos_a < 0)
     440      {
     441        pos_a = -pos_a;
     442        num_of_neg ++;
     443      }
     444    /* If b < 0, negate b.  */
     445    if (pos_b < 0)
     446      {
     447        pos_b = -pos_b;
     448        num_of_neg ++;
     449      }
     450  #endif
     451  
     452    /* Left shift pos_a to {r, s} by FBITS.  */
     453  #if FBITS == FIXED_WIDTH
     454    /* This happens only for unsigned types without any padding bits.  */
     455    r = pos_a;
     456    s = 0;
     457  #else
     458    s = pos_a << FBITS;
     459    r = pos_a >> (FIXED_WIDTH - FBITS);
     460  #endif
     461  
     462    /* Unsigned divide r by pos_b to quo_r.  The remainder is in mod.  */
     463    quo_r = (UINT_C_TYPE)r / (UINT_C_TYPE)pos_b;
     464    mod = (UINT_C_TYPE)r % (UINT_C_TYPE)pos_b;
     465    quo_s = 0;
     466  
     467    for (i = 0; i < FIXED_WIDTH; i++)
     468      {
     469        /* Record the leftmost bit of mod.  */
     470        word_type leftmost_mode = (mod >> (FIXED_WIDTH - 1)) & 1;
     471        /* Shift left mod by 1 bit.  */
     472        mod = mod << 1;
     473        /* Test the leftmost bit of s to add to mod.  */
     474        if ((s >> (FIXED_WIDTH - 1)) & 1)
     475  	mod ++;
     476        /* Shift left quo_s by 1 bit.  */
     477        quo_s = quo_s << 1;
     478        /* Try to calculate (mod - pos_b).  */
     479        temp = mod - pos_b;
     480        if (leftmost_mode || (UINT_C_TYPE)mod >= (UINT_C_TYPE)pos_b)
     481  	{
     482  	  quo_s ++;
     483  	  mod = temp;
     484  	}
     485        /* Shift left s by 1 bit.  */
     486        s = s << 1;
     487      }
     488  
     489  #if MODE_UNSIGNED == 0
     490      if (num_of_neg == 1)
     491        {
     492  	quo_s = -quo_s;
     493  	if (quo_s == 0)
     494  	  quo_r = -quo_r;
     495  	else
     496  	  quo_r = ~quo_r;
     497        }
     498  #endif
     499    if (satp)
     500      FIXED_SATURATE2 (&quo_r, &quo_s);
     501    z = quo_s;
     502  #if HAVE_PADDING_BITS
     503    z = z << PADDING_BITS;
     504    z = z >> PADDING_BITS;
     505  #endif
     506    memcpy (&c, &z, FIXED_SIZE);
     507    return c;
     508  #endif
     509  }
     510  #endif /* FIXED_DIVHELPER */
     511  
     512  #if defined(FIXED_DIV) && defined(L_div)
     513  FIXED_C_TYPE
     514  FIXED_DIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
     515  {
     516    return FIXED_DIVHELPER (a, b, 0);
     517  }
     518  #endif /* FIXED_DIV */
     519  
     520  
     521  #if defined(FIXED_UDIV) && defined(L_udiv)
     522  FIXED_C_TYPE
     523  FIXED_UDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
     524  {
     525    return FIXED_DIVHELPER (a, b, 0);
     526  }
     527  #endif /* FIXED_UDIV */
     528  
     529  #if defined(FIXED_SSDIV) && defined(L_ssdiv)
     530  FIXED_C_TYPE
     531  FIXED_SSDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
     532  {
     533    return FIXED_DIVHELPER (a, b, 1);
     534  }
     535  #endif /* FIXED_SSDIV */
     536  
     537  #if defined(FIXED_USDIV) && defined(L_usdiv)
     538  FIXED_C_TYPE
     539  FIXED_USDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
     540  {
     541    return FIXED_DIVHELPER (a, b, 1);
     542  }
     543  #endif /* FIXED_USDIV */
     544  
     545  #if defined(FIXED_NEG) && defined(L_neg)
     546  FIXED_C_TYPE
     547  FIXED_NEG (FIXED_C_TYPE a)
     548  {
     549    FIXED_C_TYPE c;
     550    INT_C_TYPE x, z;
     551    memcpy (&x, &a, FIXED_SIZE);
     552    z = -x;
     553  #if HAVE_PADDING_BITS
     554    z = z << PADDING_BITS;
     555    z = z >> PADDING_BITS;
     556  #endif
     557    memcpy (&c, &z, FIXED_SIZE);
     558    return c;
     559  }
     560  #endif /* FIXED_NEG */
     561  
     562  #if defined(FIXED_SSNEG) && defined(L_ssneg)
     563  FIXED_C_TYPE
     564  FIXED_SSNEG (FIXED_C_TYPE a)
     565  {
     566    FIXED_C_TYPE c;
     567    INT_C_TYPE x, y, z;
     568    memcpy (&y, &a, FIXED_SIZE);
     569    x = 0;
     570    z = x - (UINT_C_TYPE) y;
     571    if (((x ^ y) >> I_F_BITS) & 1)
     572      {
     573        if (((z ^ x) >> I_F_BITS) & 1)
     574  	z = (((UINT_C_TYPE) 1) << I_F_BITS) - 1;
     575      }
     576  #if HAVE_PADDING_BITS
     577    z = z << PADDING_BITS;
     578    z = z >> PADDING_BITS;
     579  #endif
     580    memcpy (&c, &z, FIXED_SIZE);
     581    return c;
     582  }
     583  #endif /* FIXED_SSNEG */
     584  
     585  #if defined(FIXED_USNEG) && defined(L_usneg)
     586  FIXED_C_TYPE
     587  FIXED_USNEG (FIXED_C_TYPE a __attribute__ ((__unused__)))
     588  {
     589    FIXED_C_TYPE c;
     590    INT_C_TYPE z;
     591    z = 0;
     592    memcpy (&c, &z, FIXED_SIZE);
     593    return c;
     594  }
     595  #endif /* FIXED_USNEG */
     596  
     597  #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper)
     598  FIXED_C_TYPE
     599  FIXED_ASHLHELPER (FIXED_C_TYPE a, word_type b, word_type satp)
     600  {
     601    FIXED_C_TYPE c;
     602    INT_C_TYPE x, z;
     603  
     604  #if defined (DINT_C_TYPE)
     605    DINT_C_TYPE dx, dz;
     606    memcpy (&x, &a, FIXED_SIZE);
     607    dx = (DINT_C_TYPE) x;
     608    if (b >= FIXED_WIDTH)
     609      dz = dx << FIXED_WIDTH;
     610    else
     611      dz = dx << b;
     612    if (satp)
     613      FIXED_SATURATE1 (&dz);
     614    z = (INT_C_TYPE) dz;
     615  #if HAVE_PADDING_BITS
     616    z = z << PADDING_BITS;
     617    z = z >> PADDING_BITS;
     618  #endif
     619    memcpy (&c, &z, FIXED_SIZE);
     620    return c;
     621  
     622  #else /* No DINT_C_TYPE */
     623    INT_C_TYPE r, s;
     624    memcpy (&x, &a, FIXED_SIZE);
     625    /* We need to shift left x by b bits to {r, s}.  */
     626    if (b >= FIXED_WIDTH)
     627      {
     628        r = b;
     629        s = 0;
     630      }
     631    else
     632      {
     633        s = x << b;
     634        r = x >> (FIXED_WIDTH - b);
     635      }
     636    if (satp)
     637      FIXED_SATURATE2 (&r, &s);
     638    z = s;
     639  #if HAVE_PADDING_BITS
     640    z = z << PADDING_BITS;
     641    z = z >> PADDING_BITS;
     642  #endif
     643    memcpy (&c, &z, FIXED_SIZE);
     644    return c;
     645  #endif
     646  }
     647  #endif /* FIXED_ASHLHELPER */
     648  
     649  #if defined(FIXED_ASHL) && defined(L_ashl)
     650  FIXED_C_TYPE
     651  FIXED_ASHL (FIXED_C_TYPE a, word_type b)
     652  {
     653    return FIXED_ASHLHELPER (a, b, 0);
     654  }
     655  #endif /* FIXED_ASHL */
     656  
     657  #if defined(FIXED_ASHR) && defined(L_ashr)
     658  FIXED_C_TYPE
     659  FIXED_ASHR (FIXED_C_TYPE a, word_type b)
     660  {
     661    FIXED_C_TYPE c;
     662    INT_C_TYPE x, z;
     663    memcpy (&x, &a, FIXED_SIZE);
     664    z = x >> b;
     665  #if HAVE_PADDING_BITS
     666    z = z << PADDING_BITS;
     667    z = z >> PADDING_BITS;
     668  #endif
     669    memcpy (&c, &z, FIXED_SIZE);
     670    return c;
     671  }
     672  #endif /* FIXED_ASHR */
     673  
     674  #if defined(FIXED_LSHR) && defined(L_lshr)
     675  FIXED_C_TYPE
     676  FIXED_LSHR (FIXED_C_TYPE a, word_type b)
     677  {
     678    FIXED_C_TYPE c;
     679    INT_C_TYPE x, z;
     680    memcpy (&x, &a, FIXED_SIZE);
     681    z = x >> b;
     682  #if HAVE_PADDING_BITS
     683    z = z << PADDING_BITS;
     684    z = z >> PADDING_BITS;
     685  #endif
     686    memcpy (&c, &z, FIXED_SIZE);
     687    return c;
     688  }
     689  #endif /* FIXED_LSHR */
     690  
     691  #if defined(FIXED_SSASHL) && defined(L_ssashl)
     692  FIXED_C_TYPE
     693  FIXED_SSASHL (FIXED_C_TYPE a, word_type b)
     694  {
     695    return FIXED_ASHLHELPER (a, b, 1);
     696  }
     697  #endif /* FIXED_SSASHL */
     698  
     699  #if defined(FIXED_USASHL) && defined(L_usashl)
     700  FIXED_C_TYPE
     701  FIXED_USASHL (FIXED_C_TYPE a, word_type b)
     702  {
     703    return FIXED_ASHLHELPER (a, b, 1);
     704  }
     705  #endif /* FIXED_USASHL */
     706  
     707  #if defined(FIXED_CMP) && defined(L_cmp)
     708  word_type
     709  FIXED_CMP (FIXED_C_TYPE a, FIXED_C_TYPE b)
     710  {
     711    INT_C_TYPE x, y;
     712    memcpy (&x, &a, FIXED_SIZE);
     713    memcpy (&y, &b, FIXED_SIZE);
     714  
     715    if (x < y)
     716      return 0;
     717    else if (x > y)
     718      return 2;
     719  
     720    return 1;
     721  }
     722  #endif /* FIXED_CMP */
     723  
     724  /* Fixed -> Fixed.  */
     725  #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4
     726  TO_FIXED_C_TYPE
     727  FRACT (FROM_FIXED_C_TYPE a)
     728  {
     729    TO_FIXED_C_TYPE c;
     730    FROM_INT_C_TYPE x;
     731    TO_INT_C_TYPE z;
     732    int shift_amount;
     733    memcpy (&x, &a, FROM_FIXED_SIZE);
     734  #if TO_FBITS > FROM_FBITS  /* Need left shift.  */
     735    shift_amount = TO_FBITS - FROM_FBITS;
     736    z = (TO_INT_C_TYPE) x;
     737    z = z << shift_amount;
     738  #else /* TO_FBITS <= FROM_FBITS.  Need right Shift.  */
     739    shift_amount = FROM_FBITS - TO_FBITS;
     740    x = x >> shift_amount;
     741    z = (TO_INT_C_TYPE) x;
     742  #endif /* TO_FBITS > FROM_FBITS  */
     743  
     744  #if TO_HAVE_PADDING_BITS
     745    z = z << TO_PADDING_BITS;
     746    z = z >> TO_PADDING_BITS;
     747  #endif
     748    memcpy (&c, &z, TO_FIXED_SIZE);
     749    return c;
     750  }
     751  #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4  */
     752  
     753  /* Fixed -> Fixed with saturation.  */
     754  #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4
     755  TO_FIXED_C_TYPE
     756  SATFRACT (FROM_FIXED_C_TYPE a)
     757  {
     758    TO_FIXED_C_TYPE c;
     759    TO_INT_C_TYPE z;
     760    FROM_INT_C_TYPE x;
     761  #if FROM_MODE_UNSIGNED == 0
     762    BIG_SINT_C_TYPE high, low;
     763    BIG_SINT_C_TYPE max_high, max_low;
     764  #if TO_MODE_UNSIGNED == 0
     765    BIG_SINT_C_TYPE min_high, min_low;
     766  #endif
     767  #else
     768    BIG_UINT_C_TYPE high, low;
     769    BIG_UINT_C_TYPE max_high, max_low;
     770  #endif
     771  #if TO_FBITS > FROM_FBITS
     772    BIG_UINT_C_TYPE utemp;
     773  #endif
     774  #if TO_MODE_UNSIGNED == 0
     775    BIG_SINT_C_TYPE stemp;
     776  #endif
     777  #if TO_FBITS != FROM_FBITS
     778    int shift_amount;
     779  #endif
     780    memcpy (&x, &a, FROM_FIXED_SIZE);
     781  
     782    /* Step 1. We need to store x to {high, low}.  */
     783  #if FROM_MODE_UNSIGNED == 0
     784    low = (BIG_SINT_C_TYPE) x;
     785    if (x < 0)
     786      high = -1;
     787    else
     788      high = 0;
     789  #else
     790    low = (BIG_UINT_C_TYPE) x;
     791    high = 0;
     792  #endif
     793  
     794    /* Step 2. We need to shift {high, low}.  */
     795  #if TO_FBITS > FROM_FBITS /* Left shift.  */
     796    shift_amount = TO_FBITS - FROM_FBITS;
     797    utemp = (BIG_UINT_C_TYPE) low;
     798    utemp = utemp >> (BIG_WIDTH - shift_amount);
     799    high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
     800    low = low << shift_amount;
     801  #elif TO_FBITS < FROM_FBITS /* Right shift.  */
     802    shift_amount = FROM_FBITS - TO_FBITS;
     803    low = low >> shift_amount;
     804  #endif
     805  
     806    /* Step 3. Compare {high, low} with max and  min of TO_FIXED_C_TYPE.  */
     807    max_high = 0;
     808  #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
     809    max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
     810    max_low = max_low - 1;
     811  #else
     812    max_low = -1;
     813  #endif
     814  
     815  #if TO_MODE_UNSIGNED == 0
     816    stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1);
     817    stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS);
     818  #if FROM_MODE_UNSIGNED == 0
     819    min_high = -1;
     820    min_low = stemp;
     821  #endif
     822  #endif
     823  
     824  #if FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 0
     825    /* Signed -> Signed.  */
     826    if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
     827        || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
     828  	  && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
     829      low = max_low; /* Maximum.  */
     830    else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high
     831  	   || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high
     832  	       && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low))
     833      low = min_low; /* Minimum.  */
     834  #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 1
     835    /* Unigned -> Unsigned.  */
     836    if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
     837        || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
     838  	  && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
     839      low = max_low; /* Maximum.  */
     840  #elif FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 1
     841    /* Signed -> Unsigned.  */
     842    if (x < 0)
     843      low = 0; /* Minimum.  */
     844    else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
     845  	   || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
     846  	       && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
     847      low = max_low; /* Maximum.  */
     848  #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 0
     849    /* Unsigned -> Signed.  */
     850    if ((BIG_SINT_C_TYPE) high < 0)
     851      low = max_low; /* Maximum.  */
     852    else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
     853  	   || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
     854  	       && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
     855      low = max_low; /* Maximum.  */
     856  #endif
     857  
     858    /* Step 4. Store the result.  */
     859    z = (TO_INT_C_TYPE) low;
     860  #if TO_HAVE_PADDING_BITS
     861    z = z << TO_PADDING_BITS;
     862    z = z >> TO_PADDING_BITS;
     863  #endif
     864    memcpy (&c, &z, TO_FIXED_SIZE);
     865    return c;
     866  }
     867  #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4  */
     868  
     869  /* Fixed -> Int.  */
     870  #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1
     871  TO_INT_C_TYPE
     872  FRACT (FROM_FIXED_C_TYPE a)
     873  {
     874    FROM_INT_C_TYPE x;
     875    TO_INT_C_TYPE z;
     876    FROM_INT_C_TYPE i = 0;
     877    memcpy (&x, &a, FROM_FIXED_SIZE);
     878  
     879  #if FROM_MODE_UNSIGNED == 0
     880    if (x < 0)
     881      {
     882  #if FROM_FIXED_WIDTH == FROM_FBITS
     883        if (x != 0)
     884  	i = 1;
     885  #else
     886        if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0)
     887  	i = 1;
     888  #endif
     889      }
     890  #endif
     891  
     892  #if FROM_FIXED_WIDTH == FROM_FBITS
     893    x = 0;
     894  #else
     895    x = x >> FROM_FBITS;
     896  #endif
     897    x = x + i;
     898    z = (TO_INT_C_TYPE) x;
     899    return z;
     900  }
     901  #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1  */
     902  
     903  /* Fixed -> Unsigned int.  */
     904  #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2
     905  TO_INT_C_TYPE
     906  FRACTUNS (FROM_FIXED_C_TYPE a)
     907  {
     908    FROM_INT_C_TYPE x;
     909    TO_INT_C_TYPE z;
     910    FROM_INT_C_TYPE i = 0;
     911    memcpy (&x, &a, FROM_FIXED_SIZE);
     912  
     913  #if FROM_MODE_UNSIGNED == 0
     914    if (x < 0)
     915      {
     916  #if FROM_FIXED_WIDTH == FROM_FBITS
     917        if (x != 0)
     918  	i = 1;
     919  #else
     920        if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0)
     921  	i = 1;
     922  #endif
     923      }
     924  #endif
     925  
     926  #if FROM_FIXED_WIDTH == FROM_FBITS
     927    x = 0;
     928  #else
     929    x = x >> FROM_FBITS;
     930  #endif
     931    x = x + i;
     932    z = (TO_INT_C_TYPE) x;
     933    return z;
     934  }
     935  #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2  */
     936  
     937  /* Int -> Fixed.  */
     938  #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4
     939  TO_FIXED_C_TYPE
     940  FRACT (FROM_INT_C_TYPE a)
     941  {
     942    TO_FIXED_C_TYPE c;
     943    TO_INT_C_TYPE z;
     944    z = (TO_INT_C_TYPE) a;
     945  #if TO_FIXED_WIDTH == TO_FBITS
     946    z = 0;
     947  #else
     948    z = z << TO_FBITS;
     949  #endif
     950  #if TO_HAVE_PADDING_BITS
     951    z = z << TO_PADDING_BITS;
     952    z = z >> TO_PADDING_BITS;
     953  #endif
     954    memcpy (&c, &z, TO_FIXED_SIZE);
     955    return c;
     956  }
     957  #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4  */
     958  
     959  /* Signed int -> Fixed with saturation.  */
     960  #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 1 && TO_TYPE == 4
     961  TO_FIXED_C_TYPE
     962  SATFRACT (FROM_INT_C_TYPE a)
     963  {
     964    TO_FIXED_C_TYPE c;
     965    TO_INT_C_TYPE z;
     966    FROM_INT_C_TYPE x = a;
     967    BIG_SINT_C_TYPE high, low;
     968    BIG_SINT_C_TYPE max_high, max_low;
     969  #if TO_MODE_UNSIGNED == 0
     970    BIG_SINT_C_TYPE min_high, min_low;
     971    BIG_SINT_C_TYPE stemp;
     972  #endif
     973  #if BIG_WIDTH != TO_FBITS
     974    BIG_UINT_C_TYPE utemp;
     975    int shift_amount;
     976  #endif
     977  
     978    /* Step 1. We need to store x to {high, low}.  */
     979    low = (BIG_SINT_C_TYPE) x;
     980    if (x < 0)
     981      high = -1;
     982    else
     983      high = 0;
     984  
     985    /* Step 2. We need to left shift {high, low}.  */
     986  #if BIG_WIDTH == TO_FBITS
     987    high = low;
     988    low = 0;
     989  #else
     990    shift_amount = TO_FBITS;
     991    utemp = (BIG_UINT_C_TYPE) low;
     992    utemp = utemp >> (BIG_WIDTH - shift_amount);
     993    high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
     994    low = low << shift_amount;
     995  #endif
     996  
     997    /* Step 3. Compare {high, low} with max and  min of TO_FIXED_C_TYPE.  */
     998    max_high = 0;
     999  #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
    1000    max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
    1001    max_low = max_low - 1;
    1002  #else
    1003    max_low = -1;
    1004  #endif
    1005  
    1006  #if TO_MODE_UNSIGNED == 0
    1007    min_high = -1;
    1008    stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1);
    1009    stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS);
    1010    min_low = stemp;
    1011  
    1012    /* Signed -> Signed.  */
    1013    if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
    1014        || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
    1015            && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
    1016      low = max_low; /* Maximum.  */
    1017    else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high
    1018             || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high
    1019                 && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low))
    1020      low = min_low; /* Minimum.  */
    1021  #else
    1022    /* Signed -> Unsigned.  */
    1023    if (x < 0)
    1024      low = 0; /* Minimum.  */
    1025    else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
    1026             || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
    1027                 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
    1028      low = max_low; /* Maximum.  */
    1029  #endif
    1030  
    1031    /* Step 4. Store the result.  */
    1032    z = (TO_INT_C_TYPE) low;
    1033  #if TO_HAVE_PADDING_BITS
    1034    z = z << TO_PADDING_BITS;
    1035    z = z >> TO_PADDING_BITS;
    1036  #endif
    1037    memcpy (&c, &z, TO_FIXED_SIZE);
    1038    return c;
    1039  }
    1040  #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4  */
    1041  
    1042  /* Unsigned int -> Fixed.  */
    1043  #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4
    1044  TO_FIXED_C_TYPE
    1045  FRACTUNS (FROM_INT_C_TYPE a)
    1046  {
    1047    TO_FIXED_C_TYPE c;
    1048    TO_INT_C_TYPE z;
    1049    z = (TO_INT_C_TYPE) a;
    1050  #if TO_FIXED_WIDTH == TO_FBITS
    1051    z = 0;
    1052  #else
    1053    z = z << TO_FBITS;
    1054  #endif
    1055  #if TO_HAVE_PADDING_BITS
    1056    z = z << TO_PADDING_BITS;
    1057    z = z >> TO_PADDING_BITS;
    1058  #endif
    1059    memcpy (&c, &z, TO_FIXED_SIZE);
    1060    return c;
    1061  }
    1062  #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4  */
    1063  
    1064  /* Unsigned int -> Fixed with saturation.  */
    1065  #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4
    1066  TO_FIXED_C_TYPE
    1067  SATFRACTUNS (FROM_INT_C_TYPE a)
    1068  {
    1069    TO_FIXED_C_TYPE c;
    1070    TO_INT_C_TYPE z;
    1071    FROM_INT_C_TYPE x = a;
    1072    BIG_UINT_C_TYPE high, low;
    1073    BIG_UINT_C_TYPE max_high, max_low;
    1074  #if BIG_WIDTH != TO_FBITS
    1075    BIG_UINT_C_TYPE utemp;
    1076    int shift_amount;
    1077  #endif
    1078  
    1079    /* Step 1. We need to store x to {high, low}.  */
    1080    low = (BIG_UINT_C_TYPE) x;
    1081    high = 0;
    1082  
    1083    /* Step 2. We need to left shift {high, low}.  */
    1084  #if BIG_WIDTH == TO_FBITS
    1085    high = low;
    1086    low = 0;
    1087  #else
    1088    shift_amount = TO_FBITS;
    1089    utemp = (BIG_UINT_C_TYPE) low;
    1090    utemp = utemp >> (BIG_WIDTH - shift_amount);
    1091    high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
    1092    low = low << shift_amount;
    1093  #endif
    1094  
    1095    /* Step 3. Compare {high, low} with max and  min of TO_FIXED_C_TYPE.  */
    1096    max_high = 0;
    1097  #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
    1098    max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
    1099    max_low = max_low - 1;
    1100  #else
    1101    max_low = -1;
    1102  #endif
    1103  
    1104  #if TO_MODE_UNSIGNED == 1
    1105    /* Unigned -> Unsigned.  */
    1106    if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
    1107        || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
    1108            && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
    1109      low = max_low; /* Maximum.  */
    1110  #else
    1111    /* Unsigned -> Signed.  */
    1112    if ((BIG_SINT_C_TYPE) high < 0)
    1113      low = max_low; /* Maximum.  */
    1114    else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
    1115             || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
    1116                 && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
    1117      low = max_low; /* Maximum.  */
    1118  #endif
    1119  
    1120    /* Step 4. Store the result.  */
    1121    z = (TO_INT_C_TYPE) low;
    1122  #if TO_HAVE_PADDING_BITS
    1123    z = z << TO_PADDING_BITS;
    1124    z = z >> TO_PADDING_BITS;
    1125  #endif
    1126    memcpy (&c, &z, TO_FIXED_SIZE);
    1127    return c;
    1128  }
    1129  #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4  */
    1130  
    1131  /* Fixed -> Float.  */
    1132  #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3
    1133  TO_FLOAT_C_TYPE
    1134  FRACT (FROM_FIXED_C_TYPE a)
    1135  {
    1136    FROM_INT_C_TYPE x;
    1137    TO_FLOAT_C_TYPE z;
    1138    memcpy (&x, &a, FROM_FIXED_SIZE);
    1139    z = (TO_FLOAT_C_TYPE) x;
    1140    z = z / BASE;
    1141    return z;
    1142  }
    1143  #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3  */
    1144  
    1145  /* Float -> Fixed.  */
    1146  #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4
    1147  TO_FIXED_C_TYPE
    1148  FRACT (FROM_FLOAT_C_TYPE a)
    1149  {
    1150    FROM_FLOAT_C_TYPE temp;
    1151    TO_INT_C_TYPE z;
    1152    TO_FIXED_C_TYPE c;
    1153  
    1154    temp = a * BASE;
    1155    z = (TO_INT_C_TYPE) temp;
    1156  #if TO_HAVE_PADDING_BITS
    1157    z = z << TO_PADDING_BITS;
    1158    z = z >> TO_PADDING_BITS;
    1159  #endif
    1160    memcpy (&c, &z, TO_FIXED_SIZE);
    1161    return c;
    1162  }
    1163  #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4  */
    1164  
    1165  /* Float -> Fixed with saturation.  */
    1166  #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4
    1167  TO_FIXED_C_TYPE
    1168  SATFRACT (FROM_FLOAT_C_TYPE a)
    1169  {
    1170    FROM_FLOAT_C_TYPE temp;
    1171    TO_INT_C_TYPE z;
    1172    TO_FIXED_C_TYPE c;
    1173  
    1174    if (a >= FIXED_MAX)
    1175      {
    1176  #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
    1177        z = (TO_INT_C_TYPE)1 << TO_I_F_BITS;
    1178        z = z - 1;
    1179  #else
    1180        z = -1;
    1181  #endif
    1182      }
    1183    else if (a <= FIXED_MIN)
    1184      {
    1185  #if TO_MODE_UNSIGNED == 0
    1186        z = (TO_INT_C_TYPE)1 << TO_I_F_BITS;
    1187  #else
    1188        z = 0;
    1189  #endif
    1190      }
    1191    else
    1192      {
    1193        temp = a * BASE;
    1194        z = (TO_INT_C_TYPE) temp;
    1195      }
    1196  
    1197  #if TO_HAVE_PADDING_BITS
    1198    z = z << TO_PADDING_BITS;
    1199    z = z >> TO_PADDING_BITS;
    1200  #endif
    1201    memcpy (&c, &z, TO_FIXED_SIZE);
    1202    return c;
    1203  }
    1204  #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4  */
    1205