1/* 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
13typedef USI SF;
14typedef UDI DF;
15typedef struct { SI parts[3]; } XF;
16typedef 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
25typedef 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 */
35typedef struct cgen_fp_ops CGEN_FP_OPS;
36
37/* Instance of an fpu.  */
38
39typedef 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
49typedef 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
56typedef void (CGEN_FPU_ERROR_FN) (CGEN_FPU*, int);
57
58/* fpu operation table */
59
60struct 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 (*remsf) (CGEN_FPU*, SF, SF);
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);
90  int (*unorderedsf) (CGEN_FPU*, SF, SF);
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);
98  DF (*remdf) (CGEN_FPU*, DF, DF);
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);
116  int (*unordereddf) (CGEN_FPU*, DF, DF);
117
118  /* SF/DF conversion ops */
119
120  DF (*fextsfdf) (CGEN_FPU*, int, SF);
121  SF (*ftruncdfsf) (CGEN_FPU*, int, DF);
122
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);
127
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);
132
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);
137
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);
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);
149  XF (*remxf) (CGEN_FPU*, XF, XF);
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
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);
171
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);
176
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);
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);
188  TF (*remtf) (CGEN_FPU*, TF, TF);
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
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);
210
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);
215
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);
220
221};
222
223extern void cgen_init_accurate_fpu (SIM_CPU*, CGEN_FPU*, CGEN_FPU_ERROR_FN*);
224
225BI cgen_sf_snan_p (CGEN_FPU*, SF);
226BI cgen_df_snan_p (CGEN_FPU*, DF);
227
228/* no-op fp error handler */
229extern CGEN_FPU_ERROR_FN cgen_fpu_ignore_errors;
230
231#endif /* CGEN_FPU_H */
232