Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6515 serge 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
.  */
24
 
25
/* This implements fixed-point arithmetic.
26
 
27
   Contributed by Chao-ying Fu  .  */
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