OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [fixed-bit.c] - Blame information for rev 818

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
/* 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
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 + 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.