File: /usr/src/linux/arch/ppc/math-emu/soft-fp.h

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