inline/parametrize rootcounter reads
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / fpu.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - fpu.c                                                   *
3  *   Copyright (C) 2010 Ari64                                              *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
19  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20
21 #include <math.h>
22
23 extern int FCR0, FCR31;
24
25 void cvt_s_w(int *source,float *dest)
26 {
27   *dest = *source;
28 }
29 void cvt_d_w(int *source,double *dest)
30 {
31   *dest = *source;
32 }
33 void cvt_s_l(long long *source,float *dest)
34 {
35   *dest = *source;
36 }
37 void cvt_d_l(long long *source,double *dest)
38 {
39   *dest = *source;
40 }
41 void cvt_d_s(float *source,double *dest)
42 {
43   *dest = *source;
44 }
45 void cvt_s_d(double *source,float *dest)
46 {
47   *dest = *source;
48 }
49
50 void round_l_s(float *source,long long *dest)
51 {
52   *dest = roundf(*source);
53 }
54 void round_w_s(float *source,int *dest)
55 {
56   *dest = roundf(*source);
57 }
58 void trunc_l_s(float *source,long long *dest)
59 {
60   *dest = truncf(*source);
61 }
62 void trunc_w_s(float *source,int *dest)
63 {
64   *dest = truncf(*source);
65 }
66 void ceil_l_s(float *source,long long *dest)
67 {
68   *dest = ceilf(*source);
69 }
70 void ceil_w_s(float *source,int *dest)
71 {
72   *dest = ceilf(*source);
73 }
74 void floor_l_s(float *source,long long *dest)
75 {
76   *dest = floorf(*source);
77 }
78 void floor_w_s(float *source,int *dest)
79 {
80   *dest = floorf(*source);
81 }
82
83 void round_l_d(double *source,long long *dest)
84 {
85   *dest = round(*source);
86 }
87 void round_w_d(double *source,int *dest)
88 {
89   *dest = round(*source);
90 }
91 void trunc_l_d(double *source,long long *dest)
92 {
93   *dest = trunc(*source);
94 }
95 void trunc_w_d(double *source,int *dest)
96 {
97   *dest = trunc(*source);
98 }
99 void ceil_l_d(double *source,long long *dest)
100 {
101   *dest = ceil(*source);
102 }
103 void ceil_w_d(double *source,int *dest)
104 {
105   *dest = ceil(*source);
106 }
107 void floor_l_d(double *source,long long *dest)
108 {
109   *dest = floor(*source);
110 }
111 void floor_w_d(double *source,int *dest)
112 {
113   *dest = floor(*source);
114 }
115
116 void cvt_w_s(float *source,int *dest)
117 {
118   switch(FCR31&3)
119   {
120     case 0: round_w_s(source,dest);return;
121     case 1: trunc_w_s(source,dest);return;
122     case 2: ceil_w_s(source,dest);return;
123     case 3: floor_w_s(source,dest);return;
124   }
125 }
126 void cvt_w_d(double *source,int *dest)
127 {
128   switch(FCR31&3)
129   {
130     case 0: round_w_d(source,dest);return;
131     case 1: trunc_w_d(source,dest);return;
132     case 2: ceil_w_d(source,dest);return;
133     case 3: floor_w_d(source,dest);return;
134   }
135 }
136 void cvt_l_s(float *source,long long *dest)
137 {
138   switch(FCR31&3)
139   {
140     case 0: round_l_s(source,dest);return;
141     case 1: trunc_l_s(source,dest);return;
142     case 2: ceil_l_s(source,dest);return;
143     case 3: floor_l_s(source,dest);return;
144   }
145 }
146 void cvt_l_d(double *source,long long *dest)
147 {
148   switch(FCR31&3)
149   {
150     case 0: round_l_d(source,dest);return;
151     case 1: trunc_l_d(source,dest);return;
152     case 2: ceil_l_d(source,dest);return;
153     case 3: floor_l_d(source,dest);return;
154   }
155 }
156
157 void c_f_s()
158 {
159   FCR31 &= ~0x800000;
160 }
161 void c_un_s(float *source,float *target)
162 {
163   FCR31=(isnan(*source) || isnan(*target)) ? FCR31|0x800000 : FCR31&~0x800000;
164 }
165                           
166 void c_eq_s(float *source,float *target)
167 {
168   if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
169   FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
170 }
171 void c_ueq_s(float *source,float *target)
172 {
173   if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
174   FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
175 }
176
177 void c_olt_s(float *source,float *target)
178 {
179   if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
180   FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
181 }
182 void c_ult_s(float *source,float *target)
183 {
184   if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
185   FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
186 }
187
188 void c_ole_s(float *source,float *target)
189 {
190   if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
191   FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
192 }
193 void c_ule_s(float *source,float *target)
194 {
195   if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
196   FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
197 }
198
199 void c_sf_s(float *source,float *target)
200 {
201   //if (isnan(*source) || isnan(*target)) // FIXME - exception
202   FCR31&=~0x800000;
203 }
204 void c_ngle_s(float *source,float *target)
205 {
206   //if (isnan(*source) || isnan(*target)) // FIXME - exception
207   FCR31&=~0x800000;
208 }
209
210 void c_seq_s(float *source,float *target)
211 {
212   //if (isnan(*source) || isnan(*target)) // FIXME - exception
213   FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
214 }
215 void c_ngl_s(float *source,float *target)
216 {
217   //if (isnan(*source) || isnan(*target)) // FIXME - exception
218   FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
219 }
220
221 void c_lt_s(float *source,float *target)
222 {
223   //if (isnan(*source) || isnan(*target)) // FIXME - exception
224   FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
225 }
226 void c_nge_s(float *source,float *target)
227 {
228   //if (isnan(*source) || isnan(*target)) // FIXME - exception
229   FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
230 }
231
232 void c_le_s(float *source,float *target)
233 {
234   //if (isnan(*source) || isnan(*target)) // FIXME - exception
235   FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
236 }
237 void c_ngt_s(float *source,float *target)
238 {
239   //if (isnan(*source) || isnan(*target)) // FIXME - exception
240   FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
241 }
242
243 void c_f_d()
244 {
245   FCR31 &= ~0x800000;
246 }
247 void c_un_d(double *source,double *target)
248 {
249   FCR31=(isnan(*source) || isnan(*target)) ? FCR31|0x800000 : FCR31&~0x800000;
250 }
251                           
252 void c_eq_d(double *source,double *target)
253 {
254   if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
255   FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
256 }
257 void c_ueq_d(double *source,double *target)
258 {
259   if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
260   FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
261 }
262
263 void c_olt_d(double *source,double *target)
264 {
265   if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
266   FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
267 }
268 void c_ult_d(double *source,double *target)
269 {
270   if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
271   FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
272 }
273
274 void c_ole_d(double *source,double *target)
275 {
276   if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
277   FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
278 }
279 void c_ule_d(double *source,double *target)
280 {
281   if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
282   FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
283 }
284
285 void c_sf_d(double *source,double *target)
286 {
287   //if (isnan(*source) || isnan(*target)) // FIXME - exception
288   FCR31&=~0x800000;
289 }
290 void c_ngle_d(double *source,double *target)
291 {
292   //if (isnan(*source) || isnan(*target)) // FIXME - exception
293   FCR31&=~0x800000;
294 }
295
296 void c_seq_d(double *source,double *target)
297 {
298   //if (isnan(*source) || isnan(*target)) // FIXME - exception
299   FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
300 }
301 void c_ngl_d(double *source,double *target)
302 {
303   //if (isnan(*source) || isnan(*target)) // FIXME - exception
304   FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
305 }
306
307 void c_lt_d(double *source,double *target)
308 {
309   //if (isnan(*source) || isnan(*target)) // FIXME - exception
310   FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
311 }
312 void c_nge_d(double *source,double *target)
313 {
314   //if (isnan(*source) || isnan(*target)) // FIXME - exception
315   FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
316 }
317
318 void c_le_d(double *source,double *target)
319 {
320   //if (isnan(*source) || isnan(*target)) // FIXME - exception
321   FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
322 }
323 void c_ngt_d(double *source,double *target)
324 {
325   //if (isnan(*source) || isnan(*target)) // FIXME - exception
326   FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
327 }
328
329
330 void add_s(float *source1,float *source2,float *target)
331 {
332   *target=(*source1)+(*source2);
333 }
334 void sub_s(float *source1,float *source2,float *target)
335 {
336   *target=(*source1)-(*source2);
337 }
338 void mul_s(float *source1,float *source2,float *target)
339 {
340   *target=(*source1)*(*source2);
341 }
342 void div_s(float *source1,float *source2,float *target)
343 {
344   *target=(*source1)/(*source2);
345 }
346 void sqrt_s(float *source,float *target)
347 {
348   *target=sqrtf(*source);
349 }
350 void abs_s(float *source,float *target)
351 {
352   *target=fabsf(*source);
353 }
354 void mov_s(float *source,float *target)
355 {
356   *target=*source;
357 }
358 void neg_s(float *source,float *target)
359 {
360   *target=-(*source);
361 }
362 void add_d(double *source1,double *source2,double *target)
363 {
364   *target=(*source1)+(*source2);
365 }
366 void sub_d(double *source1,double *source2,double *target)
367 {
368   *target=(*source1)-(*source2);
369 }
370 void mul_d(double *source1,double *source2,double *target)
371 {
372   *target=(*source1)*(*source2);
373 }
374 void div_d(double *source1,double *source2,double *target)
375 {
376   *target=(*source1)/(*source2);
377 }
378 void sqrt_d(double *source,double *target)
379 {
380   *target=sqrt(*source);
381 }
382 void abs_d(double *source,double *target)
383 {
384   *target=fabs(*source);
385 }
386 void mov_d(double *source,double *target)
387 {
388   *target=*source;
389 }
390 void neg_d(double *source,double *target)
391 {
392   *target=-(*source);
393 }
394