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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [powerpc/] [math-emu/] [op-common.h] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
#define _FP_DECL(wc, X)                 \
2
  _FP_I_TYPE X##_c, X##_s, X##_e;       \
3
  _FP_FRAC_DECL_##wc(X)
4
 
5
/*
6
 * Finish truely unpacking a native fp value by classifying the kind
7
 * of fp value and normalizing both the exponent and the fraction.
8
 */
9
 
10
#define _FP_UNPACK_CANONICAL(fs, wc, X)                                 \
11
do {                                                                    \
12
  switch (X##_e)                                                        \
13
  {                                                                     \
14
  default:                                                              \
15
    _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs;                          \
16
    _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);                                 \
17
    X##_e -= _FP_EXPBIAS_##fs;                                          \
18
    X##_c = FP_CLS_NORMAL;                                              \
19
    break;                                                              \
20
                                                                        \
21
  case 0:                                                                \
22
    if (_FP_FRAC_ZEROP_##wc(X))                                         \
23
      X##_c = FP_CLS_ZERO;                                              \
24
    else                                                                \
25
      {                                                                 \
26
        /* a denormalized number */                                     \
27
        _FP_I_TYPE _shift;                                              \
28
        _FP_FRAC_CLZ_##wc(_shift, X);                                   \
29
        _shift -= _FP_FRACXBITS_##fs;                                   \
30
        _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));                    \
31
        X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;                         \
32
        X##_c = FP_CLS_NORMAL;                                          \
33
      }                                                                 \
34
    break;                                                              \
35
                                                                        \
36
  case _FP_EXPMAX_##fs:                                                 \
37
    if (_FP_FRAC_ZEROP_##wc(X))                                         \
38
      X##_c = FP_CLS_INF;                                               \
39
    else                                                                \
40
      /* we don't differentiate between signaling and quiet nans */     \
41
      X##_c = FP_CLS_NAN;                                               \
42
    break;                                                              \
43
  }                                                                     \
44
} while (0)
45
 
46
 
47
/*
48
 * Before packing the bits back into the native fp result, take care
49
 * of such mundane things as rounding and overflow.  Also, for some
50
 * kinds of fp values, the original parts may not have been fully
51
 * extracted -- but that is ok, we can regenerate them now.
52
 */
53
 
54
#define _FP_PACK_CANONICAL(fs, wc, X)                           \
55
({int __ret = 0;                                         \
56
  switch (X##_c)                                                \
57
  {                                                             \
58
  case FP_CLS_NORMAL:                                           \
59
    X##_e += _FP_EXPBIAS_##fs;                                  \
60
    if (X##_e > 0)                                              \
61
      {                                                         \
62
        __ret |= _FP_ROUND(wc, X);                              \
63
        if (_FP_FRAC_OVERP_##wc(fs, X))                         \
64
          {                                                     \
65
            _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1));             \
66
            X##_e++;                                            \
67
          }                                                     \
68
        else                                                    \
69
          _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);                   \
70
        if (X##_e >= _FP_EXPMAX_##fs)                           \
71
          {                                                     \
72
            /* overflow to infinity */                          \
73
            X##_e = _FP_EXPMAX_##fs;                            \
74
            _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);            \
75
            __ret |= EFLAG_OVERFLOW;                            \
76
          }                                                     \
77
      }                                                         \
78
    else                                                        \
79
      {                                                         \
80
        /* we've got a denormalized number */                   \
81
        X##_e = -X##_e + 1;                                     \
82
        if (X##_e <= _FP_WFRACBITS_##fs)                        \
83
          {                                                     \
84
            _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);    \
85
            _FP_FRAC_SLL_##wc(X, 1);                            \
86
            if (_FP_FRAC_OVERP_##wc(fs, X))                     \
87
              {                                                 \
88
                X##_e = 1;                                      \
89
                _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);        \
90
              }                                                 \
91
            else                                                \
92
              {                                                 \
93
                X##_e = 0;                                      \
94
                _FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1);           \
95
                __ret |= EFLAG_UNDERFLOW;                       \
96
              }                                                 \
97
          }                                                     \
98
        else                                                    \
99
          {                                                     \
100
            /* underflow to zero */                             \
101
            X##_e = 0;                                          \
102
            _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);            \
103
            __ret |= EFLAG_UNDERFLOW;                           \
104
          }                                                     \
105
      }                                                         \
106
    break;                                                      \
107
                                                                \
108
  case FP_CLS_ZERO:                                             \
109
    X##_e = 0;                                                  \
110
    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                    \
111
    break;                                                      \
112
                                                                \
113
  case FP_CLS_INF:                                              \
114
    X##_e = _FP_EXPMAX_##fs;                                    \
115
    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                    \
116
    break;                                                      \
117
                                                                \
118
  case FP_CLS_NAN:                                              \
119
    X##_e = _FP_EXPMAX_##fs;                                    \
120
    if (!_FP_KEEPNANFRACP)                                      \
121
      {                                                         \
122
        _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);                 \
123
        X##_s = 0;                                              \
124
      }                                                         \
