1 |
330 |
jeremybenn |
/* CGEN fpu support
|
2 |
|
|
Copyright (C) 1999 Cygnus Solutions.
|
3 |
|
|
Copyright (C) 2010 Doug Evans. */
|
4 |
|
|
|
5 |
|
|
#ifndef CGEN_FPU_H
|
6 |
|
|
#define CGEN_FPU_H
|
7 |
|
|
|
8 |
|
|
/* Floating point support is a little more complicated.
|
9 |
|
|
We want to support using either host fp insns or an accurate fp library.
|
10 |
|
|
We also want to support easily added variants (e.g. modified ieee).
|
11 |
|
|
This is done by vectoring all calls through a table. */
|
12 |
|
|
|
13 |
|
|
typedef USI SF;
|
14 |
|
|
typedef UDI DF;
|
15 |
|
|
typedef struct { SI parts[3]; } XF;
|
16 |
|
|
typedef struct { SI parts[4]; } TF;
|
17 |
|
|
|
18 |
|
|
#ifndef TARGET_EXT_FP_WORDS
|
19 |
|
|
#define TARGET_EXT_FP_WORDS 4
|
20 |
|
|
#endif
|
21 |
|
|
|
22 |
|
|
/* Supported floating point conversion kinds (rounding modes).
|
23 |
|
|
FIXME: The IEEE rounding modes need to be implemented. */
|
24 |
|
|
|
25 |
|
|
typedef enum {
|
26 |
|
|
FPCONV_DEFAULT = 0,
|
27 |
|
|
FPCONV_TIES_TO_EVEN = 1,
|
28 |
|
|
FPCONV_TIES_TO_AWAY = 2,
|
29 |
|
|
FPCONV_TOWARD_ZERO = 3,
|
30 |
|
|
FPCONV_TOWARD_POSITIVE = 4,
|
31 |
|
|
FPCONV_TOWARD_NEGATIVE = 5
|
32 |
|
|
} CGEN_FPCONV_KIND;
|
33 |
|
|
|
34 |
|
|
/* forward decl */
|
35 |
|
|
typedef struct cgen_fp_ops CGEN_FP_OPS;
|
36 |
|
|
|
37 |
|
|
/* Instance of an fpu. */
|
38 |
|
|
|
39 |
|
|
typedef struct {
|
40 |
|
|
/* Usually a pointer back to the SIM_CPU struct. */
|
41 |
|
|
void* owner;
|
42 |
|
|
/* Pointer to ops struct, rather than copy of it, to avoid bloating
|
43 |
|
|
SIM_CPU struct. */
|
44 |
|
|
CGEN_FP_OPS* ops;
|
45 |
|
|
} CGEN_FPU;
|
46 |
|
|
|
47 |
|
|
/* result of cmp */
|
48 |
|
|
|
49 |
|
|
typedef enum {
|
50 |
|
|
/* ??? May wish to distinguish qnan/snan here. */
|
51 |
|
|
FP_CMP_EQ, FP_CMP_LT, FP_CMP_GT, FP_CMP_NAN
|
52 |
|
|
} CGEN_FP_CMP;
|
53 |
|
|
|
54 |
|
|
/* error handler */
|
55 |
|
|
|
56 |
|
|
typedef void (CGEN_FPU_ERROR_FN) (CGEN_FPU*, int);
|
57 |
|
|
|
58 |
|
|
/* fpu operation table */
|
59 |
|
|
|
60 |
|
|
struct cgen_fp_ops {
|
61 |
|
|
|
62 |
|
|
/* error (e.g. signalling nan) handler, supplied by owner */
|
63 |
|
|
|
64 |
|
|
CGEN_FPU_ERROR_FN *error;
|
65 |
|
|
|
66 |
|
|
/* basic SF ops */
|
67 |
|
|
|
68 |
|
|
SF (*addsf) (CGEN_FPU*, SF, SF);
|
69 |
|
|
SF (*subsf) (CGEN_FPU*, SF, SF);
|
70 |
|
|
SF (*mulsf) (CGEN_FPU*, SF, SF);
|
71 |
|
|
SF (*divsf) (CGEN_FPU*, SF, SF);
|
72 |
|
|
SF (*negsf) (CGEN_FPU*, SF);
|
73 |
|
|
SF (*abssf) (CGEN_FPU*, SF);
|
74 |
|
|
SF (*sqrtsf) (CGEN_FPU*, SF);
|
75 |
|
|
SF (*invsf) (CGEN_FPU*, SF);
|
76 |
|
|
SF (*cossf) (CGEN_FPU*, SF);
|
77 |
|
|
SF (*sinsf) (CGEN_FPU*, SF);
|
78 |
|
|
SF (*minsf) (CGEN_FPU*, SF, SF);
|
79 |
|
|
SF (*maxsf) (CGEN_FPU*, SF, SF);
|
80 |
|
|
|
81 |
|
|
/* ??? to be revisited */
|
82 |
|
|
CGEN_FP_CMP (*cmpsf) (CGEN_FPU*, SF, SF);
|
83 |
|
|
int (*eqsf) (CGEN_FPU*, SF, SF);
|
84 |
|
|
int (*nesf) (CGEN_FPU*, SF, SF);
|
85 |
|
|
int (*ltsf) (CGEN_FPU*, SF, SF);
|
86 |
|
|
int (*lesf) (CGEN_FPU*, SF, SF);
|
87 |
|
|
int (*gtsf) (CGEN_FPU*, SF, SF);
|
88 |
|
|
int (*gesf) (CGEN_FPU*, SF, SF);
|
89 |
|
|
|
90 |
|
|
/* basic DF ops */
|
91 |
|
|
|
92 |
|
|
DF (*adddf) (CGEN_FPU*, DF, DF);
|
93 |
|
|
DF (*subdf) (CGEN_FPU*, DF, DF);
|
94 |
|
|
DF (*muldf) (CGEN_FPU*, DF, DF);
|
95 |
|
|
DF (*divdf) (CGEN_FPU*, DF, DF);
|
96 |
|
|
DF (*negdf) (CGEN_FPU*, DF);
|
97 |
|
|
DF (*absdf) (CGEN_FPU*, DF);
|
98 |
|
|
DF (*sqrtdf) (CGEN_FPU*, DF);
|
99 |
|
|
DF (*invdf) (CGEN_FPU*, DF);
|
100 |
|
|
DF (*cosdf) (CGEN_FPU*, DF);
|
101 |
|
|
DF (*sindf) (CGEN_FPU*, DF);
|
102 |
|
|
DF (*mindf) (CGEN_FPU*, DF, DF);
|
103 |
|
|
DF (*maxdf) (CGEN_FPU*, DF, DF);
|
104 |
|
|
|
105 |
|
|
/* ??? to be revisited */
|
106 |
|
|
CGEN_FP_CMP (*cmpdf) (CGEN_FPU*, DF, DF);
|
107 |
|
|
int (*eqdf) (CGEN_FPU*, DF, DF);
|
108 |
|
|
int (*nedf) (CGEN_FPU*, DF, DF);
|
109 |
|
|
int (*ltdf) (CGEN_FPU*, DF, DF);
|
110 |
|
|
int (*ledf) (CGEN_FPU*, DF, DF);
|
111 |
|
|
int (*gtdf) (CGEN_FPU*, DF, DF);
|
112 |
|
|
int (*gedf) (CGEN_FPU*, DF, DF);
|
113 |
|
|
|
114 |
|
|
/* SF/DF conversion ops */
|
115 |
|
|
|
116 |
|
|
DF (*fextsfdf) (CGEN_FPU*, int, SF);
|
117 |
|
|
SF (*ftruncdfsf) (CGEN_FPU*, int, DF);
|
118 |
|
|
|
119 |
|
|
SF (*floatsisf) (CGEN_FPU*, int, SI);
|
120 |
|
|
SF (*floatdisf) (CGEN_FPU*, int, DI);
|
121 |
|
|
SF (*ufloatsisf) (CGEN_FPU*, int, USI);
|
122 |
|
|
SF (*ufloatdisf) (CGEN_FPU*, int, UDI);
|
123 |
|
|
|
124 |
|
|
SI (*fixsfsi) (CGEN_FPU*, int, SF);
|
125 |
|
|
DI (*fixsfdi) (CGEN_FPU*, int, SF);
|
126 |
|
|
USI (*ufixsfsi) (CGEN_FPU*, int, SF);
|
127 |
|
|
UDI (*ufixsfdi) (CGEN_FPU*, int, SF);
|
128 |
|
|
|
129 |
|
|
DF (*floatsidf) (CGEN_FPU*, int, SI);
|
130 |
|
|
DF (*floatdidf) (CGEN_FPU*, int, DI);
|
131 |
|
|
DF (*ufloatsidf) (CGEN_FPU*, int, USI);
|
132 |
|
|
DF (*ufloatdidf) (CGEN_FPU*, int, UDI);
|
133 |
|
|
|
134 |
|
|
SI (*fixdfsi) (CGEN_FPU*, int, DF);
|
135 |
|
|
DI (*fixdfdi) (CGEN_FPU*, int, DF);
|
136 |
|
|
USI (*ufixdfsi) (CGEN_FPU*, int, DF);
|
137 |
|
|
UDI (*ufixdfdi) (CGEN_FPU*, int, DF);
|
138 |
|
|
|
139 |
|
|
/* XF mode support (kept separate 'cus not always present) */
|
140 |
|
|
|
141 |
|
|
XF (*addxf) (CGEN_FPU*, XF, XF);
|
142 |
|
|
XF (*subxf) (CGEN_FPU*, XF, XF);
|
143 |
|
|
XF (*mulxf) (CGEN_FPU*, XF, XF);
|
144 |
|
|
XF (*divxf) (CGEN_FPU*, XF, XF);
|
145 |
|
|
XF (*negxf) (CGEN_FPU*, XF);
|
146 |
|
|
XF (*absxf) (CGEN_FPU*, XF);
|
147 |
|
|
XF (*sqrtxf) (CGEN_FPU*, XF);
|
148 |
|
|
XF (*invxf) (CGEN_FPU*, XF);
|
149 |
|
|
XF (*cosxf) (CGEN_FPU*, XF);
|
150 |
|
|
XF (*sinxf) (CGEN_FPU*, XF);
|
151 |
|
|
XF (*minxf) (CGEN_FPU*, XF, XF);
|
152 |
|
|
XF (*maxxf) (CGEN_FPU*, XF, XF);
|
153 |
|
|
|
154 |
|
|
CGEN_FP_CMP (*cmpxf) (CGEN_FPU*, XF, XF);
|
155 |
|
|
int (*eqxf) (CGEN_FPU*, XF, XF);
|
156 |
|
|
int (*nexf) (CGEN_FPU*, XF, XF);
|
157 |
|
|
int (*ltxf) (CGEN_FPU*, XF, XF);
|
158 |
|
|
int (*lexf) (CGEN_FPU*, XF, XF);
|
159 |
|
|
int (*gtxf) (CGEN_FPU*, XF, XF);
|
160 |
|
|
int (*gexf) (CGEN_FPU*, XF, XF);
|
161 |
|
|
|
162 |
|
|
XF (*extsfxf) (CGEN_FPU*, int, SF);
|
163 |
|
|
XF (*extdfxf) (CGEN_FPU*, int, DF);
|
164 |
|
|
SF (*truncxfsf) (CGEN_FPU*, int, XF);
|
165 |
|
|
DF (*truncxfdf) (CGEN_FPU*, int, XF);
|
166 |
|
|
|
167 |
|
|
XF (*floatsixf) (CGEN_FPU*, int, SI);
|
168 |
|
|
XF (*floatdixf) (CGEN_FPU*, int, DI);
|
169 |
|
|
XF (*ufloatsixf) (CGEN_FPU*, int, USI);
|
170 |
|
|
XF (*ufloatdixf) (CGEN_FPU*, int, UDI);
|
171 |
|
|
|
172 |
|
|
SI (*fixxfsi) (CGEN_FPU*, int, XF);
|
173 |
|
|
DI (*fixxfdi) (CGEN_FPU*, int, XF);
|
174 |
|
|
USI (*ufixxfsi) (CGEN_FPU*, int, XF);
|
175 |
|
|
UDI (*ufixxfdi) (CGEN_FPU*, int, XF);
|
176 |
|
|
|
177 |
|
|
/* TF mode support (kept separate 'cus not always present) */
|
178 |
|
|
|
179 |
|
|
TF (*addtf) (CGEN_FPU*, TF, TF);
|
180 |
|
|
TF (*subtf) (CGEN_FPU*, TF, TF);
|
181 |
|
|
TF (*multf) (CGEN_FPU*, TF, TF);
|
182 |
|
|
TF (*divtf) (CGEN_FPU*, TF, TF);
|
183 |
|
|
TF (*negtf) (CGEN_FPU*, TF);
|
184 |
|
|
TF (*abstf) (CGEN_FPU*, TF);
|
185 |
|
|
TF (*sqrttf) (CGEN_FPU*, TF);
|
186 |
|
|
TF (*invtf) (CGEN_FPU*, TF);
|
187 |
|
|
TF (*costf) (CGEN_FPU*, TF);
|
188 |
|
|
TF (*sintf) (CGEN_FPU*, TF);
|
189 |
|
|
TF (*mintf) (CGEN_FPU*, TF, TF);
|
190 |
|
|
TF (*maxtf) (CGEN_FPU*, TF, TF);
|
191 |
|
|
|
192 |
|
|
CGEN_FP_CMP (*cmptf) (CGEN_FPU*, TF, TF);
|
193 |
|
|
int (*eqtf) (CGEN_FPU*, TF, TF);
|
194 |
|
|
int (*netf) (CGEN_FPU*, TF, TF);
|
195 |
|
|
int (*lttf) (CGEN_FPU*, TF, TF);
|
196 |
|
|
int (*letf) (CGEN_FPU*, TF, TF);
|
197 |
|
|
int (*gttf) (CGEN_FPU*, TF, TF);
|
198 |
|
|
int (*getf) (CGEN_FPU*, TF, TF);
|
199 |
|
|
|
200 |
|
|
TF (*extsftf) (CGEN_FPU*, int, SF);
|
201 |
|
|
TF (*extdftf) (CGEN_FPU*, int, DF);
|
202 |
|
|
SF (*trunctfsf) (CGEN_FPU*, int, TF);
|
203 |
|
|
DF (*trunctfdf) (CGEN_FPU*, int, TF);
|
204 |
|
|
|
205 |
|
|
TF (*floatsitf) (CGEN_FPU*, int, SI);
|
206 |
|
|
TF (*floatditf) (CGEN_FPU*, int, DI);
|
207 |
|
|
TF (*ufloatsitf) (CGEN_FPU*, int, USI);
|
208 |
|
|
TF (*ufloatditf) (CGEN_FPU*, int, UDI);
|
209 |
|
|
|
210 |
|
|
SI (*fixtfsi) (CGEN_FPU*, int, TF);
|
211 |
|
|
DI (*fixtfdi) (CGEN_FPU*, int, TF);
|
212 |
|
|
USI (*ufixtfsi) (CGEN_FPU*, int, TF);
|
213 |
|
|
UDI (*ufixtfdi) (CGEN_FPU*, int, TF);
|
214 |
|
|
|
215 |
|
|
};
|
216 |
|
|
|
217 |
|
|
extern void cgen_init_accurate_fpu (SIM_CPU*, CGEN_FPU*, CGEN_FPU_ERROR_FN*);
|
218 |
|
|
|
219 |
|
|
BI cgen_sf_snan_p (CGEN_FPU*, SF);
|
220 |
|
|
BI cgen_df_snan_p (CGEN_FPU*, DF);
|
221 |
|
|
|
222 |
|
|
/* no-op fp error handler */
|
223 |
|
|
extern CGEN_FPU_ERROR_FN cgen_fpu_ignore_errors;
|
224 |
|
|
|
225 |
|
|
#endif /* CGEN_FPU_H */
|