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 (*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
217extern void cgen_init_accurate_fpu (SIM_CPU*, CGEN_FPU*, CGEN_FPU_ERROR_FN*);
218
219BI cgen_sf_snan_p (CGEN_FPU*, SF);
220BI cgen_df_snan_p (CGEN_FPU*, DF);
221
222/* no-op fp error handler */
223extern CGEN_FPU_ERROR_FN cgen_fpu_ignore_errors;
224
225#endif /* CGEN_FPU_H */
226