125
    else                                                        \
126
      _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs;                \
127
    break;                                                      \
128
  }                                                             \
129
  __ret;                                                        \
130
})
131
 
132
 
133
/*
134
 * Main addition routine.  The input values should be cooked.
135
 */
136
 
137
#define _FP_ADD(fs, wc, R, X, Y)                                             \
138
do {                                                                         \
139
  switch (_FP_CLS_COMBINE(X##_c, Y##_c))                                     \
140
  {                                                                          \
141
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):                         \
142
    {                                                                        \
143
      /* shift the smaller number so that its exponent matches the larger */ \
144
      _FP_I_TYPE diff = X##_e - Y##_e;                                       \
145
                                                                             \
146
      if (diff < 0)                                                           \
147
        {                                                                    \
148
          diff = -diff;                                                      \
149
          if (diff <= _FP_WFRACBITS_##fs)                                    \
150
            _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs);                  \
151
          else if (!_FP_FRAC_ZEROP_##wc(X))                                  \
152
            _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);                          \
153
          else                                                               \
154
            _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                         \
155
          R##_e = Y##_e;                                                     \
156
        }                                                                    \
157
      else                                                                   \
158
        {                                                                    \
159
          if (diff > 0)                                                       \
160
            {                                                                \
161
              if (diff <= _FP_WFRACBITS_##fs)                                \
162
                _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs);              \
163
              else if (!_FP_FRAC_ZEROP_##wc(Y))                              \
164
                _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);                      \
165
              else                                                           \
166
                _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc);                     \
167
            }                                                                \
168
          R##_e = X##_e;                                                     \
169
        }                                                                    \
170
                                                                             \
171
      R##_c = FP_CLS_NORMAL;                                                 \
172
                                                                             \
173
      if (X##_s == Y##_s)                                                    \
174
        {                                                                    \
175
          R##_s = X##_s;                                                     \
176
          _FP_FRAC_ADD_##wc(R, X, Y);                                        \
177
          if (_FP_FRAC_OVERP_##wc(fs, R))                                    \
178
            {                                                                \
179
              _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);                   \
180
              R##_e++;                                                       \
181
            }                                                                \
182
        }                                                                    \
183
      else                                                                   \
184
        {                                                                    \
185
          R##_s = X##_s;                                                     \
186
          _FP_FRAC_SUB_##wc(R, X, Y);                                        \
187
          if (_FP_FRAC_ZEROP_##wc(R))                                        \
188
            {                                                                \
189
              /* return an exact zero */                                     \
190
              if (FP_ROUNDMODE == FP_RND_MINF)                               \
191
                R##_s |= Y##_s;                                              \
192
              else                                                           \
193
                R##_s &= Y##_s;                                              \
194
              R##_c = FP_CLS_ZERO;                                           \
195
            }                                                                \
196
          else                                                               \
197
            {                                                                \
198
              if (_FP_FRAC_NEGP_##wc(R))                                     \
199
                {                                                            \
200
                  _FP_FRAC_SUB_##wc(R, Y, X);                                \
201
                  R##_s = Y##_s;                                             \
202
                }                                                            \
203
                                                                             \
204
              /* renormalize after subtraction */                            \
205
              _FP_FRAC_CLZ_##wc(diff, R);                                    \
206
              diff -= _FP_WFRACXBITS_##fs;                                   \
207
              if (diff)                                                      \
208
                {                                                            \
209
                  R##_e -= diff;                                             \
210
                  _FP_FRAC_SLL_##wc(R, diff);                                \
211
                }                                                            \
212
            }                                                                \
213
        }                                                                    \
214
      break;                                                                 \
215
    }                                                                        \
216
                                                                             \
217
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):                               \
218
    _FP_CHOOSENAN(fs, wc, R, X, Y);                                          \
219
    break;                                                                   \
220
                                                                             \
221
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):                           \
222
    R##_e = X##_e;                                                           \
223
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):                            \
224
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):                               \
225
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                              \
226
    _FP_FRAC_COPY_##wc(R, X);                                                \
227
    R##_s = X##_s;                                                           \
228
    R##_c = X##_c;                                                           \
229
    break;                                                                   \
230
                                                                             \
231
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):                           \
232
    R##_e = Y##_e;                                                           \
