Commit | Line | Data |
---|---|---|
3535ad49 | 1 | /* CGEN fpu support |
d2c7a1a6 DE |
2 | Copyright (C) 1999 Cygnus Solutions. |
3 | Copyright (C) 2010 Doug Evans. */ | |
3535ad49 JM |
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 | ||
d2c7a1a6 DE |
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 | ||
3535ad49 JM |
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); | |
07b95864 | 72 | SF (*remsf) (CGEN_FPU*, SF, SF); |
3535ad49 JM |
73 | SF (*negsf) (CGEN_FPU*, SF); |
74 | SF (*abssf) (CGEN_FPU*, SF); | |
75 | SF (*sqrtsf) (CGEN_FPU*, SF); | |
76 | SF (*invsf) (CGEN_FPU*, SF); | |
77 | SF (*cossf) (CGEN_FPU*, SF); | |
78 | SF (*sinsf) (CGEN_FPU*, SF); | |
79 | SF (*minsf) (CGEN_FPU*, SF, SF); | |
80 | SF (*maxsf) (CGEN_FPU*, SF, SF); | |
81 | ||
82 | /* ??? to be revisited */ | |
83 | CGEN_FP_CMP (*cmpsf) (CGEN_FPU*, SF, SF); | |
84 | int (*eqsf) (CGEN_FPU*, SF, SF); | |
85 | int (*nesf) (CGEN_FPU*, SF, SF); | |
86 | int (*ltsf) (CGEN_FPU*, SF, SF); | |
87 | int (*lesf) (CGEN_FPU*, SF, SF); | |
88 | int (*gtsf) (CGEN_FPU*, SF, SF); | |
89 | int (*gesf) (CGEN_FPU*, SF, SF); | |
f1cc84f5 | 90 | int (*unorderedsf) (CGEN_FPU*, SF, SF); |
3535ad49 JM |
91 | |
92 | /* basic DF ops */ | |
93 | ||
94 | DF (*adddf) (CGEN_FPU*, DF, DF); | |
95 | DF (*subdf) (CGEN_FPU*, DF, DF); | |
96 | DF (*muldf) (CGEN_FPU*, DF, DF); | |
97 | DF (*divdf) (CGEN_FPU*, DF, DF); | |
07b95864 | 98 | DF (*remdf) (CGEN_FPU*, DF, DF); |
3535ad49 JM |
99 | DF (*negdf) (CGEN_FPU*, DF); |
100 | DF (*absdf) (CGEN_FPU*, DF); | |
101 | DF (*sqrtdf) (CGEN_FPU*, DF); | |
102 | DF (*invdf) (CGEN_FPU*, DF); | |
103 | DF (*cosdf) (CGEN_FPU*, DF); | |
104 | DF (*sindf) (CGEN_FPU*, DF); | |
105 | DF (*mindf) (CGEN_FPU*, DF, DF); | |
106 | DF (*maxdf) (CGEN_FPU*, DF, DF); | |
107 | ||
108 | /* ??? to be revisited */ | |
109 | CGEN_FP_CMP (*cmpdf) (CGEN_FPU*, DF, DF); | |
110 | int (*eqdf) (CGEN_FPU*, DF, DF); | |
111 | int (*nedf) (CGEN_FPU*, DF, DF); | |
112 | int (*ltdf) (CGEN_FPU*, DF, DF); | |
113 | int (*ledf) (CGEN_FPU*, DF, DF); | |
114 | int (*gtdf) (CGEN_FPU*, DF, DF); | |
115 | int (*gedf) (CGEN_FPU*, DF, DF); | |
f1cc84f5 | 116 | int (*unordereddf) (CGEN_FPU*, DF, DF); |
3535ad49 JM |
117 | |
118 | /* SF/DF conversion ops */ | |
119 | ||
d2c7a1a6 DE |
120 | DF (*fextsfdf) (CGEN_FPU*, int, SF); |
121 | SF (*ftruncdfsf) (CGEN_FPU*, int, DF); | |
3535ad49 | 122 | |
d2c7a1a6 DE |
123 | SF (*floatsisf) (CGEN_FPU*, int, SI); |
124 | SF (*floatdisf) (CGEN_FPU*, int, DI); | |
125 | SF (*ufloatsisf) (CGEN_FPU*, int, USI); | |
126 | SF (*ufloatdisf) (CGEN_FPU*, int, UDI); | |
3535ad49 | 127 | |
d2c7a1a6 DE |
128 | SI (*fixsfsi) (CGEN_FPU*, int, SF); |
129 | DI (*fixsfdi) (CGEN_FPU*, int, SF); | |
130 | USI (*ufixsfsi) (CGEN_FPU*, int, SF); | |
131 | UDI (*ufixsfdi) (CGEN_FPU*, int, SF); | |
3535ad49 | 132 | |
d2c7a1a6 DE |
133 | DF (*floatsidf) (CGEN_FPU*, int, SI); |
134 | DF (*floatdidf) (CGEN_FPU*, int, DI); | |
135 | DF (*ufloatsidf) (CGEN_FPU*, int, USI); | |
136 | DF (*ufloatdidf) (CGEN_FPU*, int, UDI); | |
3535ad49 | 137 | |
d2c7a1a6 DE |
138 | SI (*fixdfsi) (CGEN_FPU*, int, DF); |
139 | DI (*fixdfdi) (CGEN_FPU*, int, DF); | |
140 | USI (*ufixdfsi) (CGEN_FPU*, int, DF); | |
141 | UDI (*ufixdfdi) (CGEN_FPU*, int, DF); | |
3535ad49 JM |
142 | |
143 | /* XF mode support (kept separate 'cus not always present) */ | |
144 | ||
145 | XF (*addxf) (CGEN_FPU*, XF, XF); | |
146 | XF (*subxf) (CGEN_FPU*, XF, XF); | |
147 | XF (*mulxf) (CGEN_FPU*, XF, XF); | |
148 | XF (*divxf) (CGEN_FPU*, XF, XF); | |
07b95864 | 149 | XF (*remxf) (CGEN_FPU*, XF, XF); |
3535ad49 JM |
150 | XF (*negxf) (CGEN_FPU*, XF); |
151 | XF (*absxf) (CGEN_FPU*, XF); | |
152 | XF (*sqrtxf) (CGEN_FPU*, XF); | |
153 | XF (*invxf) (CGEN_FPU*, XF); | |
154 | XF (*cosxf) (CGEN_FPU*, XF); | |
155 | XF (*sinxf) (CGEN_FPU*, XF); | |
156 | XF (*minxf) (CGEN_FPU*, XF, XF); | |
157 | XF (*maxxf) (CGEN_FPU*, XF, XF); | |
158 | ||
159 | CGEN_FP_CMP (*cmpxf) (CGEN_FPU*, XF, XF); | |
160 | int (*eqxf) (CGEN_FPU*, XF, XF); | |
161 | int (*nexf) (CGEN_FPU*, XF, XF); | |
162 | int (*ltxf) (CGEN_FPU*, XF, XF); | |
163 | int (*lexf) (CGEN_FPU*, XF, XF); | |
164 | int (*gtxf) (CGEN_FPU*, XF, XF); | |
165 | int (*gexf) (CGEN_FPU*, XF, XF); | |
166 | ||
d2c7a1a6 DE |
167 | XF (*extsfxf) (CGEN_FPU*, int, SF); |
168 | XF (*extdfxf) (CGEN_FPU*, int, DF); | |
169 | SF (*truncxfsf) (CGEN_FPU*, int, XF); | |
170 | DF (*truncxfdf) (CGEN_FPU*, int, XF); | |
3535ad49 | 171 | |
d2c7a1a6 DE |
172 | XF (*floatsixf) (CGEN_FPU*, int, SI); |
173 | XF (*floatdixf) (CGEN_FPU*, int, DI); | |
174 | XF (*ufloatsixf) (CGEN_FPU*, int, USI); | |
175 | XF (*ufloatdixf) (CGEN_FPU*, int, UDI); | |
3535ad49 | 176 | |
d2c7a1a6 DE |
177 | SI (*fixxfsi) (CGEN_FPU*, int, XF); |
178 | DI (*fixxfdi) (CGEN_FPU*, int, XF); | |
179 | USI (*ufixxfsi) (CGEN_FPU*, int, XF); | |
180 | UDI (*ufixxfdi) (CGEN_FPU*, int, XF); | |
3535ad49 JM |
181 | |
182 | /* TF mode support (kept separate 'cus not always present) */ | |
183 | ||
184 | TF (*addtf) (CGEN_FPU*, TF, TF); | |
185 | TF (*subtf) (CGEN_FPU*, TF, TF); | |
186 | TF (*multf) (CGEN_FPU*, TF, TF); | |
187 | TF (*divtf) (CGEN_FPU*, TF, TF); | |
07b95864 | 188 | TF (*remtf) (CGEN_FPU*, TF, TF); |
3535ad49 JM |
189 | TF (*negtf) (CGEN_FPU*, TF); |
190 | TF (*abstf) (CGEN_FPU*, TF); | |
191 | TF (*sqrttf) (CGEN_FPU*, TF); | |
192 | TF (*invtf) (CGEN_FPU*, TF); | |
193 | TF (*costf) (CGEN_FPU*, TF); | |
194 | TF (*sintf) (CGEN_FPU*, TF); | |
195 | TF (*mintf) (CGEN_FPU*, TF, TF); | |
196 | TF (*maxtf) (CGEN_FPU*, TF, TF); | |
197 | ||
198 | CGEN_FP_CMP (*cmptf) (CGEN_FPU*, TF, TF); | |
199 | int (*eqtf) (CGEN_FPU*, TF, TF); | |
200 | int (*netf) (CGEN_FPU*, TF, TF); | |
201 | int (*lttf) (CGEN_FPU*, TF, TF); | |
202 | int (*letf) (CGEN_FPU*, TF, TF); | |
203 | int (*gttf) (CGEN_FPU*, TF, TF); | |
204 | int (*getf) (CGEN_FPU*, TF, TF); | |
205 | ||
d2c7a1a6 DE |
206 | TF (*extsftf) (CGEN_FPU*, int, SF); |
207 | TF (*extdftf) (CGEN_FPU*, int, DF); | |
208 | SF (*trunctfsf) (CGEN_FPU*, int, TF); | |
209 | DF (*trunctfdf) (CGEN_FPU*, int, TF); | |
3535ad49 | 210 | |
d2c7a1a6 DE |
211 | TF (*floatsitf) (CGEN_FPU*, int, SI); |
212 | TF (*floatditf) (CGEN_FPU*, int, DI); | |
213 | TF (*ufloatsitf) (CGEN_FPU*, int, USI); | |
214 | TF (*ufloatditf) (CGEN_FPU*, int, UDI); | |
3535ad49 | 215 | |
d2c7a1a6 DE |
216 | SI (*fixtfsi) (CGEN_FPU*, int, TF); |
217 | DI (*fixtfdi) (CGEN_FPU*, int, TF); | |
218 | USI (*ufixtfsi) (CGEN_FPU*, int, TF); | |
219 | UDI (*ufixtfdi) (CGEN_FPU*, int, TF); | |
3535ad49 JM |
220 | |
221 | }; | |
222 | ||
223 | extern void cgen_init_accurate_fpu (SIM_CPU*, CGEN_FPU*, CGEN_FPU_ERROR_FN*); | |
224 | ||
225 | BI cgen_sf_snan_p (CGEN_FPU*, SF); | |
226 | BI cgen_df_snan_p (CGEN_FPU*, DF); | |
227 | ||
228 | /* no-op fp error handler */ | |
229 | extern CGEN_FPU_ERROR_FN cgen_fpu_ignore_errors; | |
230 | ||
231 | #endif /* CGEN_FPU_H */ |