1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - gcop1_d.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25 #include "interpret.h"
27 #include "r4300/recomph.h"
28 #include "r4300/r4300.h"
29 #include "r4300/ops.h"
33 #ifdef INTERPRET_ADD_D
34 gencallinterp((unsigned int)cached_interpreter_table.ADD_D, 0);
36 gencheck_cop1_unusable();
37 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
38 fld_preg32_qword(EAX);
39 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft]));
40 fadd_preg32_qword(EAX);
41 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
42 fstp_preg32_qword(EAX);
48 #ifdef INTERPRET_SUB_D
49 gencallinterp((unsigned int)cached_interpreter_table.SUB_D, 0);
51 gencheck_cop1_unusable();
52 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
53 fld_preg32_qword(EAX);
54 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft]));
55 fsub_preg32_qword(EAX);
56 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
57 fstp_preg32_qword(EAX);
63 #ifdef INTERPRET_MUL_D
64 gencallinterp((unsigned int)cached_interpreter_table.MUL_D, 0);
66 gencheck_cop1_unusable();
67 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
68 fld_preg32_qword(EAX);
69 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft]));
70 fmul_preg32_qword(EAX);
71 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
72 fstp_preg32_qword(EAX);
78 #ifdef INTERPRET_DIV_D
79 gencallinterp((unsigned int)cached_interpreter_table.DIV_D, 0);
81 gencheck_cop1_unusable();
82 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
83 fld_preg32_qword(EAX);
84 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft]));
85 fdiv_preg32_qword(EAX);
86 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
87 fstp_preg32_qword(EAX);
93 #ifdef INTERPRET_SQRT_D
94 gencallinterp((unsigned int)cached_interpreter_table.SQRT_D, 0);
96 gencheck_cop1_unusable();
97 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
98 fld_preg32_qword(EAX);
100 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
101 fstp_preg32_qword(EAX);
107 #ifdef INTERPRET_ABS_D
108 gencallinterp((unsigned int)cached_interpreter_table.ABS_D, 0);
110 gencheck_cop1_unusable();
111 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
112 fld_preg32_qword(EAX);
114 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
115 fstp_preg32_qword(EAX);
121 #ifdef INTERPRET_MOV_D
122 gencallinterp((unsigned int)cached_interpreter_table.MOV_D, 0);
124 gencheck_cop1_unusable();
125 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
126 mov_reg32_preg32(EBX, EAX);
127 mov_reg32_preg32pimm32(ECX, EAX, 4);
128 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
129 mov_preg32_reg32(EAX, EBX);
130 mov_preg32pimm32_reg32(EAX, 4, ECX);
136 #ifdef INTERPRET_NEG_D
137 gencallinterp((unsigned int)cached_interpreter_table.NEG_D, 0);
139 gencheck_cop1_unusable();
140 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
141 fld_preg32_qword(EAX);
143 mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
144 fstp_preg32_qword(EAX);
148 void genround_l_d(void)
150 #ifdef INTERPRET_ROUND_L_D
151 gencallinterp((unsigned int)cached_interpreter_table.ROUND_L_D, 0);
153 gencheck_cop1_unusable();
154 fldcw_m16((unsigned short*)&round_mode);
155 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
156 fld_preg32_qword(EAX);
157 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
158 fistp_preg32_qword(EAX);
159 fldcw_m16((unsigned short*)&rounding_mode);
163 void gentrunc_l_d(void)
165 #ifdef INTERPRET_TRUNC_L_D
166 gencallinterp((unsigned int)cached_interpreter_table.TRUNC_L_D, 0);
168 gencheck_cop1_unusable();
169 fldcw_m16((unsigned short*)&trunc_mode);
170 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
171 fld_preg32_qword(EAX);
172 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
173 fistp_preg32_qword(EAX);
174 fldcw_m16((unsigned short*)&rounding_mode);
178 void genceil_l_d(void)
180 #ifdef INTERPRET_CEIL_L_D
181 gencallinterp((unsigned int)cached_interpreter_table.CEIL_L_D, 0);
183 gencheck_cop1_unusable();
184 fldcw_m16((unsigned short*)&ceil_mode);
185 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
186 fld_preg32_qword(EAX);
187 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
188 fistp_preg32_qword(EAX);
189 fldcw_m16((unsigned short*)&rounding_mode);
193 void genfloor_l_d(void)
195 #ifdef INTERPRET_FLOOR_L_D
196 gencallinterp((unsigned int)cached_interpreter_table.FLOOR_L_D, 0);
198 gencheck_cop1_unusable();
199 fldcw_m16((unsigned short*)&floor_mode);
200 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
201 fld_preg32_qword(EAX);
202 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
203 fistp_preg32_qword(EAX);
204 fldcw_m16((unsigned short*)&rounding_mode);
208 void genround_w_d(void)
210 #ifdef INTERPRET_ROUND_W_D
211 gencallinterp((unsigned int)cached_interpreter_table.ROUND_W_D, 0);
213 gencheck_cop1_unusable();
214 fldcw_m16((unsigned short*)&round_mode);
215 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
216 fld_preg32_qword(EAX);
217 mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
218 fistp_preg32_dword(EAX);
219 fldcw_m16((unsigned short*)&rounding_mode);
223 void gentrunc_w_d(void)
225 #ifdef INTERPRET_TRUNC_W_D
226 gencallinterp((unsigned int)cached_interpreter_table.TRUNC_W_D, 0);
228 gencheck_cop1_unusable();
229 fldcw_m16((unsigned short*)&trunc_mode);
230 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
231 fld_preg32_qword(EAX);
232 mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
233 fistp_preg32_dword(EAX);
234 fldcw_m16((unsigned short*)&rounding_mode);
238 void genceil_w_d(void)
240 #ifdef INTERPRET_CEIL_W_D
241 gencallinterp((unsigned int)cached_interpreter_table.CEIL_W_D, 0);
243 gencheck_cop1_unusable();
244 fldcw_m16((unsigned short*)&ceil_mode);
245 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
246 fld_preg32_qword(EAX);
247 mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
248 fistp_preg32_dword(EAX);
249 fldcw_m16((unsigned short*)&rounding_mode);
253 void genfloor_w_d(void)
255 #ifdef INTERPRET_FLOOR_W_D
256 gencallinterp((unsigned int)cached_interpreter_table.FLOOR_W_D, 0);
258 gencheck_cop1_unusable();
259 fldcw_m16((unsigned short*)&floor_mode);
260 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
261 fld_preg32_qword(EAX);
262 mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
263 fistp_preg32_dword(EAX);
264 fldcw_m16((unsigned short*)&rounding_mode);
268 void gencvt_s_d(void)
270 #ifdef INTERPRET_CVT_S_D
271 gencallinterp((unsigned int)cached_interpreter_table.CVT_S_D, 0);
273 gencheck_cop1_unusable();
274 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
275 fld_preg32_qword(EAX);
276 mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
277 fstp_preg32_dword(EAX);
281 void gencvt_w_d(void)
283 #ifdef INTERPRET_CVT_W_D
284 gencallinterp((unsigned int)cached_interpreter_table.CVT_W_D, 0);
286 gencheck_cop1_unusable();
287 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
288 fld_preg32_qword(EAX);
289 mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
290 fistp_preg32_dword(EAX);
294 void gencvt_l_d(void)
296 #ifdef INTERPRET_CVT_L_D
297 gencallinterp((unsigned int)cached_interpreter_table.CVT_L_D, 0);
299 gencheck_cop1_unusable();
300 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
301 fld_preg32_qword(EAX);
302 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
303 fistp_preg32_qword(EAX);
309 #ifdef INTERPRET_C_F_D
310 gencallinterp((unsigned int)cached_interpreter_table.C_F_D, 0);
312 gencheck_cop1_unusable();
313 and_m32_imm32((unsigned int*)&FCR31, ~0x800000);
319 #ifdef INTERPRET_C_UN_D
320 gencallinterp((unsigned int)cached_interpreter_table.C_UN_D, 0);
322 gencheck_cop1_unusable();
323 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
324 fld_preg32_qword(EAX);
325 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
326 fld_preg32_qword(EAX);
330 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
331 jmp_imm_short(10); // 2
332 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
338 #ifdef INTERPRET_C_EQ_D
339 gencallinterp((unsigned int)cached_interpreter_table.C_EQ_D, 0);
341 gencheck_cop1_unusable();
342 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
343 fld_preg32_qword(EAX);
344 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
345 fld_preg32_qword(EAX);
349 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
350 jmp_imm_short(10); // 2
351 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
355 void genc_ueq_d(void)
357 #ifdef INTERPRET_C_UEQ_D
358 gencallinterp((unsigned int)cached_interpreter_table.C_UEQ_D, 0);
360 gencheck_cop1_unusable();
361 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
362 fld_preg32_qword(EAX);
363 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
364 fld_preg32_qword(EAX);
369 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
370 jmp_imm_short(10); // 2
371 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
375 void genc_olt_d(void)
377 #ifdef INTERPRET_C_OLT_D
378 gencallinterp((unsigned int)cached_interpreter_table.C_OLT_D, 0);
380 gencheck_cop1_unusable();
381 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
382 fld_preg32_qword(EAX);
383 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
384 fld_preg32_qword(EAX);
388 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
389 jmp_imm_short(10); // 2
390 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
394 void genc_ult_d(void)
396 #ifdef INTERPRET_C_ULT_D
397 gencallinterp((unsigned int)cached_interpreter_table.C_ULT_D, 0);
399 gencheck_cop1_unusable();
400 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
401 fld_preg32_qword(EAX);
402 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
403 fld_preg32_qword(EAX);
408 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
409 jmp_imm_short(10); // 2
410 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
414 void genc_ole_d(void)
416 #ifdef INTERPRET_C_OLE_D
417 gencallinterp((unsigned int)cached_interpreter_table.C_OLE_D, 0);
419 gencheck_cop1_unusable();
420 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
421 fld_preg32_qword(EAX);
422 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
423 fld_preg32_qword(EAX);
427 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
428 jmp_imm_short(10); // 2
429 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
433 void genc_ule_d(void)
435 #ifdef INTERPRET_C_ULE_D
436 gencallinterp((unsigned int)cached_interpreter_table.C_ULE_D, 0);
438 gencheck_cop1_unusable();
439 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
440 fld_preg32_qword(EAX);
441 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
442 fld_preg32_qword(EAX);
447 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
448 jmp_imm_short(10); // 2
449 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
455 #ifdef INTERPRET_C_SF_D
456 gencallinterp((unsigned int)cached_interpreter_table.C_SF_D, 0);
458 gencheck_cop1_unusable();
459 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
460 fld_preg32_qword(EAX);
461 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
462 fld_preg32_qword(EAX);
465 and_m32_imm32((unsigned int*)&FCR31, ~0x800000);
469 void genc_ngle_d(void)
471 #ifdef INTERPRET_C_NGLE_D
472 gencallinterp((unsigned int)cached_interpreter_table.C_NGLE_D, 0);
474 gencheck_cop1_unusable();
475 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
476 fld_preg32_qword(EAX);
477 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
478 fld_preg32_qword(EAX);
482 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
483 jmp_imm_short(10); // 2
484 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
488 void genc_seq_d(void)
490 #ifdef INTERPRET_C_SEQ_D
491 gencallinterp((unsigned int)cached_interpreter_table.C_SEQ_D, 0);
493 gencheck_cop1_unusable();
494 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
495 fld_preg32_qword(EAX);
496 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
497 fld_preg32_qword(EAX);
501 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
502 jmp_imm_short(10); // 2
503 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
507 void genc_ngl_d(void)
509 #ifdef INTERPRET_C_NGL_D
510 gencallinterp((unsigned int)cached_interpreter_table.C_NGL_D, 0);
512 gencheck_cop1_unusable();
513 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
514 fld_preg32_qword(EAX);
515 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
516 fld_preg32_qword(EAX);
521 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
522 jmp_imm_short(10); // 2
523 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
529 #ifdef INTERPRET_C_LT_D
530 gencallinterp((unsigned int)cached_interpreter_table.C_LT_D, 0);
532 gencheck_cop1_unusable();
533 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
534 fld_preg32_qword(EAX);
535 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
536 fld_preg32_qword(EAX);
540 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
541 jmp_imm_short(10); // 2
542 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
546 void genc_nge_d(void)
548 #ifdef INTERPRET_C_NGE_D
549 gencallinterp((unsigned int)cached_interpreter_table.C_NGE_D, 0);
551 gencheck_cop1_unusable();
552 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
553 fld_preg32_qword(EAX);
554 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
555 fld_preg32_qword(EAX);
560 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
561 jmp_imm_short(10); // 2
562 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
568 #ifdef INTERPRET_C_LE_D
569 gencallinterp((unsigned int)cached_interpreter_table.C_LE_D, 0);
571 gencheck_cop1_unusable();
572 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
573 fld_preg32_qword(EAX);
574 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
575 fld_preg32_qword(EAX);
579 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
580 jmp_imm_short(10); // 2
581 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
585 void genc_ngt_d(void)
587 #ifdef INTERPRET_C_NGT_D
588 gencallinterp((unsigned int)cached_interpreter_table.C_NGT_D, 0);
590 gencheck_cop1_unusable();
591 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
592 fld_preg32_qword(EAX);
593 mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
594 fld_preg32_qword(EAX);
599 or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
600 jmp_imm_short(10); // 2
601 and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10