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