1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - interpreter_cop1.def *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 DECLARE_JUMP(BC1F, PCADDR + (iimmediate+1)*4, (FCR31 & 0x800000)==0, ®[0], 0, 1)
25 DECLARE_JUMP(BC1T, PCADDR + (iimmediate+1)*4, (FCR31 & 0x800000)!=0, ®[0], 0, 1)
26 DECLARE_JUMP(BC1FL, PCADDR + (iimmediate+1)*4, (FCR31 & 0x800000)==0, ®[0], 1, 1)
27 DECLARE_JUMP(BC1TL, PCADDR + (iimmediate+1)*4, (FCR31 & 0x800000)!=0, ®[0], 1, 1)
29 DECLARE_INSTRUCTION(MFC1)
31 if (check_cop1_unusable()) return;
32 rrt32 = *((int*)reg_cop1_simple[rfs]);
37 DECLARE_INSTRUCTION(DMFC1)
39 if (check_cop1_unusable()) return;
40 rrt = *((long long*)reg_cop1_double[rfs]);
44 DECLARE_INSTRUCTION(CFC1)
46 if (check_cop1_unusable()) return;
60 DECLARE_INSTRUCTION(MTC1)
62 if (check_cop1_unusable()) return;
63 *((int*)reg_cop1_simple[rfs]) = rrt32;
67 DECLARE_INSTRUCTION(DMTC1)
69 if (check_cop1_unusable()) return;
70 *((long long*)reg_cop1_double[rfs]) = rrt;
74 DECLARE_INSTRUCTION(CTC1)
76 if (check_cop1_unusable()) return;
82 rounding_mode = 0x33F; // Round to nearest, or to even if equidistant
85 rounding_mode = 0xF3F; // Truncate (toward 0)
88 rounding_mode = 0xB3F; // Round up (toward +infinity)
91 rounding_mode = 0x73F; // Round down (toward -infinity)
94 //if ((FCR31 >> 7) & 0x1F) printf("FPU Exception enabled : %x\n",
95 // (int)((FCR31 >> 7) & 0x1F));
100 DECLARE_INSTRUCTION(ADD_D)
102 if (check_cop1_unusable()) return;
103 add_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]);
107 DECLARE_INSTRUCTION(SUB_D)
109 if (check_cop1_unusable()) return;
110 sub_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]);
114 DECLARE_INSTRUCTION(MUL_D)
116 if (check_cop1_unusable()) return;
117 mul_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]);
121 DECLARE_INSTRUCTION(DIV_D)
123 if (check_cop1_unusable()) return;
124 if((FCR31 & 0x400) && *reg_cop1_double[cfft] == 0)
129 exception_general();*/
130 DebugMessage(M64MSG_ERROR, "DIV_D by 0");
133 div_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]);
137 DECLARE_INSTRUCTION(SQRT_D)
139 if (check_cop1_unusable()) return;
140 sqrt_d(reg_cop1_double[cffs], reg_cop1_double[cffd]);
144 DECLARE_INSTRUCTION(ABS_D)
146 if (check_cop1_unusable()) return;
147 abs_d(reg_cop1_double[cffs], reg_cop1_double[cffd]);
151 DECLARE_INSTRUCTION(MOV_D)
153 if (check_cop1_unusable()) return;
154 mov_d(reg_cop1_double[cffs], reg_cop1_double[cffd]);
158 DECLARE_INSTRUCTION(NEG_D)
160 if (check_cop1_unusable()) return;
161 neg_d(reg_cop1_double[cffs], reg_cop1_double[cffd]);
165 DECLARE_INSTRUCTION(ROUND_L_D)
167 if (check_cop1_unusable()) return;
168 round_l_d(reg_cop1_double[cffs], (long long*)(reg_cop1_double[cffd]));
172 DECLARE_INSTRUCTION(TRUNC_L_D)
174 if (check_cop1_unusable()) return;
175 trunc_l_d(reg_cop1_double[cffs], (long long*)(reg_cop1_double[cffd]));
179 DECLARE_INSTRUCTION(CEIL_L_D)
181 if (check_cop1_unusable()) return;
182 ceil_l_d(reg_cop1_double[cffs], (long long*)(reg_cop1_double[cffd]));
186 DECLARE_INSTRUCTION(FLOOR_L_D)
188 if (check_cop1_unusable()) return;
189 floor_l_d(reg_cop1_double[cffs], (long long*)(reg_cop1_double[cffd]));
193 DECLARE_INSTRUCTION(ROUND_W_D)
195 if (check_cop1_unusable()) return;
196 round_w_d(reg_cop1_double[cffs], (int*)reg_cop1_simple[cffd]);
200 DECLARE_INSTRUCTION(TRUNC_W_D)
202 if (check_cop1_unusable()) return;
203 trunc_w_d(reg_cop1_double[cffs], (int*)reg_cop1_simple[cffd]);
207 DECLARE_INSTRUCTION(CEIL_W_D)
209 if (check_cop1_unusable()) return;
210 ceil_w_d(reg_cop1_double[cffs], (int*)reg_cop1_simple[cffd]);
214 DECLARE_INSTRUCTION(FLOOR_W_D)
216 if (check_cop1_unusable()) return;
217 floor_w_d(reg_cop1_double[cffs], (int*)reg_cop1_simple[cffd]);
221 DECLARE_INSTRUCTION(CVT_S_D)
223 if (check_cop1_unusable()) return;
224 cvt_s_d(reg_cop1_double[cffs], reg_cop1_simple[cffd]);
228 DECLARE_INSTRUCTION(CVT_W_D)
230 if (check_cop1_unusable()) return;
231 cvt_w_d(reg_cop1_double[cffs], (int*)reg_cop1_simple[cffd]);
235 DECLARE_INSTRUCTION(CVT_L_D)
237 if (check_cop1_unusable()) return;
238 cvt_l_d(reg_cop1_double[cffs], (long long*)(reg_cop1_double[cffd]));
242 DECLARE_INSTRUCTION(C_F_D)
244 if (check_cop1_unusable()) return;
249 DECLARE_INSTRUCTION(C_UN_D)
251 if (check_cop1_unusable()) return;
252 c_un_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
256 DECLARE_INSTRUCTION(C_EQ_D)
258 if (check_cop1_unusable()) return;
259 c_eq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
263 DECLARE_INSTRUCTION(C_UEQ_D)
265 if (check_cop1_unusable()) return;
266 c_ueq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
270 DECLARE_INSTRUCTION(C_OLT_D)
272 if (check_cop1_unusable()) return;
273 c_olt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
277 DECLARE_INSTRUCTION(C_ULT_D)
279 if (check_cop1_unusable()) return;
280 c_ult_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
284 DECLARE_INSTRUCTION(C_OLE_D)
286 if (check_cop1_unusable()) return;
287 c_ole_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
291 DECLARE_INSTRUCTION(C_ULE_D)
293 if (check_cop1_unusable()) return;
294 c_ule_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
298 DECLARE_INSTRUCTION(C_SF_D)
300 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
302 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
305 c_sf_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
309 DECLARE_INSTRUCTION(C_NGLE_D)
311 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
313 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
316 c_ngle_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
320 DECLARE_INSTRUCTION(C_SEQ_D)
322 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
324 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
327 c_seq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
331 DECLARE_INSTRUCTION(C_NGL_D)
333 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
335 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
338 c_ngl_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
342 DECLARE_INSTRUCTION(C_LT_D)
344 if (check_cop1_unusable()) return;
345 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
347 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
350 c_lt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
354 DECLARE_INSTRUCTION(C_NGE_D)
356 if (check_cop1_unusable()) return;
357 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
359 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
362 c_nge_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
366 DECLARE_INSTRUCTION(C_LE_D)
368 if (check_cop1_unusable()) return;
369 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
371 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
374 c_le_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
378 DECLARE_INSTRUCTION(C_NGT_D)
380 if (check_cop1_unusable()) return;
381 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft]))
383 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
386 c_ngt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]);
391 DECLARE_INSTRUCTION(CVT_S_L)
393 if (check_cop1_unusable()) return;
394 cvt_s_l((long long*)(reg_cop1_double[cffs]), reg_cop1_simple[cffd]);
398 DECLARE_INSTRUCTION(CVT_D_L)
400 if (check_cop1_unusable()) return;
401 cvt_d_l((long long*)(reg_cop1_double[cffs]), reg_cop1_double[cffd]);
406 DECLARE_INSTRUCTION(ADD_S)
408 if (check_cop1_unusable()) return;
409 add_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]);
413 DECLARE_INSTRUCTION(SUB_S)
415 if (check_cop1_unusable()) return;
416 sub_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]);
420 DECLARE_INSTRUCTION(MUL_S)
422 if (check_cop1_unusable()) return;
423 mul_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]);
427 DECLARE_INSTRUCTION(DIV_S)
429 if (check_cop1_unusable()) return;
430 if((FCR31 & 0x400) && *reg_cop1_simple[cfft] == 0)
432 DebugMessage(M64MSG_ERROR, "DIV_S by 0");
434 div_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]);
438 DECLARE_INSTRUCTION(SQRT_S)
440 if (check_cop1_unusable()) return;
441 sqrt_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
445 DECLARE_INSTRUCTION(ABS_S)
447 if (check_cop1_unusable()) return;
448 abs_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
452 DECLARE_INSTRUCTION(MOV_S)
454 if (check_cop1_unusable()) return;
455 mov_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
459 DECLARE_INSTRUCTION(NEG_S)
461 if (check_cop1_unusable()) return;
462 neg_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
466 DECLARE_INSTRUCTION(ROUND_L_S)
468 if (check_cop1_unusable()) return;
469 round_l_s(reg_cop1_simple[cffs], (long long*)(reg_cop1_double[cffd]));
473 DECLARE_INSTRUCTION(TRUNC_L_S)
475 if (check_cop1_unusable()) return;
476 trunc_l_s(reg_cop1_simple[cffs], (long long*)(reg_cop1_double[cffd]));
480 DECLARE_INSTRUCTION(CEIL_L_S)
482 if (check_cop1_unusable()) return;
483 ceil_l_s(reg_cop1_simple[cffs], (long long*)(reg_cop1_double[cffd]));
487 DECLARE_INSTRUCTION(FLOOR_L_S)
489 if (check_cop1_unusable()) return;
490 floor_l_s(reg_cop1_simple[cffs], (long long*)(reg_cop1_double[cffd]));
494 DECLARE_INSTRUCTION(ROUND_W_S)
496 if (check_cop1_unusable()) return;
497 round_w_s(reg_cop1_simple[cffs], (int*)reg_cop1_simple[cffd]);
501 DECLARE_INSTRUCTION(TRUNC_W_S)
503 if (check_cop1_unusable()) return;
504 trunc_w_s(reg_cop1_simple[cffs], (int*)reg_cop1_simple[cffd]);
508 DECLARE_INSTRUCTION(CEIL_W_S)
510 if (check_cop1_unusable()) return;
511 ceil_w_s(reg_cop1_simple[cffs], (int*)reg_cop1_simple[cffd]);
515 DECLARE_INSTRUCTION(FLOOR_W_S)
517 if (check_cop1_unusable()) return;
518 floor_w_s(reg_cop1_simple[cffs], (int*)reg_cop1_simple[cffd]);
522 DECLARE_INSTRUCTION(CVT_D_S)
524 if (check_cop1_unusable()) return;
525 cvt_d_s(reg_cop1_simple[cffs], reg_cop1_double[cffd]);
529 DECLARE_INSTRUCTION(CVT_W_S)
531 if (check_cop1_unusable()) return;
532 cvt_w_s(reg_cop1_simple[cffs], (int*)reg_cop1_simple[cffd]);
536 DECLARE_INSTRUCTION(CVT_L_S)
538 if (check_cop1_unusable()) return;
539 cvt_l_s(reg_cop1_simple[cffs], (long long*)(reg_cop1_double[cffd]));
543 DECLARE_INSTRUCTION(C_F_S)
545 if (check_cop1_unusable()) return;
550 DECLARE_INSTRUCTION(C_UN_S)
552 if (check_cop1_unusable()) return;
553 c_un_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
557 DECLARE_INSTRUCTION(C_EQ_S)
559 if (check_cop1_unusable()) return;
560 c_eq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
564 DECLARE_INSTRUCTION(C_UEQ_S)
566 if (check_cop1_unusable()) return;
567 c_ueq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
571 DECLARE_INSTRUCTION(C_OLT_S)
573 if (check_cop1_unusable()) return;
574 c_olt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
578 DECLARE_INSTRUCTION(C_ULT_S)
580 if (check_cop1_unusable()) return;
581 c_ult_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
585 DECLARE_INSTRUCTION(C_OLE_S)
587 if (check_cop1_unusable()) return;
588 c_ole_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
592 DECLARE_INSTRUCTION(C_ULE_S)
594 if (check_cop1_unusable()) return;
595 c_ule_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
599 DECLARE_INSTRUCTION(C_SF_S)
601 if (check_cop1_unusable()) return;
602 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
604 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
607 c_sf_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
611 DECLARE_INSTRUCTION(C_NGLE_S)
613 if (check_cop1_unusable()) return;
614 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
616 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
619 c_ngle_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
623 DECLARE_INSTRUCTION(C_SEQ_S)
625 if (check_cop1_unusable()) return;
626 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
628 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
631 c_seq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
635 DECLARE_INSTRUCTION(C_NGL_S)
637 if (check_cop1_unusable()) return;
638 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
640 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
643 c_ngl_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
647 DECLARE_INSTRUCTION(C_LT_S)
649 if (check_cop1_unusable()) return;
650 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
652 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
655 c_lt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
659 DECLARE_INSTRUCTION(C_NGE_S)
661 if (check_cop1_unusable()) return;
662 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
664 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
667 c_nge_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
671 DECLARE_INSTRUCTION(C_LE_S)
673 if (check_cop1_unusable()) return;
674 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
676 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
679 c_le_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
683 DECLARE_INSTRUCTION(C_NGT_S)
685 if (check_cop1_unusable()) return;
686 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft]))
688 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode");
691 c_ngt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]);
696 DECLARE_INSTRUCTION(CVT_S_W)
698 if (check_cop1_unusable()) return;
699 cvt_s_w((int*)reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
703 DECLARE_INSTRUCTION(CVT_D_W)
705 if (check_cop1_unusable()) return;
706 cvt_d_w((int*)reg_cop1_simple[cffs], reg_cop1_double[cffd]);