gcc50: Disconnect from buildworld.
[dragonfly.git] / contrib / gcc-5.0 / libgcc / fixed-bit.c
1 /* This is a software fixed-point library.
2    Copyright (C) 2007-2015 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