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 
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 */
226