233
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):                            \
234
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):                               \
235
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                              \
236
    _FP_FRAC_COPY_##wc(R, Y);                                                \
237
    R##_s = Y##_s;                                                           \
238
    R##_c = Y##_c;                                                           \
239
    break;                                                                   \
240
                                                                             \
241
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):                               \
242
    if (X##_s != Y##_s)                                                      \
243
      {                                                                      \
244
        /* +INF + -INF => NAN */                                             \
245
        _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                              \
246
        R##_s = X##_s ^ Y##_s;                                               \
247
        R##_c = FP_CLS_NAN;                                                  \
248
        break;                                                               \
249
      }                                                                      \
250
    /* FALLTHRU */                                                           \
251
                                                                             \
252
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):                            \
253
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                              \
254
    R##_s = X##_s;                                                           \
255
    R##_c = FP_CLS_INF;                                                      \
256
    break;                                                                   \
257
                                                                             \
258
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):                            \
259
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):                              \
260
    R##_s = Y##_s;                                                           \
261
    R##_c = FP_CLS_INF;                                                      \
262
    break;                                                                   \
263
                                                                             \
264
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):                             \
265
    /* make sure the sign is correct */                                      \
266
    if (FP_ROUNDMODE == FP_RND_MINF)                                         \
267
      R##_s = X##_s | Y##_s;                                                 \
268
    else                                                                     \
269
      R##_s = X##_s & Y##_s;                                                 \
270
    R##_c = FP_CLS_ZERO;                                                     \
271
    break;                                                                   \
272
                                                                             \
273
  default:                                                                   \
274
    abort();                                                                 \
275
  }                                                                          \
276
} while (0)
277
 
278
 
279
/*
280
 * Main negation routine.  FIXME -- when we care about setting exception
281
 * bits reliably, this will not do.  We should examine all of the fp classes.
282
 */
283
 
284
#define _FP_NEG(fs, wc, R, X)           \
285
  do {                                  \
286
    _FP_FRAC_COPY_##wc(R, X);           \
287
    R##_c = X##_c;                      \
288
    R##_e = X##_e;                      \
289
    R##_s = 1 ^ X##_s;                  \
290
  } while (0)
291
 
292
 
293
/*
294
 * Main multiplication routine.  The input values should be cooked.
295
 */
296
 
297
#define _FP_MUL(fs, wc, R, X, Y)                        \
298
do {                                                    \
299
  R##_s = X##_s ^ Y##_s;                                \
300
  switch (_FP_CLS_COMBINE(X##_c, Y##_c))                \
301
  {                                                     \
302
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):    \
303
    R##_c = FP_CLS_NORMAL;                              \
304
    R##_e = X##_e + Y##_e + 1;                          \
305
                                                        \
306
    _FP_MUL_MEAT_##fs(R,X,Y);                           \
307
                                                        \
308
    if (_FP_FRAC_OVERP_##wc(fs, R))                     \
309
      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);      \
310
    else                                                \
311
      R##_e--;                                          \
312
    break;                                              \
313
                                                        \
314
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):          \
315
    _FP_CHOOSENAN(fs, wc, R, X, Y);                     \
316
    break;                                              \
317
                                                        \
318
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):       \
319
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):          \
320
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):         \
321
    R##_s = X##_s;                                      \
322
                                                        \
323
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):          \
324
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):       \
325
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):      \
326
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):        \
327
    _FP_FRAC_COPY_##wc(R, X);                           \
328
    R##_c = X##_c;                                      \
329
    break;                                              \
330
                                                        \
331
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):       \
332
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):          \
333
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):         \
334
    R##_s = Y##_s;                                      \
335
                                                        \
336
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):       \
337
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):      \
338
    _FP_FRAC_COPY_##wc(R, Y);                           \
339
    R##_c = Y##_c;                                      \
340
    break;                                              \
341
                                                        \
342
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):         \
343
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):         \
344
    R##_c = FP_CLS_NAN;                                 \
345
    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);             \
346
    break;                                              \
347
                                                        \
348
  default:                                              \
349
    abort();                                            \
350
  }                                                     \
351
} while (0)
352
 
353
 
