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