OSDN Git Service

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