354
/*
355
 * Main division routine.  The input values should be cooked.
356
 */
357
 
358
#define _FP_DIV(fs, wc, R, X, Y)                        \
359
do {                                                    \
360
  R##_s = X##_s ^ Y##_s;                                \
361
  switch (_FP_CLS_COMBINE(X##_c, Y##_c))                \
362
  {                                                     \
363
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):    \
364
    R##_c = FP_CLS_NORMAL;                              \
365
    R##_e = X##_e - Y##_e;                              \
366
                                                        \
367
    _FP_DIV_MEAT_##fs(R,X,Y);                           \
368
    break;                                              \
369
                                                        \
370
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):          \
371
    _FP_CHOOSENAN(fs, wc, R, X, Y);                     \
372
    break;                                              \
373
                                                        \
374
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):       \
375
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):          \
376
  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):         \
377
    R##_s = X##_s;                                      \
378
    _FP_FRAC_COPY_##wc(R, X);                           \
379
    R##_c = X##_c;                                      \
380
    break;                                              \
381
                                                        \
382
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):       \
383
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):          \
384
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):         \
385
    R##_s = Y##_s;                                      \
386
    _FP_FRAC_COPY_##wc(R, Y);                           \
387
    R##_c = Y##_c;                                      \
388
    break;                                              \
389
                                                        \
390
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):       \
391
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):         \
392
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):      \
393
    R##_c = FP_CLS_ZERO;                                \
394
    break;                                              \
395
                                                        \
396
  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):      \
397
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):         \
398
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):       \
399
    R##_c = FP_CLS_INF;                                 \
400
    break;                                              \
401
                                                        \
402
  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):          \
403
  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):        \
404
    R##_c = FP_CLS_NAN;                                 \
405
    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);             \
406
    break;                                              \
407
                                                        \
408
  default:                                              \
409
    abort();                                            \
410
  }                                                     \
411
} while (0)
412
 
413
 
414
/*
415
 * Main differential comparison routine.  The inputs should be raw not
416
 * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
417
 */
418
 
419
#define _FP_CMP(fs, wc, ret, X, Y, un)                                  \
420
  do {                                                                  \
421
    /* NANs are unordered */                                            \
422
    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))           \
423
        || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))       \
424
      {                                                                 \
425
        ret = un;                                                       \
426
      }                                                                 \
427
    else                                                                \
