1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - fpu.c *
3 * Copyright (C) 2010 Ari64 *
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. *
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. *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23 extern int FCR0, FCR31;
25 void cvt_s_w(int *source,float *dest)
29 void cvt_d_w(int *source,double *dest)
33 void cvt_s_l(long long *source,float *dest)
37 void cvt_d_l(long long *source,double *dest)
41 void cvt_d_s(float *source,double *dest)
45 void cvt_s_d(double *source,float *dest)
50 void round_l_s(float *source,long long *dest)
52 *dest = roundf(*source);
54 void round_w_s(float *source,int *dest)
56 *dest = roundf(*source);
58 void trunc_l_s(float *source,long long *dest)
60 *dest = truncf(*source);
62 void trunc_w_s(float *source,int *dest)
64 *dest = truncf(*source);
66 void ceil_l_s(float *source,long long *dest)
68 *dest = ceilf(*source);
70 void ceil_w_s(float *source,int *dest)
72 *dest = ceilf(*source);
74 void floor_l_s(float *source,long long *dest)
76 *dest = floorf(*source);
78 void floor_w_s(float *source,int *dest)
80 *dest = floorf(*source);
83 void round_l_d(double *source,long long *dest)
85 *dest = round(*source);
87 void round_w_d(double *source,int *dest)
89 *dest = round(*source);
91 void trunc_l_d(double *source,long long *dest)
93 *dest = trunc(*source);
95 void trunc_w_d(double *source,int *dest)
97 *dest = trunc(*source);
99 void ceil_l_d(double *source,long long *dest)
101 *dest = ceil(*source);
103 void ceil_w_d(double *source,int *dest)
105 *dest = ceil(*source);
107 void floor_l_d(double *source,long long *dest)
109 *dest = floor(*source);
111 void floor_w_d(double *source,int *dest)
113 *dest = floor(*source);
116 void cvt_w_s(float *source,int *dest)
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;
126 void cvt_w_d(double *source,int *dest)
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;
136 void cvt_l_s(float *source,long long *dest)
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;
146 void cvt_l_d(double *source,long long *dest)
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;
161 void c_un_s(float *source,float *target)
163 FCR31=(isnan(*source) || isnan(*target)) ? FCR31|0x800000 : FCR31&~0x800000;
166 void c_eq_s(float *source,float *target)
168 if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
169 FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
171 void c_ueq_s(float *source,float *target)
173 if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
174 FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
177 void c_olt_s(float *source,float *target)
179 if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
180 FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
182 void c_ult_s(float *source,float *target)
184 if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
185 FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
188 void c_ole_s(float *source,float *target)
190 if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
191 FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
193 void c_ule_s(float *source,float *target)
195 if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
196 FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
199 void c_sf_s(float *source,float *target)
201 //if (isnan(*source) || isnan(*target)) // FIXME - exception
204 void c_ngle_s(float *source,float *target)
206 //if (isnan(*source) || isnan(*target)) // FIXME - exception
210 void c_seq_s(float *source,float *target)
212 //if (isnan(*source) || isnan(*target)) // FIXME - exception
213 FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
215 void c_ngl_s(float *source,float *target)
217 //if (isnan(*source) || isnan(*target)) // FIXME - exception
218 FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
221 void c_lt_s(float *source,float *target)
223 //if (isnan(*source) || isnan(*target)) // FIXME - exception
224 FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
226 void c_nge_s(float *source,float *target)
228 //if (isnan(*source) || isnan(*target)) // FIXME - exception
229 FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
232 void c_le_s(float *source,float *target)
234 //if (isnan(*source) || isnan(*target)) // FIXME - exception
235 FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
237 void c_ngt_s(float *source,float *target)
239 //if (isnan(*source) || isnan(*target)) // FIXME - exception
240 FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
247 void c_un_d(double *source,double *target)
249 FCR31=(isnan(*source) || isnan(*target)) ? FCR31|0x800000 : FCR31&~0x800000;
252 void c_eq_d(double *source,double *target)
254 if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
255 FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
257 void c_ueq_d(double *source,double *target)
259 if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
260 FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
263 void c_olt_d(double *source,double *target)
265 if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
266 FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
268 void c_ult_d(double *source,double *target)
270 if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
271 FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
274 void c_ole_d(double *source,double *target)
276 if (isnan(*source) || isnan(*target)) {FCR31&=~0x800000;return;}
277 FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
279 void c_ule_d(double *source,double *target)
281 if (isnan(*source) || isnan(*target)) {FCR31|=0x800000;return;}
282 FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
285 void c_sf_d(double *source,double *target)
287 //if (isnan(*source) || isnan(*target)) // FIXME - exception
290 void c_ngle_d(double *source,double *target)
292 //if (isnan(*source) || isnan(*target)) // FIXME - exception
296 void c_seq_d(double *source,double *target)
298 //if (isnan(*source) || isnan(*target)) // FIXME - exception
299 FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
301 void c_ngl_d(double *source,double *target)
303 //if (isnan(*source) || isnan(*target)) // FIXME - exception
304 FCR31 = *source==*target ? FCR31|0x800000 : FCR31&~0x800000;
307 void c_lt_d(double *source,double *target)
309 //if (isnan(*source) || isnan(*target)) // FIXME - exception
310 FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
312 void c_nge_d(double *source,double *target)
314 //if (isnan(*source) || isnan(*target)) // FIXME - exception
315 FCR31 = *source<*target ? FCR31|0x800000 : FCR31&~0x800000;
318 void c_le_d(double *source,double *target)
320 //if (isnan(*source) || isnan(*target)) // FIXME - exception
321 FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
323 void c_ngt_d(double *source,double *target)
325 //if (isnan(*source) || isnan(*target)) // FIXME - exception
326 FCR31 = *source<=*target ? FCR31|0x800000 : FCR31&~0x800000;
330 void add_s(float *source1,float *source2,float *target)
332 *target=(*source1)+(*source2);
334 void sub_s(float *source1,float *source2,float *target)
336 *target=(*source1)-(*source2);
338 void mul_s(float *source1,float *source2,float *target)
340 *target=(*source1)*(*source2);
342 void div_s(float *source1,float *source2,float *target)
344 *target=(*source1)/(*source2);
346 void sqrt_s(float *source,float *target)
348 *target=sqrtf(*source);
350 void abs_s(float *source,float *target)
352 *target=fabsf(*source);
354 void mov_s(float *source,float *target)
358 void neg_s(float *source,float *target)
362 void add_d(double *source1,double *source2,double *target)
364 *target=(*source1)+(*source2);
366 void sub_d(double *source1,double *source2,double *target)
368 *target=(*source1)-(*source2);
370 void mul_d(double *source1,double *source2,double *target)
372 *target=(*source1)*(*source2);
374 void div_d(double *source1,double *source2,double *target)
376 *target=(*source1)/(*source2);
378 void sqrt_d(double *source,double *target)
380 *target=sqrt(*source);
382 void abs_d(double *source,double *target)
384 *target=fabs(*source);
386 void mov_d(double *source,double *target)
390 void neg_d(double *source,double *target)