Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef SOFT_FP_H |
| 2 | #define SOFT_FP_H |
| 3 | |
| 4 | #include "sfp-machine.h" |
| 5 | |
| 6 | #define _FP_WORKBITS 3 |
| 7 | #define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) |
| 8 | #define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) |
| 9 | #define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) |
| 10 | #define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) |
| 11 | |
| 12 | #ifndef FP_RND_NEAREST |
| 13 | # define FP_RND_NEAREST 0 |
| 14 | # define FP_RND_ZERO 1 |
| 15 | # define FP_RND_PINF 2 |
| 16 | # define FP_RND_MINF 3 |
| 17 | #ifndef FP_ROUNDMODE |
| 18 | # define FP_ROUNDMODE FP_RND_NEAREST |
| 19 | #endif |
| 20 | #endif |
| 21 | |
| 22 | #define _FP_ROUND_NEAREST(wc, X) \ |
| 23 | ({ int __ret = 0; \ |
| 24 | int __frac = _FP_FRAC_LOW_##wc(X) & 15; \ |
| 25 | if (__frac & 7) { \ |
| 26 | __ret = EFLAG_INEXACT; \ |
| 27 | if ((__frac & 7) != _FP_WORK_ROUND) \ |
| 28 | _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ |
| 29 | else if (__frac & _FP_WORK_LSB) \ |
| 30 | _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ |
| 31 | } \ |
| 32 | __ret; \ |
| 33 | }) |
| 34 | |
| 35 | #define _FP_ROUND_ZERO(wc, X) \ |
| 36 | ({ int __ret = 0; \ |
| 37 | if (_FP_FRAC_LOW_##wc(X) & 7) \ |
| 38 | __ret = EFLAG_INEXACT; \ |
| 39 | __ret; \ |
| 40 | }) |
| 41 | |
| 42 | #define _FP_ROUND_PINF(wc, X) \ |
| 43 | ({ int __ret = EFLAG_INEXACT; \ |
| 44 | if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ |
| 45 | _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ |
| 46 | else __ret = 0; \ |
| 47 | __ret; \ |
| 48 | }) |
| 49 | |
| 50 | #define _FP_ROUND_MINF(wc, X) \ |
| 51 | ({ int __ret = EFLAG_INEXACT; \ |
| 52 | if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ |
| 53 | _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ |
| 54 | else __ret = 0; \ |
| 55 | __ret; \ |
| 56 | }) |
| 57 | |
| 58 | #define _FP_ROUND(wc, X) \ |
| 59 | ({ int __ret = 0; \ |
| 60 | switch (FP_ROUNDMODE) \ |
| 61 | { \ |
| 62 | case FP_RND_NEAREST: \ |
| 63 | __ret |= _FP_ROUND_NEAREST(wc,X); \ |
| 64 | break; \ |
| 65 | case FP_RND_ZERO: \ |
| 66 | __ret |= _FP_ROUND_ZERO(wc,X); \ |
| 67 | break; \ |
| 68 | case FP_RND_PINF: \ |
| 69 | __ret |= _FP_ROUND_PINF(wc,X); \ |
| 70 | break; \ |
| 71 | case FP_RND_MINF: \ |
| 72 | __ret |= _FP_ROUND_MINF(wc,X); \ |
| 73 | break; \ |
| 74 | }; \ |
| 75 | __ret; \ |
| 76 | }) |
| 77 | |
| 78 | #define FP_CLS_NORMAL 0 |
| 79 | #define FP_CLS_ZERO 1 |
| 80 | #define FP_CLS_INF 2 |
| 81 | #define FP_CLS_NAN 3 |
| 82 | |
| 83 | #define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) |
| 84 | |
| 85 | #include "op-1.h" |
| 86 | #include "op-2.h" |
| 87 | #include "op-4.h" |
| 88 | #include "op-common.h" |
| 89 | |
| 90 | /* Sigh. Silly things longlong.h needs. */ |
| 91 | #define UWtype _FP_W_TYPE |
| 92 | #define W_TYPE_SIZE _FP_W_TYPE_SIZE |
| 93 | |
| 94 | typedef int SItype __attribute__((mode(SI))); |
| 95 | typedef int DItype __attribute__((mode(DI))); |
| 96 | typedef unsigned int USItype __attribute__((mode(SI))); |
| 97 | typedef unsigned int UDItype __attribute__((mode(DI))); |
| 98 | #if _FP_W_TYPE_SIZE == 32 |
| 99 | typedef unsigned int UHWtype __attribute__((mode(HI))); |
| 100 | #elif _FP_W_TYPE_SIZE == 64 |
| 101 | typedef USItype UHWtype; |
| 102 | #endif |
| 103 | |
| 104 | #endif |