428
      {                                                                 \
429
        int __x_zero = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;      \
430
        int __y_zero = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;      \
431
                                                                        \
432
        if (__x_zero && __y_zero)                                       \
433
          ret = 0;                                                       \
434
        else if (__x_zero)                                              \
435
          ret = Y##_s ? 1 : -1;                                         \
436
        else if (__y_zero)                                              \
437
          ret = X##_s ? -1 : 1;                                         \
438
        else if (X##_s != Y##_s)                                        \
439
          ret = X##_s ? -1 : 1;                                         \
440
        else if (X##_e > Y##_e)                                         \
441
          ret = X##_s ? -1 : 1;                                         \
442
        else if (X##_e < Y##_e)                                         \
443
          ret = X##_s ? 1 : -1;                                         \
444
        else if (_FP_FRAC_GT_##wc(X, Y))                                \
445
          ret = X##_s ? -1 : 1;                                         \
446
        else if (_FP_FRAC_GT_##wc(Y, X))                                \
447
          ret = X##_s ? 1 : -1;                                         \
448
        else                                                            \
449
          ret = 0;                                                       \
450
      }                                                                 \
451
  } while (0)
452
 
453
 
454
/* Simplification for strict equality.  */
455
 
456
#define _FP_CMP_EQ(fs, wc, ret, X, Y)                                     \
457
  do {                                                                    \
458
    /* NANs are unordered */                                              \
459
    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))             \
460
        || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))         \
461
      {                                                                   \
462
        ret = 1;                                                          \
463
      }                                                                   \
464
    else                                                                  \
465
      {                                                                   \
466
        ret = !(X##_e == Y##_e                                            \
467
                && _FP_FRAC_EQ_##wc(X, Y)                                 \
468
                && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
469
      }                                                                   \
470
  } while (0)
471
 
472
/*
473
 * Main square root routine.  The input value should be cooked.
474
 */
475
 
476
#define _FP_SQRT(fs, wc, R, X)                                          \
477
do {                                                                    \
478
    _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);                       \
479
    _FP_W_TYPE q;                                                       \
480
    switch (X##_c)                                                      \
481
    {                                                                   \
482
    case FP_CLS_NAN:                                                    \
483
        R##_s = 0;                                                      \
484
        R##_c = FP_CLS_NAN;                                             \
485
        _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                        \
486
        break;                                                          \
487
    case FP_CLS_INF:                                                    \
488
        if (X##_s)                                                      \
489
          {                                                             \
490
            R##_s = 0;                                                  \
491
            R##_c = FP_CLS_NAN; /* sNAN */                              \
492
          }                                                             \
493
        else                                                            \
494
          {                                                             \
495
            R##_s = 0;                                                  \
496
            R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */                 \
497
          }                                                             \
498
        break;                                                          \
499
    case FP_CLS_ZERO:                                                   \
500
        R##_s = X##_s;                                                  \
501
        R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */                      \
502
        break;                                                          \
503
    case FP_CLS_NORMAL:                                                 \
504
        R##_s = 0;                                                      \
505
        if (X##_s)                                                      \
506
          {                                                             \
507
            R##_c = FP_CLS_NAN; /* sNAN */                              \
508
            break;                                                      \
509
          }                                                             \
510
        R##_c = FP_CLS_NORMAL;                                          \
511
        if (X##_e & 1)                                                  \
512
          _FP_FRAC_SLL_##wc(X, 1);                                      \
513
        R##_e = X##_e >> 1;                                             \
514
        _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);                        \
515
        _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);                        \
516
        q = _FP_OVERFLOW_##fs;                                          \
517
        _FP_FRAC_SLL_##wc(X, 1);                                        \
518
        _FP_SQRT_MEAT_##wc(R, S, T, X, q);                              \
519
        _FP_FRAC_SRL_##wc(R, 1);                                        \
520
    }                                                                   \
521
  } while (0)
522
 
523
/*
524
 * Convert from FP to integer
525
 */
526
 
527
/* "When a NaN, infinity, large positive argument >= 2147483648.0, or
528
 * large negative argument <= -2147483649.0 is converted to an integer,
529
 * the invalid_current bit...should be set and fp_exception_IEEE_754 should
530
 * be raised. If the floating point invalid trap is disabled, no trap occurs
531
 * and a numerical result is generated: if the sign bit of the operand
532
 * is 0, the result is 2147483647; if the sign bit of the operand is 1,
533
 * the result is -2147483648."
534
 * Similarly for conversion to extended ints, except that the boundaries
535
 * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and
536
 * -2^63 for s=1.
537
 * -- SPARC Architecture Manual V9, Appendix B, which specifies how
538
 * SPARCs resolve implementation dependencies in the IEEE-754 spec.
539
 * I don't believe that the code below follows this. I'm not even sure
540
 * it's right!
541
 * It doesn't cope with needing to convert to an n bit integer when there
542
 * is no n bit integer type. Fortunately gcc provides long long so this
543
 * isn't a problem for sparc32.
544
 * I have, however, fixed its NaN handling to conform as above.
545
 *         -- PMM 02/1998
546
 * NB: rsigned is not 'is r declared signed?' but 'should the value stored
547
 * in r be signed or unsigned?'. r is always(?) declared unsigned.
548
 * Comments below are mine, BTW -- PMM
549
 */
550
#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)                        \
551
  do {                                                                  \
552
    switch (X##_c)                                                      \
553
      {                                                                 \
554
      case FP_CLS_NORMAL:                                               \
555
        if (X##_e < 0)                                                  \
556
          {                                                             \
557
          /* case FP_CLS_NAN: see above! */                             \
558
          case FP_CLS_ZERO:                                             \
559
            r = 0;                                                       \
560
          }                                                             \
561
        else if (X##_e >= rsize - (rsigned != 0))                       \
562
          {     /* overflow */                                          \
563
          case FP_CLS_NAN:                                              \
564
          case FP_CLS_INF:                                              \
565
            if (rsigned)                                                \
566
              {                                                         \
567
                r = 1;                                                  \
568
                r <<= rsize - 1;                                        \
569
                r -= 1 - X##_s;                                         \
570
              }                                                         \
571
            else                                                        \
572
              {                                                         \
573
                r = 0;                                                   \
574
                if (!X##_s)                                             \
575
                  r = ~r;                                               \
576
              }                                                         \
577
          }                                                             \
578
        else                                                            \
579
          {                                                             \
580
            if (_FP_W_TYPE_SIZE*wc < rsize)                             \
581
              {                                                         \
582
                _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                    \
583
                r <<= X##_e - _FP_WFRACBITS_##fs;                       \
584
              }                                                         \
585
            else                                                        \
586
              {                                                         \
587
                if (X##_e >= _FP_WFRACBITS_##fs)                        \
588
                  _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));\
589
                else                                                    \
590
                  _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));\
591
                _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                    \
592
              }                                                         \
593
            if (rsigned && X##_s)                                       \
594
              r = -r;                                                   \
595
          }                                                             \
596
        break;                                                          \
597
      }                                                                 \
598
  } while (0)
599
 
600
#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)                        \
601
  do {                                                                  \
602
    if (r)                                                              \
603
      {                                                                 \
604
        X##_c = FP_CLS_NORMAL;                                          \
605
                                                                        \
606
        if ((X##_s = (r < 0)))                                          \
607
          r = -r;                                                       \
608
        /* Note that `r' is now considered unsigned, so we don't have   \
609
           to worry about the single signed overflow case.  */          \
610
                                                                        \
611
        if (rsize <= _FP_W_TYPE_SIZE)                                   \
612
          __FP_CLZ(X##_e, r);                                           \
613
        else                                                            \
614
          __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE),         \
615
                     (_FP_W_TYPE)r);                                    \
616
        if (rsize < _FP_W_TYPE_SIZE)                                    \
617
                X##_e -= (_FP_W_TYPE_SIZE - rsize);                     \
618
        X##_e = rsize - X##_e - 1;                                      \
619
                                                                        \
620
        if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e)    \
621
          __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize);      \
622
        r &= ~((_FP_W_TYPE)1 << X##_e);                                 \
623
        _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize);       \
624
        _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));         \
625
      }                                                                 \
626
    else                                                                \
627
      {                                                                 \
628
        X##_c = FP_CLS_ZERO, X##_s = 0;                                 \
629
      }                                                                 \
630
  } while (0)
631
 
632
 
633
#define FP_CONV(dfs,sfs,dwc,swc,D,S)                    \
634
  do {                                                  \
635
    _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);        \
636
    D##_e = S##_e;                                      \
637
    D##_c = S##_c;                                      \
638
    D##_s = S##_s;                                      \
639
  } while (0)
