drc: handle invalidate on clear() calls and reset
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / fpu.c
CommitLineData
57871462 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
23extern int FCR0, FCR31;
24
25void cvt_s_w(int *source,float *dest)
26{
27 *dest = *source;
28}
29void cvt_d_w(int *source,double *dest)
30{
31 *dest = *source;
32}
33void cvt_s_l(long long *source,float *dest)
34{
35 *dest = *source;
36}
37void cvt_d_l(long long *source,double *dest)
38{
39 *dest = *source;
40}
41void cvt_d_s(float *source,double *dest)
42{
43 *dest = *source;
44}
45void cvt_s_d(double *source,float *dest)
46{
47 *dest = *source;
48}
49
50void round_l_s(float *source,long long *dest)
51{
52 *dest = roundf(*source);
53}
54void round_w_s(float *source,int *dest)
55{
56 *dest = roundf(*source);
57}
58void trunc_l_s(float *source,long long *dest)
59{
60 *dest = truncf(*source);
61}
62void trunc_w_s(float *source,int *dest)
63{
64 *dest = truncf(*source);
65}
66void ceil_l_s(float *source,long long *dest)
67{
68 *dest = ceilf(*source);
69}
70void ceil_w_s(float *source,int *dest)
71{
72 *dest = ceilf(*source);
73}
74void floor_l_s(float *source,long long *dest)
75{
76 *dest = floorf(*source);
77}
78void floor_w_s(float *source,int *dest)
79{
80 *dest = floorf(*source);
81}
82
83void round_l_d(double *source,long long *dest)
84{
85 *dest = round(*source);
86}
87void round_w_d(double *source,int *dest)
88{
89 *dest = round(*source);
90}
91void trunc_l_d(double *source,long long *dest)
92{
93 *dest = trunc(*source);
94}
95void trunc_w_d(double *source,int *dest)
96{
97 *dest = trunc(*source);
98}
99void ceil_l_d(double *source,long long *dest)
100{
101 *dest = ceil(*source);
102}
103void ceil_w_d(double *source,int *dest)
104{
105 *dest = ceil(*source);
106}
107void floor_l_d(double *source,long long *dest)
108{
109 *dest = floor(*source);
110}
111void floor_w_d(double *source,int *dest)
112{
113 *dest = floor(*source);
114}
115
116void 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}
126void 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}
136void 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}
146void 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
157void c_f_s()
158{
159 FCR31 &= ~0x800000;
160}
161void c_un_s(float *source,float *target)
162{
163 FCR31=(isnan(*source) || isnan(*target)) ? FCR31|0x800000 : FCR31&~0x800000;
164}
165
166void 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}
171void 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
177void 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}
182void 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
188void 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}
193void 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
199void c_sf_s(float *source,float *target)
200{
201 //if (isnan(*source) || isnan(*target)) // FIXME - exception
202 FCR31&=~0x800000;
203}
204void c_ngle_s(float *source,float *target)
205{
206 //if (isnan(*source) || isnan(*target)) // FIXME - exception
207 FCR31&=~0x800000;
208}
209
210void 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}
215void 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
221void 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}
226void 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
232void 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}
237void 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
243void c_f_d()
244{
245 FCR31 &= ~0x800000;
246}
247void c_un_d(double *source,double *target)
248{
249 FCR31=(isnan(*source) || isnan(*target)) ? FCR31|0x800000 : FCR31&~0x800000;
250}
251
252void 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}
257void 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
263void 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}
268void 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
274void 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}
279void 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
285void c_sf_d(double *source,double *target)
286{
287 //if (isnan(*source) || isnan(*target)) // FIXME - exception
288 FCR31&=~0x800000;
289}
290void c_ngle_d(double *source,double *target)
291{
292 //if (isnan(*source) || isnan(*target)) // FIXME - exception
293 FCR31&=~0x800000;
294}
295
296void 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}
301void 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
307void 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}
312void 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
318void 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}
323void 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
330void add_s(float *source1,float *source2,float *target)
331{
332 *target=(*source1)+(*source2);
333}
334void sub_s(float *source1,float *source2,float *target)
335{
336 *target=(*source1)-(*source2);
337}
338void mul_s(float *source1,float *source2,float *target)
339{
340 *target=(*source1)*(*source2);
341}
342void div_s(float *source1,float *source2,float *target)
343{
344 *target=(*source1)/(*source2);
345}
346void sqrt_s(float *source,float *target)
347{
348 *target=sqrtf(*source);
349}
350void abs_s(float *source,float *target)
351{
352 *target=fabsf(*source);
353}
354void mov_s(float *source,float *target)
355{
356 *target=*source;
357}
358void neg_s(float *source,float *target)
359{
360 *target=-(*source);
361}
362void add_d(double *source1,double *source2,double *target)
363{
364 *target=(*source1)+(*source2);
365}
366void sub_d(double *source1,double *source2,double *target)
367{
368 *target=(*source1)-(*source2);
369}
370void mul_d(double *source1,double *source2,double *target)
371{
372 *target=(*source1)*(*source2);
373}
374void div_d(double *source1,double *source2,double *target)
375{
376 *target=(*source1)/(*source2);
377}
378void sqrt_d(double *source,double *target)
379{
380 *target=sqrt(*source);
381}
382void abs_d(double *source,double *target)
383{
384 *target=fabs(*source);
385}
386void mov_d(double *source,double *target)
387{
388 *target=*source;
389}
390void neg_d(double *source,double *target)
391{
392 *target=-(*source);
393}
394