OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [fixed-bit.c] - Blame information for rev 300

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

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

powered by: WebSVN 2.1.0

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