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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [math-emu/] [extended.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* Software floating-point emulation.
2
   Definitions for IEEE Extended Precision.
3
   Copyright (C) 1999 Free Software Foundation, Inc.
4
   This file is part of the GNU C Library.
5
   Contributed by Jakub Jelinek (jj@ultra.linux.cz).
6
 
7
   The GNU C Library is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU Library General Public License as
9
   published by the Free Software Foundation; either version 2 of the
10
   License, or (at your option) any later version.
11
 
12
   The GNU C Library is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
   Library General Public License for more details.
16
 
17
   You should have received a copy of the GNU Library General Public
18
   License along with the GNU C Library; see the file COPYING.LIB.  If
19
   not, write to the Free Software Foundation, Inc.,
20
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
 
22
 
23
#ifndef    __MATH_EMU_EXTENDED_H__
24
#define    __MATH_EMU_EXTENDED_H__
25
 
26
#if _FP_W_TYPE_SIZE < 32
27
#error "Here's a nickel, kid. Go buy yourself a real computer."
28
#endif
29
 
30
#if _FP_W_TYPE_SIZE < 64
31
#define _FP_FRACTBITS_E         (4*_FP_W_TYPE_SIZE)
32
#else
33
#define _FP_FRACTBITS_E         (2*_FP_W_TYPE_SIZE)
34
#endif
35
 
36
#define _FP_FRACBITS_E          64
37
#define _FP_FRACXBITS_E         (_FP_FRACTBITS_E - _FP_FRACBITS_E)
38
#define _FP_WFRACBITS_E         (_FP_WORKBITS + _FP_FRACBITS_E)
39
#define _FP_WFRACXBITS_E        (_FP_FRACTBITS_E - _FP_WFRACBITS_E)
40
#define _FP_EXPBITS_E           15
41
#define _FP_EXPBIAS_E           16383
42
#define _FP_EXPMAX_E            32767
43
 
44
#define _FP_QNANBIT_E           \
45
        ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
46
#define _FP_IMPLBIT_E           \
47
        ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
48
#define _FP_OVERFLOW_E          \
49
        ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
50
 
51
#if _FP_W_TYPE_SIZE < 64
52
 
53
union _FP_UNION_E
54
{
55
   long double flt;
56
   struct
57
   {
58
#if __BYTE_ORDER == __BIG_ENDIAN
59
      unsigned long pad1 : _FP_W_TYPE_SIZE;
60
      unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
61
      unsigned long sign : 1;
62
      unsigned long exp : _FP_EXPBITS_E;
63
      unsigned long frac1 : _FP_W_TYPE_SIZE;
64
      unsigned long frac0 : _FP_W_TYPE_SIZE;
65
#else
66
      unsigned long frac0 : _FP_W_TYPE_SIZE;
67
      unsigned long frac1 : _FP_W_TYPE_SIZE;
68
      unsigned exp : _FP_EXPBITS_E;
69
      unsigned sign : 1;
70
#endif /* not bigendian */
71
   } bits __attribute__((packed));
72
};
73
 
74
 
75
#define FP_DECL_E(X)            _FP_DECL(4,X)
76
 
77
#define FP_UNPACK_RAW_E(X, val)                         \
78
  do {                                                  \
79
    union _FP_UNION_E _flo; _flo.flt = (val);           \
80
                                                        \
81
    X##_f[2] = 0; X##_f[3] = 0;                         \
82
    X##_f[0] = _flo.bits.frac0;                         \
83
    X##_f[1] = _flo.bits.frac1;                         \
84
    X##_e  = _flo.bits.exp;                             \
85
    X##_s  = _flo.bits.sign;                            \
86
    if (!X##_e && (X##_f[1] || X##_f[0])                \
87
        && !(X##_f[1] & _FP_IMPLBIT_E))                 \
88
      {                                                 \
89
        X##_e++;                                        \
90
        FP_SET_EXCEPTION(FP_EX_DENORM);                 \
91
      }                                                 \
92
  } while (0)
93
 
94
#define FP_UNPACK_RAW_EP(X, val)                        \
95
  do {                                                  \
96
    union _FP_UNION_E *_flo =                           \
97
    (union _FP_UNION_E *)(val);                         \
98
                                                        \
99
    X##_f[2] = 0; X##_f[3] = 0;                         \
100
    X##_f[0] = _flo->bits.frac0;                        \
101
    X##_f[1] = _flo->bits.frac1;                        \
102
    X##_e  = _flo->bits.exp;                            \
103
    X##_s  = _flo->bits.sign;                           \
104
    if (!X##_e && (X##_f[1] || X##_f[0])                \
105
        && !(X##_f[1] & _FP_IMPLBIT_E))                 \
106
      {                                                 \
107
        X##_e++;                                        \
108
        FP_SET_EXCEPTION(FP_EX_DENORM);                 \
109
      }                                                 \
110
  } while (0)
111
 
112
#define FP_PACK_RAW_E(val, X)                           \
113
  do {                                                  \
114
    union _FP_UNION_E _flo;                             \
115
                                                        \
116
    if (X##_e) X##_f[1] |= _FP_IMPLBIT_E;               \
117
    else X##_f[1] &= ~(_FP_IMPLBIT_E);                  \
118
    _flo.bits.frac0 = X##_f[0];                         \
119
    _flo.bits.frac1 = X##_f[1];                         \
120
    _flo.bits.exp   = X##_e;                            \
121
    _flo.bits.sign  = X##_s;                            \
122
                                                        \
123
    (val) = _flo.flt;                                   \
124
  } while (0)
125
 
126
#define FP_PACK_RAW_EP(val, X)                          \
127
  do {                                                  \
128
    if (!FP_INHIBIT_RESULTS)                            \
129
      {                                                 \
130
        union _FP_UNION_E *_flo =                       \
131
          (union _FP_UNION_E *)(val);                   \
132
                                                        \
133
        if (X##_e) X##_f[1] |= _FP_IMPLBIT_E;           \
134
        else X##_f[1] &= ~(_FP_IMPLBIT_E);              \
135
        _flo->bits.frac0 = X##_f[0];                    \
136
        _flo->bits.frac1 = X##_f[1];                    \
137
        _flo->bits.exp   = X##_e;                       \
138
        _flo->bits.sign  = X##_s;                       \
139
      }                                                 \
140
  } while (0)
141
 
142
#define FP_UNPACK_E(X,val)              \
143
  do {                                  \
144
    FP_UNPACK_RAW_E(X,val);             \
145
    _FP_UNPACK_CANONICAL(E,4,X);        \
146
  } while (0)
147
 
148
#define FP_UNPACK_EP(X,val)             \
149
  do {                                  \
150
    FP_UNPACK_RAW_2_P(X,val);           \
151
    _FP_UNPACK_CANONICAL(E,4,X);        \
152
  } while (0)
153
 
154
#define FP_PACK_E(val,X)                \
155
  do {                                  \
156
    _FP_PACK_CANONICAL(E,4,X);          \
157
    FP_PACK_RAW_E(val,X);               \
158
  } while (0)
159
 
160
#define FP_PACK_EP(val,X)               \
161
  do {                                  \
162
    _FP_PACK_CANONICAL(E,4,X);          \
163
    FP_PACK_RAW_EP(val,X);              \
164
  } while (0)
165
 
166
#define FP_ISSIGNAN_E(X)        _FP_ISSIGNAN(E,4,X)
167
#define FP_NEG_E(R,X)           _FP_NEG(E,4,R,X)
168
#define FP_ADD_E(R,X,Y)         _FP_ADD(E,4,R,X,Y)
169
#define FP_SUB_E(R,X,Y)         _FP_SUB(E,4,R,X,Y)
170
#define FP_MUL_E(R,X,Y)         _FP_MUL(E,4,R,X,Y)
171
#define FP_DIV_E(R,X,Y)         _FP_DIV(E,4,R,X,Y)
172
#define FP_SQRT_E(R,X)          _FP_SQRT(E,4,R,X)
173
 
174
/*
175
 * Square root algorithms:
176
 * We have just one right now, maybe Newton approximation
177
 * should be added for those machines where division is fast.
178
 * This has special _E version because standard _4 square
179
 * root would not work (it has to start normally with the
180
 * second word and not the first), but as we have to do it
181
 * anyway, we optimize it by doing most of the calculations
182
 * in two UWtype registers instead of four.
183
 */
184
 
185
#define _FP_SQRT_MEAT_E(R, S, T, X, q)                  \
186
  do {                                                  \
187
    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);         \
188
    _FP_FRAC_SRL_4(X, (_FP_WORKBITS));                  \
189
    while (q)                                           \
190
      {                                                 \
191
        T##_f[1] = S##_f[1] + q;                        \
192
        if (T##_f[1] <= X##_f[1])                       \
193
          {                                             \
194
            S##_f[1] = T##_f[1] + q;                    \
195
            X##_f[1] -= T##_f[1];                       \
196
            R##_f[1] += q;                              \
197
          }                                             \
198
        _FP_FRAC_SLL_2(X, 1);                           \
199
        q >>= 1;                                        \
200
      }                                                 \
201
    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);         \
202
    while (q)                                           \
203
      {                                                 \
204
        T##_f[0] = S##_f[0] + q;                        \
205
        T##_f[1] = S##_f[1];                            \
206
        if (T##_f[1] < X##_f[1] ||                      \
207
            (T##_f[1] == X##_f[1] &&                    \
208
             T##_f[0] <= X##_f[0]))                     \
209
          {                                             \
210
            S##_f[0] = T##_f[0] + q;                    \
211
            S##_f[1] += (T##_f[0] > S##_f[0]);          \
212
            _FP_FRAC_DEC_2(X, T);                       \
213
            R##_f[0] += q;                              \
214
          }                                             \
215
        _FP_FRAC_SLL_2(X, 1);                           \
216
        q >>= 1;                                        \
217
      }                                                 \
218
    _FP_FRAC_SLL_4(R, (_FP_WORKBITS));                  \
219
    if (X##_f[0] | X##_f[1])                            \
220
      {                                                 \
221
        if (S##_f[1] < X##_f[1] ||                      \
222
            (S##_f[1] == X##_f[1] &&                    \
223
             S##_f[0] < X##_f[0]))                      \
224
          R##_f[0] |= _FP_WORK_ROUND;                   \
225
        R##_f[0] |= _FP_WORK_STICKY;                    \
226
      }                                                 \
227
  } while (0)
228
 
229
#define FP_CMP_E(r,X,Y,un)      _FP_CMP(E,4,r,X,Y,un)
230
#define FP_CMP_EQ_E(r,X,Y)      _FP_CMP_EQ(E,4,r,X,Y)
231
 
232
#define FP_TO_INT_E(r,X,rsz,rsg)        _FP_TO_INT(E,4,r,X,rsz,rsg)
233
#define FP_TO_INT_ROUND_E(r,X,rsz,rsg)  _FP_TO_INT_ROUND(E,4,r,X,rsz,rsg)
234
#define FP_FROM_INT_E(X,r,rs,rt)        _FP_FROM_INT(E,4,X,r,rs,rt)
235
 
236
#define _FP_FRAC_HIGH_E(X)      (X##_f[2])
237
#define _FP_FRAC_HIGH_RAW_E(X)  (X##_f[1])
238
 
239
#else   /* not _FP_W_TYPE_SIZE < 64 */
240
union _FP_UNION_E
241
{
242
  long double flt /* __attribute__((mode(TF))) */ ;
243
  struct {
244
#if __BYTE_ORDER == __BIG_ENDIAN
245
    unsigned long pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
246
    unsigned sign  : 1;
247
    unsigned exp   : _FP_EXPBITS_E;
248
    unsigned long frac : _FP_W_TYPE_SIZE;
249
#else
250
    unsigned long frac : _FP_W_TYPE_SIZE;
251
    unsigned exp   : _FP_EXPBITS_E;
252
    unsigned sign  : 1;
253
#endif
254
  } bits;
255
};
256
 
257
#define FP_DECL_E(X)            _FP_DECL(2,X)
258
 
259
#define FP_UNPACK_RAW_E(X, val)                                 \
260
  do {                                                          \
261
    union _FP_UNION_E _flo; _flo.flt = (val);                   \
262
                                                                \
263
    X##_f0 = _flo.bits.frac;                                    \
264
    X##_f1 = 0;                                                 \
265
    X##_e = _flo.bits.exp;                                      \
266
    X##_s = _flo.bits.sign;                                     \
267
    if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E))          \
268
      {                                                         \
269
        X##_e++;                                                \
270
        FP_SET_EXCEPTION(FP_EX_DENORM);                         \
271
      }                                                         \
272
  } while (0)
273
 
274
#define FP_UNPACK_RAW_EP(X, val)                                \
275
  do {                                                          \
276
    union _FP_UNION_E *_flo =                                   \
277
      (union _FP_UNION_E *)(val);                               \
278
                                                                \
279
    X##_f0 = _flo->bits.frac;                                   \
280
    X##_f1 = 0;                                                 \
281
    X##_e = _flo->bits.exp;                                     \
282
    X##_s = _flo->bits.sign;                                    \
283
    if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E))          \
284
      {                                                         \
285
        X##_e++;                                                \
286
        FP_SET_EXCEPTION(FP_EX_DENORM);                         \
287
      }                                                         \
288
  } while (0)
289
 
290
#define FP_PACK_RAW_E(val, X)                                   \
291
  do {                                                          \
292
    union _FP_UNION_E _flo;                                     \
293
                                                                \
294
    if (X##_e) X##_f0 |= _FP_IMPLBIT_E;                         \
295
    else X##_f0 &= ~(_FP_IMPLBIT_E);                            \
296
    _flo.bits.frac = X##_f0;                                    \
297
    _flo.bits.exp  = X##_e;                                     \
298
    _flo.bits.sign = X##_s;                                     \
299
                                                                \
300
    (val) = _flo.flt;                                           \
301
  } while (0)
302
 
303
#define FP_PACK_RAW_EP(fs, val, X)                              \
304
  do {                                                          \
305
    if (!FP_INHIBIT_RESULTS)                                    \
306
      {                                                         \
307
        union _FP_UNION_E *_flo =                               \
308
          (union _FP_UNION_E *)(val);                           \
309
                                                                \
310
        if (X##_e) X##_f0 |= _FP_IMPLBIT_E;                     \
311
        else X##_f0 &= ~(_FP_IMPLBIT_E);                        \
312
        _flo->bits.frac = X##_f0;                               \
313
        _flo->bits.exp  = X##_e;                                \
314
        _flo->bits.sign = X##_s;                                \
315
      }                                                         \
316
  } while (0)
317
 
318
 
319
#define FP_UNPACK_E(X,val)              \
320
  do {                                  \
321
    FP_UNPACK_RAW_E(X,val);             \
322
    _FP_UNPACK_CANONICAL(E,2,X);        \
323
  } while (0)
324
 
325
#define FP_UNPACK_EP(X,val)             \
326
  do {                                  \
327
    FP_UNPACK_RAW_EP(X,val);            \
328
    _FP_UNPACK_CANONICAL(E,2,X);        \
329
  } while (0)
330
 
331
#define FP_PACK_E(val,X)                \
332
  do {                                  \
333
    _FP_PACK_CANONICAL(E,2,X);          \
334
    FP_PACK_RAW_E(val,X);               \
335
  } while (0)
336
 
337
#define FP_PACK_EP(val,X)               \
338
  do {                                  \
339
    _FP_PACK_CANONICAL(E,2,X);          \
340
    FP_PACK_RAW_EP(val,X);              \
341
  } while (0)
342
 
343
#define FP_ISSIGNAN_E(X)        _FP_ISSIGNAN(E,2,X)
344
#define FP_NEG_E(R,X)           _FP_NEG(E,2,R,X)
345
#define FP_ADD_E(R,X,Y)         _FP_ADD(E,2,R,X,Y)
346
#define FP_SUB_E(R,X,Y)         _FP_SUB(E,2,R,X,Y)
347
#define FP_MUL_E(R,X,Y)         _FP_MUL(E,2,R,X,Y)
348
#define FP_DIV_E(R,X,Y)         _FP_DIV(E,2,R,X,Y)
349
#define FP_SQRT_E(R,X)          _FP_SQRT(E,2,R,X)
350
 
351
/*
352
 * Square root algorithms:
353
 * We have just one right now, maybe Newton approximation
354
 * should be added for those machines where division is fast.
355
 * We optimize it by doing most of the calculations
356
 * in one UWtype registers instead of two, although we don't
357
 * have to.
358
 */
359
#define _FP_SQRT_MEAT_E(R, S, T, X, q)                  \
360
  do {                                                  \
361
    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);         \
362
    _FP_FRAC_SRL_2(X, (_FP_WORKBITS));                  \
363
    while (q)                                           \
364
      {                                                 \
365
        T##_f0 = S##_f0 + q;                            \
366
        if (T##_f0 <= X##_f0)                           \
367
          {                                             \
368
            S##_f0 = T##_f0 + q;                        \
369
            X##_f0 -= T##_f0;                           \
370
            R##_f0 += q;                                \
371
          }                                             \
372
        _FP_FRAC_SLL_1(X, 1);                           \
373
        q >>= 1;                                        \
374
      }                                                 \
375
    _FP_FRAC_SLL_2(R, (_FP_WORKBITS));                  \
376
    if (X##_f0)                                         \
377
      {                                                 \
378
        if (S##_f0 < X##_f0)                            \
379
          R##_f0 |= _FP_WORK_ROUND;                     \
380
        R##_f0 |= _FP_WORK_STICKY;                      \
381
      }                                                 \
382
  } while (0)
383
 
384
#define FP_CMP_E(r,X,Y,un)      _FP_CMP(E,2,r,X,Y,un)
385
#define FP_CMP_EQ_E(r,X,Y)      _FP_CMP_EQ(E,2,r,X,Y)
386
 
387
#define FP_TO_INT_E(r,X,rsz,rsg)        _FP_TO_INT(E,2,r,X,rsz,rsg)
388
#define FP_TO_INT_ROUND_E(r,X,rsz,rsg)  _FP_TO_INT_ROUND(E,2,r,X,rsz,rsg)
389
#define FP_FROM_INT_E(X,r,rs,rt)        _FP_FROM_INT(E,2,X,r,rs,rt)
390
 
391
#define _FP_FRAC_HIGH_E(X)      (X##_f1)
392
#define _FP_FRAC_HIGH_RAW_E(X)  (X##_f0)
393
 
394
#endif /* not _FP_W_TYPE_SIZE < 64 */
395
 
396
#endif /* __MATH_EMU_EXTENDED_H__ */

powered by: WebSVN 2.1.0

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