640
 
641
/*
642
 * Helper primitives.
643
 */
644
 
645
/* Count leading zeros in a word.  */
646
 
647
#ifndef __FP_CLZ
648
#if _FP_W_TYPE_SIZE < 64
649
/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
650
#define __FP_CLZ(r, x)                          \
651
  do {                                          \
652
    _FP_W_TYPE _t = (x);                        \
653
    r = _FP_W_TYPE_SIZE - 1;                    \
654
    if (_t > 0xffff) r -= 16;                   \
655
    if (_t > 0xffff) _t >>= 16;                 \
656
    if (_t > 0xff) r -= 8;                      \
657
    if (_t > 0xff) _t >>= 8;                    \
658
    if (_t & 0xf0) r -= 4;                      \
659
    if (_t & 0xf0) _t >>= 4;                    \
660
    if (_t & 0xc) r -= 2;                       \
661
    if (_t & 0xc) _t >>= 2;                     \
662
    if (_t & 0x2) r -= 1;                       \
663
  } while (0)
664
#else /* not _FP_W_TYPE_SIZE < 64 */
665
#define __FP_CLZ(r, x)                          \
666
  do {                                          \
667
    _FP_W_TYPE _t = (x);                        \
668
    r = _FP_W_TYPE_SIZE - 1;                    \
669
    if (_t > 0xffffffff) r -= 32;               \
670
    if (_t > 0xffffffff) _t >>= 32;             \
671
    if (_t > 0xffff) r -= 16;                   \
672
    if (_t > 0xffff) _t >>= 16;                 \
673
    if (_t > 0xff) r -= 8;                      \
674
    if (_t > 0xff) _t >>= 8;                    \
675
    if (_t & 0xf0) r -= 4;                      \
676
    if (_t & 0xf0) _t >>= 4;                    \
677
    if (_t & 0xc) r -= 2;                       \
678
    if (_t & 0xc) _t >>= 2;                     \
679
    if (_t & 0x2) r -= 1;                       \
680
  } while (0)
681
#endif /* not _FP_W_TYPE_SIZE < 64 */
682
#endif /* ndef __FP_CLZ */
683
 
684
#define _FP_DIV_HELP_imm(q, r, n, d)            \
685
  do {                                          \
686
    q = n / d, r = n % d;                       \
687
  } while (0)
688
 

powered by: WebSVN 2.1.0

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