1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - recomp.h *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 #include "api/m64p_types.h"
33 #include "api/callbacks.h"
34 #include "memory/memory.h"
37 #include "recomph.h" //include for function prototypes
42 static void *malloc_exec(size_t size);
43 static void free_exec(void *ptr, size_t length);
46 precomp_instr *dst; // destination structure for the recompiled instruction
47 int code_length; // current real recompiled code length
48 int max_code_length; // current recompiled code's buffer length
49 unsigned char **inst_pointer; // output buffer for recompiled code
50 precomp_block *dst_block; // the current block that we are recompiling
51 int src; // the current recompiled instruction
54 static void (*recomp_func)(void); // pointer to the dynarec's generator
55 // function for the latest decoded opcode
57 #if defined(PROFILE_R4300)
61 static int *SRC; // currently recompiled instruction in the input stream
62 static int check_nop; // next instruction is nop ?
63 static int delay_slot_compiled = 0;
69 dst->ops = current_instruction_table.RESERVED;
70 recomp_func = genreserved;
73 static void RFIN_BLOCK(void)
75 dst->ops = current_instruction_table.FIN_BLOCK;
76 recomp_func = genfin_block;
79 static void RNOTCOMPILED(void)
81 dst->ops = current_instruction_table.NOTCOMPILED;
82 recomp_func = gennotcompiled;
85 static void recompile_standard_i_type(void)
87 dst->f.i.rs = reg + ((src >> 21) & 0x1F);
88 dst->f.i.rt = reg + ((src >> 16) & 0x1F);
89 dst->f.i.immediate = src & 0xFFFF;
92 static void recompile_standard_j_type(void)
94 dst->f.j.inst_index = src & 0x3FFFFFF;
97 static void recompile_standard_r_type(void)
99 dst->f.r.rs = reg + ((src >> 21) & 0x1F);
100 dst->f.r.rt = reg + ((src >> 16) & 0x1F);
101 dst->f.r.rd = reg + ((src >> 11) & 0x1F);
102 dst->f.r.sa = (src >> 6) & 0x1F;
105 static void recompile_standard_lf_type(void)
107 dst->f.lf.base = (src >> 21) & 0x1F;
108 dst->f.lf.ft = (src >> 16) & 0x1F;
109 dst->f.lf.offset = src & 0xFFFF;
112 static void recompile_standard_cf_type(void)
114 dst->f.cf.ft = (src >> 16) & 0x1F;
115 dst->f.cf.fs = (src >> 11) & 0x1F;
116 dst->f.cf.fd = (src >> 6) & 0x1F;
119 //-------------------------------------------------------------------------
121 //-------------------------------------------------------------------------
123 static void RNOP(void)
125 dst->ops = current_instruction_table.NOP;
126 recomp_func = gennop;
129 static void RSLL(void)
131 dst->ops = current_instruction_table.SLL;
132 recomp_func = gensll;
133 recompile_standard_r_type();
134 if (dst->f.r.rd == reg) RNOP();
137 static void RSRL(void)
139 dst->ops = current_instruction_table.SRL;
140 recomp_func = gensrl;
141 recompile_standard_r_type();
142 if (dst->f.r.rd == reg) RNOP();
145 static void RSRA(void)
147 dst->ops = current_instruction_table.SRA;
148 recomp_func = gensra;
149 recompile_standard_r_type();
150 if (dst->f.r.rd == reg) RNOP();
153 static void RSLLV(void)
155 dst->ops = current_instruction_table.SLLV;
156 recomp_func = gensllv;
157 recompile_standard_r_type();
158 if (dst->f.r.rd == reg) RNOP();
161 static void RSRLV(void)
163 dst->ops = current_instruction_table.SRLV;
164 recomp_func = gensrlv;
165 recompile_standard_r_type();
166 if (dst->f.r.rd == reg) RNOP();
169 static void RSRAV(void)
171 dst->ops = current_instruction_table.SRAV;
172 recomp_func = gensrav;
173 recompile_standard_r_type();
174 if (dst->f.r.rd == reg) RNOP();
177 static void RJR(void)
179 dst->ops = current_instruction_table.JR;
181 recompile_standard_i_type();
184 static void RJALR(void)
186 dst->ops = current_instruction_table.JALR;
187 recomp_func = genjalr;
188 recompile_standard_r_type();
191 static void RSYSCALL(void)
193 dst->ops = current_instruction_table.SYSCALL;
194 recomp_func = gensyscall;
197 static void RBREAK(void)
199 dst->ops = current_instruction_table.NI;
203 static void RSYNC(void)
205 dst->ops = current_instruction_table.SYNC;
206 recomp_func = gensync;
209 static void RMFHI(void)
211 dst->ops = current_instruction_table.MFHI;
212 recomp_func = genmfhi;
213 recompile_standard_r_type();
214 if (dst->f.r.rd == reg) RNOP();
217 static void RMTHI(void)
219 dst->ops = current_instruction_table.MTHI;
220 recomp_func = genmthi;
221 recompile_standard_r_type();
224 static void RMFLO(void)
226 dst->ops = current_instruction_table.MFLO;
227 recomp_func = genmflo;
228 recompile_standard_r_type();
229 if (dst->f.r.rd == reg) RNOP();
232 static void RMTLO(void)
234 dst->ops = current_instruction_table.MTLO;
235 recomp_func = genmtlo;
236 recompile_standard_r_type();
239 static void RDSLLV(void)
241 dst->ops = current_instruction_table.DSLLV;
242 recomp_func = gendsllv;
243 recompile_standard_r_type();
244 if (dst->f.r.rd == reg) RNOP();
247 static void RDSRLV(void)
249 dst->ops = current_instruction_table.DSRLV;
250 recomp_func = gendsrlv;
251 recompile_standard_r_type();
252 if (dst->f.r.rd == reg) RNOP();
255 static void RDSRAV(void)
257 dst->ops = current_instruction_table.DSRAV;
258 recomp_func = gendsrav;
259 recompile_standard_r_type();
260 if (dst->f.r.rd == reg) RNOP();
263 static void RMULT(void)
265 dst->ops = current_instruction_table.MULT;
266 recomp_func = genmult;
267 recompile_standard_r_type();
270 static void RMULTU(void)
272 dst->ops = current_instruction_table.MULTU;
273 recomp_func = genmultu;
274 recompile_standard_r_type();
277 static void RDIV(void)
279 dst->ops = current_instruction_table.DIV;
280 recomp_func = gendiv;
281 recompile_standard_r_type();
284 static void RDIVU(void)
286 dst->ops = current_instruction_table.DIVU;
287 recomp_func = gendivu;
288 recompile_standard_r_type();
291 static void RDMULT(void)
293 dst->ops = current_instruction_table.DMULT;
294 recomp_func = gendmult;
295 recompile_standard_r_type();
298 static void RDMULTU(void)
300 dst->ops = current_instruction_table.DMULTU;
301 recomp_func = gendmultu;
302 recompile_standard_r_type();
305 static void RDDIV(void)
307 dst->ops = current_instruction_table.DDIV;
308 recomp_func = genddiv;
309 recompile_standard_r_type();
312 static void RDDIVU(void)
314 dst->ops = current_instruction_table.DDIVU;
315 recomp_func = genddivu;
316 recompile_standard_r_type();
319 static void RADD(void)
321 dst->ops = current_instruction_table.ADD;
322 recomp_func = genadd;
323 recompile_standard_r_type();
324 if (dst->f.r.rd == reg) RNOP();
327 static void RADDU(void)
329 dst->ops = current_instruction_table.ADDU;
330 recomp_func = genaddu;
331 recompile_standard_r_type();
332 if (dst->f.r.rd == reg) RNOP();
335 static void RSUB(void)
337 dst->ops = current_instruction_table.SUB;
338 recomp_func = gensub;
339 recompile_standard_r_type();
340 if (dst->f.r.rd == reg) RNOP();
343 static void RSUBU(void)
345 dst->ops = current_instruction_table.SUBU;
346 recomp_func = gensubu;
347 recompile_standard_r_type();
348 if (dst->f.r.rd == reg) RNOP();
351 static void RAND(void)
353 dst->ops = current_instruction_table.AND;
354 recomp_func = genand;
355 recompile_standard_r_type();
356 if(dst->f.r.rd == reg) RNOP();
359 static void ROR(void)
361 dst->ops = current_instruction_table.OR;
363 recompile_standard_r_type();
364 if(dst->f.r.rd == reg) RNOP();
367 static void RXOR(void)
369 dst->ops = current_instruction_table.XOR;
370 recomp_func = genxor;
371 recompile_standard_r_type();
372 if(dst->f.r.rd == reg) RNOP();
375 static void RNOR(void)
377 dst->ops = current_instruction_table.NOR;
378 recomp_func = gennor;
379 recompile_standard_r_type();
380 if(dst->f.r.rd == reg) RNOP();
383 static void RSLT(void)
385 dst->ops = current_instruction_table.SLT;
386 recomp_func = genslt;
387 recompile_standard_r_type();
388 if(dst->f.r.rd == reg) RNOP();
391 static void RSLTU(void)
393 dst->ops = current_instruction_table.SLTU;
394 recomp_func = gensltu;
395 recompile_standard_r_type();
396 if(dst->f.r.rd == reg) RNOP();
399 static void RDADD(void)
401 dst->ops = current_instruction_table.DADD;
402 recomp_func = gendadd;
403 recompile_standard_r_type();
404 if (dst->f.r.rd == reg) RNOP();
407 static void RDADDU(void)
409 dst->ops = current_instruction_table.DADDU;
410 recomp_func = gendaddu;
411 recompile_standard_r_type();
412 if (dst->f.r.rd == reg) RNOP();
415 static void RDSUB(void)
417 dst->ops = current_instruction_table.DSUB;
418 recomp_func = gendsub;
419 recompile_standard_r_type();
420 if (dst->f.r.rd == reg) RNOP();
423 static void RDSUBU(void)
425 dst->ops = current_instruction_table.DSUBU;
426 recomp_func = gendsubu;
427 recompile_standard_r_type();
428 if (dst->f.r.rd == reg) RNOP();
431 static void RTGE(void)
433 dst->ops = current_instruction_table.NI;
437 static void RTGEU(void)
439 dst->ops = current_instruction_table.NI;
443 static void RTLT(void)
445 dst->ops = current_instruction_table.NI;
449 static void RTLTU(void)
451 dst->ops = current_instruction_table.NI;
455 static void RTEQ(void)
457 dst->ops = current_instruction_table.TEQ;
458 recomp_func = genteq;
459 recompile_standard_r_type();
462 static void RTNE(void)
464 dst->ops = current_instruction_table.NI;
468 static void RDSLL(void)
470 dst->ops = current_instruction_table.DSLL;
471 recomp_func = gendsll;
472 recompile_standard_r_type();
473 if (dst->f.r.rd == reg) RNOP();
476 static void RDSRL(void)
478 dst->ops = current_instruction_table.DSRL;
479 recomp_func = gendsrl;
480 recompile_standard_r_type();
481 if (dst->f.r.rd == reg) RNOP();
484 static void RDSRA(void)
486 dst->ops = current_instruction_table.DSRA;
487 recomp_func = gendsra;
488 recompile_standard_r_type();
489 if (dst->f.r.rd == reg) RNOP();
492 static void RDSLL32(void)
494 dst->ops = current_instruction_table.DSLL32;
495 recomp_func = gendsll32;
496 recompile_standard_r_type();
497 if (dst->f.r.rd == reg) RNOP();
500 static void RDSRL32(void)
502 dst->ops = current_instruction_table.DSRL32;
503 recomp_func = gendsrl32;
504 recompile_standard_r_type();
505 if (dst->f.r.rd == reg) RNOP();
508 static void RDSRA32(void)
510 dst->ops = current_instruction_table.DSRA32;
511 recomp_func = gendsra32;
512 recompile_standard_r_type();
513 if (dst->f.r.rd == reg) RNOP();
516 static void (*recomp_special[64])(void) =
518 RSLL , RSV , RSRL , RSRA , RSLLV , RSV , RSRLV , RSRAV ,
519 RJR , RJALR , RSV , RSV , RSYSCALL, RBREAK , RSV , RSYNC ,
520 RMFHI, RMTHI , RMFLO, RMTLO, RDSLLV , RSV , RDSRLV , RDSRAV ,
521 RMULT, RMULTU, RDIV , RDIVU, RDMULT , RDMULTU, RDDIV , RDDIVU ,
522 RADD , RADDU , RSUB , RSUBU, RAND , ROR , RXOR , RNOR ,
523 RSV , RSV , RSLT , RSLTU, RDADD , RDADDU , RDSUB , RDSUBU ,
524 RTGE , RTGEU , RTLT , RTLTU, RTEQ , RSV , RTNE , RSV ,
525 RDSLL, RSV , RDSRL, RDSRA, RDSLL32 , RSV , RDSRL32, RDSRA32
528 //-------------------------------------------------------------------------
530 //-------------------------------------------------------------------------
532 static void RBLTZ(void)
535 dst->ops = current_instruction_table.BLTZ;
536 recomp_func = genbltz;
537 recompile_standard_i_type();
538 target = dst->addr + dst->f.i.immediate*4 + 4;
539 if (target == dst->addr)
543 dst->ops = current_instruction_table.BLTZ_IDLE;
544 recomp_func = genbltz_idle;
547 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
549 dst->ops = current_instruction_table.BLTZ_OUT;
550 recomp_func = genbltz_out;
554 static void RBGEZ(void)
557 dst->ops = current_instruction_table.BGEZ;
558 recomp_func = genbgez;
559 recompile_standard_i_type();
560 target = dst->addr + dst->f.i.immediate*4 + 4;
561 if (target == dst->addr)
565 dst->ops = current_instruction_table.BGEZ_IDLE;
566 recomp_func = genbgez_idle;
569 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
571 dst->ops = current_instruction_table.BGEZ_OUT;
572 recomp_func = genbgez_out;
576 static void RBLTZL(void)
579 dst->ops = current_instruction_table.BLTZL;
580 recomp_func = genbltzl;
581 recompile_standard_i_type();
582 target = dst->addr + dst->f.i.immediate*4 + 4;
583 if (target == dst->addr)
587 dst->ops = current_instruction_table.BLTZL_IDLE;
588 recomp_func = genbltzl_idle;
591 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
593 dst->ops = current_instruction_table.BLTZL_OUT;
594 recomp_func = genbltzl_out;
598 static void RBGEZL(void)
601 dst->ops = current_instruction_table.BGEZL;
602 recomp_func = genbgezl;
603 recompile_standard_i_type();
604 target = dst->addr + dst->f.i.immediate*4 + 4;
605 if (target == dst->addr)
609 dst->ops = current_instruction_table.BGEZL_IDLE;
610 recomp_func = genbgezl_idle;
613 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
615 dst->ops = current_instruction_table.BGEZL_OUT;
616 recomp_func = genbgezl_out;
620 static void RTGEI(void)
622 dst->ops = current_instruction_table.NI;
626 static void RTGEIU(void)
628 dst->ops = current_instruction_table.NI;
632 static void RTLTI(void)
634 dst->ops = current_instruction_table.NI;
638 static void RTLTIU(void)
640 dst->ops = current_instruction_table.NI;
644 static void RTEQI(void)
646 dst->ops = current_instruction_table.NI;
650 static void RTNEI(void)
652 dst->ops = current_instruction_table.NI;
656 static void RBLTZAL(void)
659 dst->ops = current_instruction_table.BLTZAL;
660 recomp_func = genbltzal;
661 recompile_standard_i_type();
662 target = dst->addr + dst->f.i.immediate*4 + 4;
663 if (target == dst->addr)
667 dst->ops = current_instruction_table.BLTZAL_IDLE;
668 recomp_func = genbltzal_idle;
671 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
673 dst->ops = current_instruction_table.BLTZAL_OUT;
674 recomp_func = genbltzal_out;
678 static void RBGEZAL(void)
681 dst->ops = current_instruction_table.BGEZAL;
682 recomp_func = genbgezal;
683 recompile_standard_i_type();
684 target = dst->addr + dst->f.i.immediate*4 + 4;
685 if (target == dst->addr)
689 dst->ops = current_instruction_table.BGEZAL_IDLE;
690 recomp_func = genbgezal_idle;
693 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
695 dst->ops = current_instruction_table.BGEZAL_OUT;
696 recomp_func = genbgezal_out;
700 static void RBLTZALL(void)
703 dst->ops = current_instruction_table.BLTZALL;
704 recomp_func = genbltzall;
705 recompile_standard_i_type();
706 target = dst->addr + dst->f.i.immediate*4 + 4;
707 if (target == dst->addr)
711 dst->ops = current_instruction_table.BLTZALL_IDLE;
712 recomp_func = genbltzall_idle;
715 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
717 dst->ops = current_instruction_table.BLTZALL_OUT;
718 recomp_func = genbltzall_out;
722 static void RBGEZALL(void)
725 dst->ops = current_instruction_table.BGEZALL;
726 recomp_func = genbgezall;
727 recompile_standard_i_type();
728 target = dst->addr + dst->f.i.immediate*4 + 4;
729 if (target == dst->addr)
733 dst->ops = current_instruction_table.BGEZALL_IDLE;
734 recomp_func = genbgezall_idle;
737 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
739 dst->ops = current_instruction_table.BGEZALL_OUT;
740 recomp_func = genbgezall_out;
744 static void (*recomp_regimm[32])(void) =
746 RBLTZ , RBGEZ , RBLTZL , RBGEZL , RSV , RSV, RSV , RSV,
747 RTGEI , RTGEIU , RTLTI , RTLTIU , RTEQI, RSV, RTNEI, RSV,
748 RBLTZAL, RBGEZAL, RBLTZALL, RBGEZALL, RSV , RSV, RSV , RSV,
749 RSV , RSV , RSV , RSV , RSV , RSV, RSV , RSV
752 //-------------------------------------------------------------------------
754 //-------------------------------------------------------------------------
756 static void RTLBR(void)
758 dst->ops = current_instruction_table.TLBR;
759 recomp_func = gentlbr;
762 static void RTLBWI(void)
764 dst->ops = current_instruction_table.TLBWI;
765 recomp_func = gentlbwi;
768 static void RTLBWR(void)
770 dst->ops = current_instruction_table.TLBWR;
771 recomp_func = gentlbwr;
774 static void RTLBP(void)
776 dst->ops = current_instruction_table.TLBP;
777 recomp_func = gentlbp;
780 static void RERET(void)
782 dst->ops = current_instruction_table.ERET;
783 recomp_func = generet;
786 static void (*recomp_tlb[64])(void) =
788 RSV , RTLBR, RTLBWI, RSV, RSV, RSV, RTLBWR, RSV,
789 RTLBP, RSV , RSV , RSV, RSV, RSV, RSV , RSV,
790 RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV,
791 RERET, RSV , RSV , RSV, RSV, RSV, RSV , RSV,
792 RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV,
793 RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV,
794 RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV,
795 RSV , RSV , RSV , RSV, RSV, RSV, RSV , RSV
798 //-------------------------------------------------------------------------
800 //-------------------------------------------------------------------------
802 static void RMFC0(void)
804 dst->ops = current_instruction_table.MFC0;
805 recomp_func = genmfc0;
806 recompile_standard_r_type();
807 dst->f.r.rd = (long long*)(reg_cop0 + ((src >> 11) & 0x1F));
808 dst->f.r.nrd = (src >> 11) & 0x1F;
809 if (dst->f.r.rt == reg) RNOP();
812 static void RMTC0(void)
814 dst->ops = current_instruction_table.MTC0;
815 recomp_func = genmtc0;
816 recompile_standard_r_type();
817 dst->f.r.nrd = (src >> 11) & 0x1F;
820 static void RTLB(void)
822 recomp_tlb[(src & 0x3F)]();
825 static void (*recomp_cop0[32])(void) =
827 RMFC0, RSV, RSV, RSV, RMTC0, RSV, RSV, RSV,
828 RSV , RSV, RSV, RSV, RSV , RSV, RSV, RSV,
829 RTLB , RSV, RSV, RSV, RSV , RSV, RSV, RSV,
830 RSV , RSV, RSV, RSV, RSV , RSV, RSV, RSV
833 //-------------------------------------------------------------------------
835 //-------------------------------------------------------------------------
837 static void RBC1F(void)
840 dst->ops = current_instruction_table.BC1F;
841 recomp_func = genbc1f;
842 recompile_standard_i_type();
843 target = dst->addr + dst->f.i.immediate*4 + 4;
844 if (target == dst->addr)
848 dst->ops = current_instruction_table.BC1F_IDLE;
849 recomp_func = genbc1f_idle;
852 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
854 dst->ops = current_instruction_table.BC1F_OUT;
855 recomp_func = genbc1f_out;
859 static void RBC1T(void)
862 dst->ops = current_instruction_table.BC1T;
863 recomp_func = genbc1t;
864 recompile_standard_i_type();
865 target = dst->addr + dst->f.i.immediate*4 + 4;
866 if (target == dst->addr)
870 dst->ops = current_instruction_table.BC1T_IDLE;
871 recomp_func = genbc1t_idle;
874 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
876 dst->ops = current_instruction_table.BC1T_OUT;
877 recomp_func = genbc1t_out;
881 static void RBC1FL(void)
884 dst->ops = current_instruction_table.BC1FL;
885 recomp_func = genbc1fl;
886 recompile_standard_i_type();
887 target = dst->addr + dst->f.i.immediate*4 + 4;
888 if (target == dst->addr)
892 dst->ops = current_instruction_table.BC1FL_IDLE;
893 recomp_func = genbc1fl_idle;
896 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
898 dst->ops = current_instruction_table.BC1FL_OUT;
899 recomp_func = genbc1fl_out;
903 static void RBC1TL(void)
906 dst->ops = current_instruction_table.BC1TL;
907 recomp_func = genbc1tl;
908 recompile_standard_i_type();
909 target = dst->addr + dst->f.i.immediate*4 + 4;
910 if (target == dst->addr)
914 dst->ops = current_instruction_table.BC1TL_IDLE;
915 recomp_func = genbc1tl_idle;
918 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
920 dst->ops = current_instruction_table.BC1TL_OUT;
921 recomp_func = genbc1tl_out;
925 static void (*recomp_bc[4])(void) =
931 //-------------------------------------------------------------------------
933 //-------------------------------------------------------------------------
935 static void RADD_S(void)
937 dst->ops = current_instruction_table.ADD_S;
938 recomp_func = genadd_s;
939 recompile_standard_cf_type();
942 static void RSUB_S(void)
944 dst->ops = current_instruction_table.SUB_S;
945 recomp_func = gensub_s;
946 recompile_standard_cf_type();
949 static void RMUL_S(void)
951 dst->ops = current_instruction_table.MUL_S;
952 recomp_func = genmul_s;
953 recompile_standard_cf_type();
956 static void RDIV_S(void)
958 dst->ops = current_instruction_table.DIV_S;
959 recomp_func = gendiv_s;
960 recompile_standard_cf_type();
963 static void RSQRT_S(void)
965 dst->ops = current_instruction_table.SQRT_S;
966 recomp_func = gensqrt_s;
967 recompile_standard_cf_type();
970 static void RABS_S(void)
972 dst->ops = current_instruction_table.ABS_S;
973 recomp_func = genabs_s;
974 recompile_standard_cf_type();
977 static void RMOV_S(void)
979 dst->ops = current_instruction_table.MOV_S;
980 recomp_func = genmov_s;
981 recompile_standard_cf_type();
984 static void RNEG_S(void)
986 dst->ops = current_instruction_table.NEG_S;
987 recomp_func = genneg_s;
988 recompile_standard_cf_type();
991 static void RROUND_L_S(void)
993 dst->ops = current_instruction_table.ROUND_L_S;
994 recomp_func = genround_l_s;
995 recompile_standard_cf_type();
998 static void RTRUNC_L_S(void)
1000 dst->ops = current_instruction_table.TRUNC_L_S;
1001 recomp_func = gentrunc_l_s;
1002 recompile_standard_cf_type();
1005 static void RCEIL_L_S(void)
1007 dst->ops = current_instruction_table.CEIL_L_S;
1008 recomp_func = genceil_l_s;
1009 recompile_standard_cf_type();
1012 static void RFLOOR_L_S(void)
1014 dst->ops = current_instruction_table.FLOOR_L_S;
1015 recomp_func = genfloor_l_s;
1016 recompile_standard_cf_type();
1019 static void RROUND_W_S(void)
1021 dst->ops = current_instruction_table.ROUND_W_S;
1022 recomp_func = genround_w_s;
1023 recompile_standard_cf_type();
1026 static void RTRUNC_W_S(void)
1028 dst->ops = current_instruction_table.TRUNC_W_S;
1029 recomp_func = gentrunc_w_s;
1030 recompile_standard_cf_type();
1033 static void RCEIL_W_S(void)
1035 dst->ops = current_instruction_table.CEIL_W_S;
1036 recomp_func = genceil_w_s;
1037 recompile_standard_cf_type();
1040 static void RFLOOR_W_S(void)
1042 dst->ops = current_instruction_table.FLOOR_W_S;
1043 recomp_func = genfloor_w_s;
1044 recompile_standard_cf_type();
1047 static void RCVT_D_S(void)
1049 dst->ops = current_instruction_table.CVT_D_S;
1050 recomp_func = gencvt_d_s;
1051 recompile_standard_cf_type();
1054 static void RCVT_W_S(void)
1056 dst->ops = current_instruction_table.CVT_W_S;
1057 recomp_func = gencvt_w_s;
1058 recompile_standard_cf_type();
1061 static void RCVT_L_S(void)
1063 dst->ops = current_instruction_table.CVT_L_S;
1064 recomp_func = gencvt_l_s;
1065 recompile_standard_cf_type();
1068 static void RC_F_S(void)
1070 dst->ops = current_instruction_table.C_F_S;
1071 recomp_func = genc_f_s;
1072 recompile_standard_cf_type();
1075 static void RC_UN_S(void)
1077 dst->ops = current_instruction_table.C_UN_S;
1078 recomp_func = genc_un_s;
1079 recompile_standard_cf_type();
1082 static void RC_EQ_S(void)
1084 dst->ops = current_instruction_table.C_EQ_S;
1085 recomp_func = genc_eq_s;
1086 recompile_standard_cf_type();
1089 static void RC_UEQ_S(void)
1091 dst->ops = current_instruction_table.C_UEQ_S;
1092 recomp_func = genc_ueq_s;
1093 recompile_standard_cf_type();
1096 static void RC_OLT_S(void)
1098 dst->ops = current_instruction_table.C_OLT_S;
1099 recomp_func = genc_olt_s;
1100 recompile_standard_cf_type();
1103 static void RC_ULT_S(void)
1105 dst->ops = current_instruction_table.C_ULT_S;
1106 recomp_func = genc_ult_s;
1107 recompile_standard_cf_type();
1110 static void RC_OLE_S(void)
1112 dst->ops = current_instruction_table.C_OLE_S;
1113 recomp_func = genc_ole_s;
1114 recompile_standard_cf_type();
1117 static void RC_ULE_S(void)
1119 dst->ops = current_instruction_table.C_ULE_S;
1120 recomp_func = genc_ule_s;
1121 recompile_standard_cf_type();
1124 static void RC_SF_S(void)
1126 dst->ops = current_instruction_table.C_SF_S;
1127 recomp_func = genc_sf_s;
1128 recompile_standard_cf_type();
1131 static void RC_NGLE_S(void)
1133 dst->ops = current_instruction_table.C_NGLE_S;
1134 recomp_func = genc_ngle_s;
1135 recompile_standard_cf_type();
1138 static void RC_SEQ_S(void)
1140 dst->ops = current_instruction_table.C_SEQ_S;
1141 recomp_func = genc_seq_s;
1142 recompile_standard_cf_type();
1145 static void RC_NGL_S(void)
1147 dst->ops = current_instruction_table.C_NGL_S;
1148 recomp_func = genc_ngl_s;
1149 recompile_standard_cf_type();
1152 static void RC_LT_S(void)
1154 dst->ops = current_instruction_table.C_LT_S;
1155 recomp_func = genc_lt_s;
1156 recompile_standard_cf_type();
1159 static void RC_NGE_S(void)
1161 dst->ops = current_instruction_table.C_NGE_S;
1162 recomp_func = genc_nge_s;
1163 recompile_standard_cf_type();
1166 static void RC_LE_S(void)
1168 dst->ops = current_instruction_table.C_LE_S;
1169 recomp_func = genc_le_s;
1170 recompile_standard_cf_type();
1173 static void RC_NGT_S(void)
1175 dst->ops = current_instruction_table.C_NGT_S;
1176 recomp_func = genc_ngt_s;
1177 recompile_standard_cf_type();
1180 static void (*recomp_s[64])(void) =
1182 RADD_S , RSUB_S , RMUL_S , RDIV_S , RSQRT_S , RABS_S , RMOV_S , RNEG_S ,
1183 RROUND_L_S, RTRUNC_L_S, RCEIL_L_S, RFLOOR_L_S, RROUND_W_S, RTRUNC_W_S, RCEIL_W_S, RFLOOR_W_S,
1184 RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV ,
1185 RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV ,
1186 RSV , RCVT_D_S , RSV , RSV , RCVT_W_S , RCVT_L_S , RSV , RSV ,
1187 RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV ,
1188 RC_F_S , RC_UN_S , RC_EQ_S , RC_UEQ_S , RC_OLT_S , RC_ULT_S , RC_OLE_S , RC_ULE_S ,
1189 RC_SF_S , RC_NGLE_S , RC_SEQ_S , RC_NGL_S , RC_LT_S , RC_NGE_S , RC_LE_S , RC_NGT_S
1192 //-------------------------------------------------------------------------
1194 //-------------------------------------------------------------------------
1196 static void RADD_D(void)
1198 dst->ops = current_instruction_table.ADD_D;
1199 recomp_func = genadd_d;
1200 recompile_standard_cf_type();
1203 static void RSUB_D(void)
1205 dst->ops = current_instruction_table.SUB_D;
1206 recomp_func = gensub_d;
1207 recompile_standard_cf_type();
1210 static void RMUL_D(void)
1212 dst->ops = current_instruction_table.MUL_D;
1213 recomp_func = genmul_d;
1214 recompile_standard_cf_type();
1217 static void RDIV_D(void)
1219 dst->ops = current_instruction_table.DIV_D;
1220 recomp_func = gendiv_d;
1221 recompile_standard_cf_type();
1224 static void RSQRT_D(void)
1226 dst->ops = current_instruction_table.SQRT_D;
1227 recomp_func = gensqrt_d;
1228 recompile_standard_cf_type();
1231 static void RABS_D(void)
1233 dst->ops = current_instruction_table.ABS_D;
1234 recomp_func = genabs_d;
1235 recompile_standard_cf_type();
1238 static void RMOV_D(void)
1240 dst->ops = current_instruction_table.MOV_D;
1241 recomp_func = genmov_d;
1242 recompile_standard_cf_type();
1245 static void RNEG_D(void)
1247 dst->ops = current_instruction_table.NEG_D;
1248 recomp_func = genneg_d;
1249 recompile_standard_cf_type();
1252 static void RROUND_L_D(void)
1254 dst->ops = current_instruction_table.ROUND_L_D;
1255 recomp_func = genround_l_d;
1256 recompile_standard_cf_type();
1259 static void RTRUNC_L_D(void)
1261 dst->ops = current_instruction_table.TRUNC_L_D;
1262 recomp_func = gentrunc_l_d;
1263 recompile_standard_cf_type();
1266 static void RCEIL_L_D(void)
1268 dst->ops = current_instruction_table.CEIL_L_D;
1269 recomp_func = genceil_l_d;
1270 recompile_standard_cf_type();
1273 static void RFLOOR_L_D(void)
1275 dst->ops = current_instruction_table.FLOOR_L_D;
1276 recomp_func = genfloor_l_d;
1277 recompile_standard_cf_type();
1280 static void RROUND_W_D(void)
1282 dst->ops = current_instruction_table.ROUND_W_D;
1283 recomp_func = genround_w_d;
1284 recompile_standard_cf_type();
1287 static void RTRUNC_W_D(void)
1289 dst->ops = current_instruction_table.TRUNC_W_D;
1290 recomp_func = gentrunc_w_d;
1291 recompile_standard_cf_type();
1294 static void RCEIL_W_D(void)
1296 dst->ops = current_instruction_table.CEIL_W_D;
1297 recomp_func = genceil_w_d;
1298 recompile_standard_cf_type();
1301 static void RFLOOR_W_D(void)
1303 dst->ops = current_instruction_table.FLOOR_W_D;
1304 recomp_func = genfloor_w_d;
1305 recompile_standard_cf_type();
1308 static void RCVT_S_D(void)
1310 dst->ops = current_instruction_table.CVT_S_D;
1311 recomp_func = gencvt_s_d;
1312 recompile_standard_cf_type();
1315 static void RCVT_W_D(void)
1317 dst->ops = current_instruction_table.CVT_W_D;
1318 recomp_func = gencvt_w_d;
1319 recompile_standard_cf_type();
1322 static void RCVT_L_D(void)
1324 dst->ops = current_instruction_table.CVT_L_D;
1325 recomp_func = gencvt_l_d;
1326 recompile_standard_cf_type();
1329 static void RC_F_D(void)
1331 dst->ops = current_instruction_table.C_F_D;
1332 recomp_func = genc_f_d;
1333 recompile_standard_cf_type();
1336 static void RC_UN_D(void)
1338 dst->ops = current_instruction_table.C_UN_D;
1339 recomp_func = genc_un_d;
1340 recompile_standard_cf_type();
1343 static void RC_EQ_D(void)
1345 dst->ops = current_instruction_table.C_EQ_D;
1346 recomp_func = genc_eq_d;
1347 recompile_standard_cf_type();
1350 static void RC_UEQ_D(void)
1352 dst->ops = current_instruction_table.C_UEQ_D;
1353 recomp_func = genc_ueq_d;
1354 recompile_standard_cf_type();
1357 static void RC_OLT_D(void)
1359 dst->ops = current_instruction_table.C_OLT_D;
1360 recomp_func = genc_olt_d;
1361 recompile_standard_cf_type();
1364 static void RC_ULT_D(void)
1366 dst->ops = current_instruction_table.C_ULT_D;
1367 recomp_func = genc_ult_d;
1368 recompile_standard_cf_type();
1371 static void RC_OLE_D(void)
1373 dst->ops = current_instruction_table.C_OLE_D;
1374 recomp_func = genc_ole_d;
1375 recompile_standard_cf_type();
1378 static void RC_ULE_D(void)
1380 dst->ops = current_instruction_table.C_ULE_D;
1381 recomp_func = genc_ule_d;
1382 recompile_standard_cf_type();
1385 static void RC_SF_D(void)
1387 dst->ops = current_instruction_table.C_SF_D;
1388 recomp_func = genc_sf_d;
1389 recompile_standard_cf_type();
1392 static void RC_NGLE_D(void)
1394 dst->ops = current_instruction_table.C_NGLE_D;
1395 recomp_func = genc_ngle_d;
1396 recompile_standard_cf_type();
1399 static void RC_SEQ_D(void)
1401 dst->ops = current_instruction_table.C_SEQ_D;
1402 recomp_func = genc_seq_d;
1403 recompile_standard_cf_type();
1406 static void RC_NGL_D(void)
1408 dst->ops = current_instruction_table.C_NGL_D;
1409 recomp_func = genc_ngl_d;
1410 recompile_standard_cf_type();
1413 static void RC_LT_D(void)
1415 dst->ops = current_instruction_table.C_LT_D;
1416 recomp_func = genc_lt_d;
1417 recompile_standard_cf_type();
1420 static void RC_NGE_D(void)
1422 dst->ops = current_instruction_table.C_NGE_D;
1423 recomp_func = genc_nge_d;
1424 recompile_standard_cf_type();
1427 static void RC_LE_D(void)
1429 dst->ops = current_instruction_table.C_LE_D;
1430 recomp_func = genc_le_d;
1431 recompile_standard_cf_type();
1434 static void RC_NGT_D(void)
1436 dst->ops = current_instruction_table.C_NGT_D;
1437 recomp_func = genc_ngt_d;
1438 recompile_standard_cf_type();
1441 static void (*recomp_d[64])(void) =
1443 RADD_D , RSUB_D , RMUL_D , RDIV_D , RSQRT_D , RABS_D , RMOV_D , RNEG_D ,
1444 RROUND_L_D, RTRUNC_L_D, RCEIL_L_D, RFLOOR_L_D, RROUND_W_D, RTRUNC_W_D, RCEIL_W_D, RFLOOR_W_D,
1445 RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV ,
1446 RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV ,
1447 RCVT_S_D , RSV , RSV , RSV , RCVT_W_D , RCVT_L_D , RSV , RSV ,
1448 RSV , RSV , RSV , RSV , RSV , RSV , RSV , RSV ,
1449 RC_F_D , RC_UN_D , RC_EQ_D , RC_UEQ_D , RC_OLT_D , RC_ULT_D , RC_OLE_D , RC_ULE_D ,
1450 RC_SF_D , RC_NGLE_D , RC_SEQ_D , RC_NGL_D , RC_LT_D , RC_NGE_D , RC_LE_D , RC_NGT_D
1453 //-------------------------------------------------------------------------
1455 //-------------------------------------------------------------------------
1457 static void RCVT_S_W(void)
1459 dst->ops = current_instruction_table.CVT_S_W;
1460 recomp_func = gencvt_s_w;
1461 recompile_standard_cf_type();
1464 static void RCVT_D_W(void)
1466 dst->ops = current_instruction_table.CVT_D_W;
1467 recomp_func = gencvt_d_w;
1468 recompile_standard_cf_type();
1471 static void (*recomp_w[64])(void) =
1473 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1474 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1475 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1476 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1477 RCVT_S_W, RCVT_D_W, RSV, RSV, RSV, RSV, RSV, RSV,
1478 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1479 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1480 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV
1483 //-------------------------------------------------------------------------
1485 //-------------------------------------------------------------------------
1487 static void RCVT_S_L(void)
1489 dst->ops = current_instruction_table.CVT_S_L;
1490 recomp_func = gencvt_s_l;
1491 recompile_standard_cf_type();
1494 static void RCVT_D_L(void)
1496 dst->ops = current_instruction_table.CVT_D_L;
1497 recomp_func = gencvt_d_l;
1498 recompile_standard_cf_type();
1501 static void (*recomp_l[64])(void) =
1503 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1504 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1505 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1506 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1507 RCVT_S_L, RCVT_D_L, RSV, RSV, RSV, RSV, RSV, RSV,
1508 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1509 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1510 RSV , RSV , RSV, RSV, RSV, RSV, RSV, RSV,
1513 //-------------------------------------------------------------------------
1515 //-------------------------------------------------------------------------
1517 static void RMFC1(void)
1519 dst->ops = current_instruction_table.MFC1;
1520 recomp_func = genmfc1;
1521 recompile_standard_r_type();
1522 dst->f.r.nrd = (src >> 11) & 0x1F;
1523 if (dst->f.r.rt == reg) RNOP();
1526 static void RDMFC1(void)
1528 dst->ops = current_instruction_table.DMFC1;
1529 recomp_func = gendmfc1;
1530 recompile_standard_r_type();
1531 dst->f.r.nrd = (src >> 11) & 0x1F;
1532 if (dst->f.r.rt == reg) RNOP();
1535 static void RCFC1(void)
1537 dst->ops = current_instruction_table.CFC1;
1538 recomp_func = gencfc1;
1539 recompile_standard_r_type();
1540 dst->f.r.nrd = (src >> 11) & 0x1F;
1541 if (dst->f.r.rt == reg) RNOP();
1544 static void RMTC1(void)
1546 dst->ops = current_instruction_table.MTC1;
1547 recompile_standard_r_type();
1548 recomp_func = genmtc1;
1549 dst->f.r.nrd = (src >> 11) & 0x1F;
1552 static void RDMTC1(void)
1554 dst->ops = current_instruction_table.DMTC1;
1555 recompile_standard_r_type();
1556 recomp_func = gendmtc1;
1557 dst->f.r.nrd = (src >> 11) & 0x1F;
1560 static void RCTC1(void)
1562 dst->ops = current_instruction_table.CTC1;
1563 recompile_standard_r_type();
1564 recomp_func = genctc1;
1565 dst->f.r.nrd = (src >> 11) & 0x1F;
1568 static void RBC(void)
1570 recomp_bc[((src >> 16) & 3)]();
1573 static void RS(void)
1575 recomp_s[(src & 0x3F)]();
1578 static void RD(void)
1580 recomp_d[(src & 0x3F)]();
1583 static void RW(void)
1585 recomp_w[(src & 0x3F)]();
1588 static void RL(void)
1590 recomp_l[(src & 0x3F)]();
1593 static void (*recomp_cop1[32])(void) =
1595 RMFC1, RDMFC1, RCFC1, RSV, RMTC1, RDMTC1, RCTC1, RSV,
1596 RBC , RSV , RSV , RSV, RSV , RSV , RSV , RSV,
1597 RS , RD , RSV , RSV, RW , RL , RSV , RSV,
1598 RSV , RSV , RSV , RSV, RSV , RSV , RSV , RSV
1601 //-------------------------------------------------------------------------
1603 //-------------------------------------------------------------------------
1605 static void RSPECIAL(void)
1607 recomp_special[(src & 0x3F)]();
1610 static void RREGIMM(void)
1612 recomp_regimm[((src >> 16) & 0x1F)]();
1615 static void RJ(void)
1617 unsigned int target;
1618 dst->ops = current_instruction_table.J;
1620 recompile_standard_j_type();
1621 target = (dst->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
1622 if (target == dst->addr)
1626 dst->ops = current_instruction_table.J_IDLE;
1627 recomp_func = genj_idle;
1630 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1632 dst->ops = current_instruction_table.J_OUT;
1633 recomp_func = genj_out;
1637 static void RJAL(void)
1639 unsigned int target;
1640 dst->ops = current_instruction_table.JAL;
1641 recomp_func = genjal;
1642 recompile_standard_j_type();
1643 target = (dst->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
1644 if (target == dst->addr)
1648 dst->ops = current_instruction_table.JAL_IDLE;
1649 recomp_func = genjal_idle;
1652 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1654 dst->ops = current_instruction_table.JAL_OUT;
1655 recomp_func = genjal_out;
1659 static void RBEQ(void)
1661 unsigned int target;
1662 dst->ops = current_instruction_table.BEQ;
1663 recomp_func = genbeq;
1664 recompile_standard_i_type();
1665 target = dst->addr + dst->f.i.immediate*4 + 4;
1666 if (target == dst->addr)
1670 dst->ops = current_instruction_table.BEQ_IDLE;
1671 recomp_func = genbeq_idle;
1674 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1676 dst->ops = current_instruction_table.BEQ_OUT;
1677 recomp_func = genbeq_out;
1681 static void RBNE(void)
1683 unsigned int target;
1684 dst->ops = current_instruction_table.BNE;
1685 recomp_func = genbne;
1686 recompile_standard_i_type();
1687 target = dst->addr + dst->f.i.immediate*4 + 4;
1688 if (target == dst->addr)
1692 dst->ops = current_instruction_table.BNE_IDLE;
1693 recomp_func = genbne_idle;
1696 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1698 dst->ops = current_instruction_table.BNE_OUT;
1699 recomp_func = genbne_out;
1703 static void RBLEZ(void)
1705 unsigned int target;
1706 dst->ops = current_instruction_table.BLEZ;
1707 recomp_func = genblez;
1708 recompile_standard_i_type();
1709 target = dst->addr + dst->f.i.immediate*4 + 4;
1710 if (target == dst->addr)
1714 dst->ops = current_instruction_table.BLEZ_IDLE;
1715 recomp_func = genblez_idle;
1718 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1720 dst->ops = current_instruction_table.BLEZ_OUT;
1721 recomp_func = genblez_out;
1725 static void RBGTZ(void)
1727 unsigned int target;
1728 dst->ops = current_instruction_table.BGTZ;
1729 recomp_func = genbgtz;
1730 recompile_standard_i_type();
1731 target = dst->addr + dst->f.i.immediate*4 + 4;
1732 if (target == dst->addr)
1736 dst->ops = current_instruction_table.BGTZ_IDLE;
1737 recomp_func = genbgtz_idle;
1740 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1742 dst->ops = current_instruction_table.BGTZ_OUT;
1743 recomp_func = genbgtz_out;
1747 static void RADDI(void)
1749 dst->ops = current_instruction_table.ADDI;
1750 recomp_func = genaddi;
1751 recompile_standard_i_type();
1752 if(dst->f.i.rt == reg) RNOP();
1755 static void RADDIU(void)
1757 dst->ops = current_instruction_table.ADDIU;
1758 recomp_func = genaddiu;
1759 recompile_standard_i_type();
1760 if(dst->f.i.rt == reg) RNOP();
1763 static void RSLTI(void)
1765 dst->ops = current_instruction_table.SLTI;
1766 recomp_func = genslti;
1767 recompile_standard_i_type();
1768 if(dst->f.i.rt == reg) RNOP();
1771 static void RSLTIU(void)
1773 dst->ops = current_instruction_table.SLTIU;
1774 recomp_func = gensltiu;
1775 recompile_standard_i_type();
1776 if(dst->f.i.rt == reg) RNOP();
1779 static void RANDI(void)
1781 dst->ops = current_instruction_table.ANDI;
1782 recomp_func = genandi;
1783 recompile_standard_i_type();
1784 if(dst->f.i.rt == reg) RNOP();
1787 static void RORI(void)
1789 dst->ops = current_instruction_table.ORI;
1790 recomp_func = genori;
1791 recompile_standard_i_type();
1792 if (dst->f.i.rt == reg) RNOP();
1795 static void RXORI(void)
1797 dst->ops = current_instruction_table.XORI;
1798 recomp_func = genxori;
1799 recompile_standard_i_type();
1800 if (dst->f.i.rt == reg) RNOP();
1803 static void RLUI(void)
1805 dst->ops = current_instruction_table.LUI;
1806 recomp_func = genlui;
1807 recompile_standard_i_type();
1808 if (dst->f.i.rt == reg) RNOP();
1811 static void RCOP0(void)
1813 recomp_cop0[((src >> 21) & 0x1F)]();
1816 static void RCOP1(void)
1818 recomp_cop1[((src >> 21) & 0x1F)]();
1821 static void RBEQL(void)
1823 unsigned int target;
1824 dst->ops = current_instruction_table.BEQL;
1825 recomp_func = genbeql;
1826 recompile_standard_i_type();
1827 target = dst->addr + dst->f.i.immediate*4 + 4;
1828 if (target == dst->addr)
1832 dst->ops = current_instruction_table.BEQL_IDLE;
1833 recomp_func = genbeql_idle;
1836 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1838 dst->ops = current_instruction_table.BEQL_OUT;
1839 recomp_func = genbeql_out;
1843 static void RBNEL(void)
1845 unsigned int target;
1846 dst->ops = current_instruction_table.BNEL;
1847 recomp_func = genbnel;
1848 recompile_standard_i_type();
1849 target = dst->addr + dst->f.i.immediate*4 + 4;
1850 if (target == dst->addr)
1854 dst->ops = current_instruction_table.BNEL_IDLE;
1855 recomp_func = genbnel_idle;
1858 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1860 dst->ops = current_instruction_table.BNEL_OUT;
1861 recomp_func = genbnel_out;
1865 static void RBLEZL(void)
1867 unsigned int target;
1868 dst->ops = current_instruction_table.BLEZL;
1869 recomp_func = genblezl;
1870 recompile_standard_i_type();
1871 target = dst->addr + dst->f.i.immediate*4 + 4;
1872 if (target == dst->addr)
1876 dst->ops = current_instruction_table.BLEZL_IDLE;
1877 recomp_func = genblezl_idle;
1880 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1882 dst->ops = current_instruction_table.BLEZL_OUT;
1883 recomp_func = genblezl_out;
1887 static void RBGTZL(void)
1889 unsigned int target;
1890 dst->ops = current_instruction_table.BGTZL;
1891 recomp_func = genbgtzl;
1892 recompile_standard_i_type();
1893 target = dst->addr + dst->f.i.immediate*4 + 4;
1894 if (target == dst->addr)
1898 dst->ops = current_instruction_table.BGTZL_IDLE;
1899 recomp_func = genbgtzl_idle;
1902 else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1904 dst->ops = current_instruction_table.BGTZL_OUT;
1905 recomp_func = genbgtzl_out;
1909 static void RDADDI(void)
1911 dst->ops = current_instruction_table.DADDI;
1912 recomp_func = gendaddi;
1913 recompile_standard_i_type();
1914 if(dst->f.i.rt == reg) RNOP();
1917 static void RDADDIU(void)
1919 dst->ops = current_instruction_table.DADDIU;
1920 recomp_func = gendaddiu;
1921 recompile_standard_i_type();
1922 if(dst->f.i.rt == reg) RNOP();
1925 static void RLDL(void)
1927 dst->ops = current_instruction_table.LDL;
1928 recomp_func = genldl;
1929 recompile_standard_i_type();
1930 if(dst->f.i.rt == reg) RNOP();
1933 static void RLDR(void)
1935 dst->ops = current_instruction_table.LDR;
1936 recomp_func = genldr;
1937 recompile_standard_i_type();
1938 if(dst->f.i.rt == reg) RNOP();
1941 static void RLB(void)
1943 dst->ops = current_instruction_table.LB;
1944 recomp_func = genlb;
1945 recompile_standard_i_type();
1946 if (dst->f.i.rt == reg) RNOP();
1949 static void RLH(void)
1951 dst->ops = current_instruction_table.LH;
1952 recomp_func = genlh;
1953 recompile_standard_i_type();
1954 if (dst->f.i.rt == reg) RNOP();
1957 static void RLWL(void)
1959 dst->ops = current_instruction_table.LWL;
1960 recomp_func = genlwl;
1961 recompile_standard_i_type();
1962 if (dst->f.i.rt == reg) RNOP();
1965 static void RLW(void)
1967 dst->ops = current_instruction_table.LW;
1968 recomp_func = genlw;
1969 recompile_standard_i_type();
1970 if (dst->f.i.rt == reg) RNOP();
1973 static void RLBU(void)
1975 dst->ops = current_instruction_table.LBU;
1976 recomp_func = genlbu;
1977 recompile_standard_i_type();
1978 if(dst->f.i.rt == reg) RNOP();
1981 static void RLHU(void)
1983 dst->ops = current_instruction_table.LHU;
1984 recomp_func = genlhu;
1985 recompile_standard_i_type();
1986 if(dst->f.i.rt == reg) RNOP();
1989 static void RLWR(void)
1991 dst->ops = current_instruction_table.LWR;
1992 recomp_func = genlwr;
1993 recompile_standard_i_type();
1994 if(dst->f.i.rt == reg) RNOP();
1997 static void RLWU(void)
1999 dst->ops = current_instruction_table.LWU;
2000 recomp_func = genlwu;
2001 recompile_standard_i_type();
2002 if(dst->f.i.rt == reg) RNOP();
2005 static void RSB(void)
2007 dst->ops = current_instruction_table.SB;
2008 recomp_func = gensb;
2009 recompile_standard_i_type();
2012 static void RSH(void)
2014 dst->ops = current_instruction_table.SH;
2015 recomp_func = gensh;
2016 recompile_standard_i_type();
2019 static void RSWL(void)
2021 dst->ops = current_instruction_table.SWL;
2022 recomp_func = genswl;
2023 recompile_standard_i_type();
2026 static void RSW(void)
2028 dst->ops = current_instruction_table.SW;
2029 recomp_func = gensw;
2030 recompile_standard_i_type();
2033 static void RSDL(void)
2035 dst->ops = current_instruction_table.SDL;
2036 recomp_func = gensdl;
2037 recompile_standard_i_type();
2040 static void RSDR(void)
2042 dst->ops = current_instruction_table.SDR;
2043 recomp_func = gensdr;
2044 recompile_standard_i_type();
2047 static void RSWR(void)
2049 dst->ops = current_instruction_table.SWR;
2050 recomp_func = genswr;
2051 recompile_standard_i_type();
2054 static void RCACHE(void)
2056 recomp_func = gencache;
2057 dst->ops = current_instruction_table.CACHE;
2060 static void RLL(void)
2062 recomp_func = genll;
2063 dst->ops = current_instruction_table.LL;
2064 recompile_standard_i_type();
2065 if(dst->f.i.rt == reg) RNOP();
2068 static void RLWC1(void)
2070 dst->ops = current_instruction_table.LWC1;
2071 recomp_func = genlwc1;
2072 recompile_standard_lf_type();
2075 static void RLLD(void)
2077 dst->ops = current_instruction_table.NI;
2078 recomp_func = genni;
2079 recompile_standard_i_type();
2082 static void RLDC1(void)
2084 dst->ops = current_instruction_table.LDC1;
2085 recomp_func = genldc1;
2086 recompile_standard_lf_type();
2089 static void RLD(void)
2091 dst->ops = current_instruction_table.LD;
2092 recomp_func = genld;
2093 recompile_standard_i_type();
2094 if (dst->f.i.rt == reg) RNOP();
2097 static void RSC(void)
2099 dst->ops = current_instruction_table.SC;
2100 recomp_func = gensc;
2101 recompile_standard_i_type();
2102 if (dst->f.i.rt == reg) RNOP();
2105 static void RSWC1(void)
2107 dst->ops = current_instruction_table.SWC1;
2108 recomp_func = genswc1;
2109 recompile_standard_lf_type();
2112 static void RSCD(void)
2114 dst->ops = current_instruction_table.NI;
2115 recomp_func = genni;
2116 recompile_standard_i_type();
2119 static void RSDC1(void)
2121 dst->ops = current_instruction_table.SDC1;
2122 recomp_func = gensdc1;
2123 recompile_standard_lf_type();
2126 static void RSD(void)
2128 dst->ops = current_instruction_table.SD;
2129 recomp_func = gensd;
2130 recompile_standard_i_type();
2133 static void (*recomp_ops[64])(void) =
2135 RSPECIAL, RREGIMM, RJ , RJAL , RBEQ , RBNE , RBLEZ , RBGTZ ,
2136 RADDI , RADDIU , RSLTI, RSLTIU, RANDI, RORI , RXORI , RLUI ,
2137 RCOP0 , RCOP1 , RSV , RSV , RBEQL, RBNEL, RBLEZL, RBGTZL,
2138 RDADDI , RDADDIU, RLDL , RLDR , RSV , RSV , RSV , RSV ,
2139 RLB , RLH , RLWL , RLW , RLBU , RLHU , RLWR , RLWU ,
2140 RSB , RSH , RSWL , RSW , RSDL , RSDR , RSWR , RCACHE,
2141 RLL , RLWC1 , RSV , RSV , RLLD , RLDC1, RSV , RLD ,
2142 RSC , RSWC1 , RSV , RSV , RSCD , RSDC1, RSV , RSD
2145 static int get_block_length(const precomp_block *block)
2147 return (block->end-block->start)/4;
2150 static size_t get_block_memsize(const precomp_block *block)
2152 int length = get_block_length(block);
2153 return ((length+1)+(length>>2)) * sizeof(precomp_instr);
2156 /**********************************************************************
2157 ******************** initialize an empty block ***********************
2158 **********************************************************************/
2159 void init_block(precomp_block *block)
2161 int i, length, already_exist = 1;
2162 static int init_length;
2163 start_section(COMPILER_SECTION);
2165 DebugMessage(M64MSG_INFO, "init block %x - %x", (int) block->start, (int) block->end);
2168 length = get_block_length(block);
2172 size_t memsize = get_block_memsize(block);
2173 if (r4300emu == CORE_DYNAREC) {
2174 block->block = (precomp_instr *) malloc_exec(memsize);
2175 if (!block->block) {
2176 DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate executable memory for dynamic recompiler. Try to use an interpreter mode.");
2181 block->block = (precomp_instr *) malloc(memsize);
2182 if (!block->block) {
2183 DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate memory for cached interpreter.");
2188 memset(block->block, 0, memsize);
2192 if (r4300emu == CORE_DYNAREC)
2196 #if defined(PROFILE_R4300)
2197 max_code_length = 524288; /* allocate so much code space that we'll never have to realloc(), because this may */
2198 /* cause instruction locations to move, and break our profiling data */
2200 max_code_length = 32768;
2202 block->code = (unsigned char *) malloc_exec(max_code_length);
2206 max_code_length = block->max_code_length;
2209 inst_pointer = &block->code;
2211 if (block->jumps_table)
2213 free(block->jumps_table);
2214 block->jumps_table = NULL;
2216 if (block->riprel_table)
2218 free(block->riprel_table);
2219 block->riprel_table = NULL;
2221 init_assembler(NULL, 0, NULL, 0);
2222 init_cache(block->block);
2227 #if defined(PROFILE_R4300)
2228 pfProfile = fopen("instructionaddrs.dat", "ab");
2229 long x86addr = (long) block->code;
2230 int mipsop = -2; /* -2 == NOTCOMPILED block at beginning of x86 code */
2231 if (fwrite(&mipsop, 1, 4, pfProfile) != 4 || // write 4-byte MIPS opcode
2232 fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) // write pointer to dynamically generated x86 code for this MIPS instruction
2233 DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
2236 for (i=0; i<length; i++)
2238 dst = block->block + i;
2239 dst->addr = block->start + i*4;
2240 dst->reg_cache_infos.need_map = 0;
2241 dst->local_addr = code_length;
2243 if (r4300emu == CORE_DYNAREC) gendebug();
2246 if (r4300emu == CORE_DYNAREC) recomp_func();
2248 #if defined(PROFILE_R4300)
2252 init_length = code_length;
2256 #if defined(PROFILE_R4300)
2257 code_length = block->code_length; /* leave old instructions in their place */
2259 code_length = init_length; /* recompile everything, overwrite old recompiled instructions */
2261 for (i=0; i<length; i++)
2263 dst = block->block + i;
2264 dst->reg_cache_infos.need_map = 0;
2265 dst->local_addr = i * (init_length / length);
2266 dst->ops = current_instruction_table.NOTCOMPILED;
2270 if (r4300emu == CORE_DYNAREC)
2272 free_all_registers();
2273 /* calling pass2 of the assembler is not necessary here because all of the code emitted by
2274 gennotcompiled() and gendebug() is position-independent and contains no jumps . */
2275 block->code_length = code_length;
2276 block->max_code_length = max_code_length;
2277 free_assembler(&block->jumps_table, &block->jumps_number, &block->riprel_table, &block->riprel_number);
2280 /* here we're marking the block as a valid code even if it's not compiled
2281 * yet as the game should have already set up the code correctly.
2283 invalid_code[block->start>>12] = 0;
2284 if (block->end < 0x80000000 || block->start >= 0xc0000000)
2288 paddr = virtual_to_physical_address(block->start, 2);
2289 invalid_code[paddr>>12] = 0;
2290 if (!blocks[paddr>>12])
2292 blocks[paddr>>12] = (precomp_block *) malloc(sizeof(precomp_block));
2293 blocks[paddr>>12]->code = NULL;
2294 blocks[paddr>>12]->block = NULL;
2295 blocks[paddr>>12]->jumps_table = NULL;
2296 blocks[paddr>>12]->riprel_table = NULL;
2297 blocks[paddr>>12]->start = paddr & ~0xFFF;
2298 blocks[paddr>>12]->end = (paddr & ~0xFFF) + 0x1000;
2300 init_block(blocks[paddr>>12]);
2302 paddr += block->end - block->start - 4;
2303 invalid_code[paddr>>12] = 0;
2304 if (!blocks[paddr>>12])
2306 blocks[paddr>>12] = (precomp_block *) malloc(sizeof(precomp_block));
2307 blocks[paddr>>12]->code = NULL;
2308 blocks[paddr>>12]->block = NULL;
2309 blocks[paddr>>12]->jumps_table = NULL;
2310 blocks[paddr>>12]->riprel_table = NULL;
2311 blocks[paddr>>12]->start = paddr & ~0xFFF;
2312 blocks[paddr>>12]->end = (paddr & ~0xFFF) + 0x1000;
2314 init_block(blocks[paddr>>12]);
2318 if (block->start >= 0x80000000 && block->end < 0xa0000000 && invalid_code[(block->start+0x20000000)>>12])
2320 if (!blocks[(block->start+0x20000000)>>12])
2322 blocks[(block->start+0x20000000)>>12] = (precomp_block *) malloc(sizeof(precomp_block));
2323 blocks[(block->start+0x20000000)>>12]->code = NULL;
2324 blocks[(block->start+0x20000000)>>12]->block = NULL;
2325 blocks[(block->start+0x20000000)>>12]->jumps_table = NULL;
2326 blocks[(block->start+0x20000000)>>12]->riprel_table = NULL;
2327 blocks[(block->start+0x20000000)>>12]->start = (block->start+0x20000000) & ~0xFFF;
2328 blocks[(block->start+0x20000000)>>12]->end = ((block->start+0x20000000) & ~0xFFF) + 0x1000;
2330 init_block(blocks[(block->start+0x20000000)>>12]);
2332 if (block->start >= 0xa0000000 && block->end < 0xc0000000 && invalid_code[(block->start-0x20000000)>>12])
2334 if (!blocks[(block->start-0x20000000)>>12])
2336 blocks[(block->start-0x20000000)>>12] = (precomp_block *) malloc(sizeof(precomp_block));
2337 blocks[(block->start-0x20000000)>>12]->code = NULL;
2338 blocks[(block->start-0x20000000)>>12]->block = NULL;
2339 blocks[(block->start-0x20000000)>>12]->jumps_table = NULL;
2340 blocks[(block->start-0x20000000)>>12]->riprel_table = NULL;
2341 blocks[(block->start-0x20000000)>>12]->start = (block->start-0x20000000) & ~0xFFF;
2342 blocks[(block->start-0x20000000)>>12]->end = ((block->start-0x20000000) & ~0xFFF) + 0x1000;
2344 init_block(blocks[(block->start-0x20000000)>>12]);
2347 end_section(COMPILER_SECTION);
2350 void free_block(precomp_block *block)
2352 size_t memsize = get_block_memsize(block);
2355 if (r4300emu == CORE_DYNAREC)
2356 free_exec(block->block, memsize);
2359 block->block = NULL;
2361 if (block->code) { free_exec(block->code, block->max_code_length); block->code = NULL; }
2362 if (block->jumps_table) { free(block->jumps_table); block->jumps_table = NULL; }
2363 if (block->riprel_table) { free(block->riprel_table); block->riprel_table = NULL; }
2366 /**********************************************************************
2367 ********************* recompile a block of code **********************
2368 **********************************************************************/
2369 void recompile_block(int *source, precomp_block *block, unsigned int func)
2371 int i, length, finished=0;
2372 start_section(COMPILER_SECTION);
2373 length = (block->end-block->start)/4;
2376 //for (i=0; i<16; i++) block->md5[i] = 0;
2379 if (r4300emu == CORE_DYNAREC)
2381 code_length = block->code_length;
2382 max_code_length = block->max_code_length;
2383 inst_pointer = &block->code;
2384 init_assembler(block->jumps_table, block->jumps_number, block->riprel_table, block->riprel_number);
2385 init_cache(block->block + (func & 0xFFF) / 4);
2388 #if defined(PROFILE_R4300)
2389 pfProfile = fopen("instructionaddrs.dat", "ab");
2392 for (i = (func & 0xFFF) / 4; finished != 2; i++)
2394 if(block->start < 0x80000000 || block->start >= 0xc0000000)
2396 unsigned int address2 =
2397 virtual_to_physical_address(block->start + i*4, 0);
2398 if(blocks[address2>>12]->block[(address2&0xFFF)/4].ops == current_instruction_table.NOTCOMPILED)
2399 blocks[address2>>12]->block[(address2&0xFFF)/4].ops = current_instruction_table.NOTCOMPILED2;
2404 check_nop = source[i+1] == 0;
2405 dst = block->block + i;
2406 dst->addr = block->start + i*4;
2407 dst->reg_cache_infos.need_map = 0;
2408 dst->local_addr = code_length;
2410 if (r4300emu == CORE_DYNAREC) gendebug();
2412 #if defined(PROFILE_R4300)
2413 long x86addr = (long) (block->code + block->block[i].local_addr);
2414 if (fwrite(source + i, 1, 4, pfProfile) != 4 || // write 4-byte MIPS opcode
2415 fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) // write pointer to dynamically generated x86 code for this MIPS instruction
2416 DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
2419 recomp_ops[((src >> 26) & 0x3F)]();
2420 if (r4300emu == CORE_DYNAREC) recomp_func();
2421 dst = block->block + i;
2423 /*if ((dst+1)->ops != NOTCOMPILED && !delay_slot_compiled &&
2426 if (r4300emu == CORE_DYNAREC) genlink_subblock();
2429 if (delay_slot_compiled)
2431 delay_slot_compiled--;
2432 free_all_registers();
2435 if (i >= length-2+(length>>2)) finished = 2;
2436 if (i >= (length-1) && (block->start == 0xa4000000 ||
2437 block->start >= 0xc0000000 ||
2438 block->end < 0x80000000)) finished = 2;
2439 if (dst->ops == current_instruction_table.ERET || finished == 1) finished = 2;
2440 if (/*i >= length &&*/
2441 (dst->ops == current_instruction_table.J ||
2442 dst->ops == current_instruction_table.J_OUT ||
2443 dst->ops == current_instruction_table.JR) &&
2444 !(i >= (length-1) && (block->start >= 0xc0000000 ||
2445 block->end < 0x80000000)))
2449 #if defined(PROFILE_R4300)
2450 long x86addr = (long) (block->code + code_length);
2451 int mipsop = -3; /* -3 == block-postfix */
2452 if (fwrite(&mipsop, 1, 4, pfProfile) != 4 || // write 4-byte MIPS opcode
2453 fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) // write pointer to dynamically generated x86 code for this MIPS instruction
2454 DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
2459 dst = block->block + i;
2460 dst->addr = block->start + i*4;
2461 dst->reg_cache_infos.need_map = 0;
2462 dst->local_addr = code_length;
2464 if (r4300emu == CORE_DYNAREC) gendebug();
2467 if (r4300emu == CORE_DYNAREC) recomp_func();
2469 if (i < length-1+(length>>2)) // useful when last opcode is a jump
2471 dst = block->block + i;
2472 dst->addr = block->start + i*4;
2473 dst->reg_cache_infos.need_map = 0;
2474 dst->local_addr = code_length;
2476 if (r4300emu == CORE_DYNAREC) gendebug();
2479 if (r4300emu == CORE_DYNAREC) recomp_func();
2483 else if (r4300emu == CORE_DYNAREC) genlink_subblock();
2485 if (r4300emu == CORE_DYNAREC)
2487 free_all_registers();
2488 passe2(block->block, (func&0xFFF)/4, i, block);
2489 block->code_length = code_length;
2490 block->max_code_length = max_code_length;
2491 free_assembler(&block->jumps_table, &block->jumps_number, &block->riprel_table, &block->riprel_number);
2494 DebugMessage(M64MSG_INFO, "block recompiled (%x-%x)", (int)func, (int)(block->start+i*4));
2496 #if defined(PROFILE_R4300)
2500 end_section(COMPILER_SECTION);
2503 static int is_jump(void)
2505 recomp_ops[((src >> 26) & 0x3F)]();
2507 (dst->ops == current_instruction_table.J ||
2508 dst->ops == current_instruction_table.J_OUT ||
2509 dst->ops == current_instruction_table.J_IDLE ||
2510 dst->ops == current_instruction_table.JAL ||
2511 dst->ops == current_instruction_table.JAL_OUT ||
2512 dst->ops == current_instruction_table.JAL_IDLE ||
2513 dst->ops == current_instruction_table.BEQ ||
2514 dst->ops == current_instruction_table.BEQ_OUT ||
2515 dst->ops == current_instruction_table.BEQ_IDLE ||
2516 dst->ops == current_instruction_table.BNE ||
2517 dst->ops == current_instruction_table.BNE_OUT ||
2518 dst->ops == current_instruction_table.BNE_IDLE ||
2519 dst->ops == current_instruction_table.BLEZ ||
2520 dst->ops == current_instruction_table.BLEZ_OUT ||
2521 dst->ops == current_instruction_table.BLEZ_IDLE ||
2522 dst->ops == current_instruction_table.BGTZ ||
2523 dst->ops == current_instruction_table.BGTZ_OUT ||
2524 dst->ops == current_instruction_table.BGTZ_IDLE ||
2525 dst->ops == current_instruction_table.BEQL ||
2526 dst->ops == current_instruction_table.BEQL_OUT ||
2527 dst->ops == current_instruction_table.BEQL_IDLE ||
2528 dst->ops == current_instruction_table.BNEL ||
2529 dst->ops == current_instruction_table.BNEL_OUT ||
2530 dst->ops == current_instruction_table.BNEL_IDLE ||
2531 dst->ops == current_instruction_table.BLEZL ||
2532 dst->ops == current_instruction_table.BLEZL_OUT ||
2533 dst->ops == current_instruction_table.BLEZL_IDLE ||
2534 dst->ops == current_instruction_table.BGTZL ||
2535 dst->ops == current_instruction_table.BGTZL_OUT ||
2536 dst->ops == current_instruction_table.BGTZL_IDLE ||
2537 dst->ops == current_instruction_table.JR ||
2538 dst->ops == current_instruction_table.JALR ||
2539 dst->ops == current_instruction_table.BLTZ ||
2540 dst->ops == current_instruction_table.BLTZ_OUT ||
2541 dst->ops == current_instruction_table.BLTZ_IDLE ||
2542 dst->ops == current_instruction_table.BGEZ ||
2543 dst->ops == current_instruction_table.BGEZ_OUT ||
2544 dst->ops == current_instruction_table.BGEZ_IDLE ||
2545 dst->ops == current_instruction_table.BLTZL ||
2546 dst->ops == current_instruction_table.BLTZL_OUT ||
2547 dst->ops == current_instruction_table.BLTZL_IDLE ||
2548 dst->ops == current_instruction_table.BGEZL ||
2549 dst->ops == current_instruction_table.BGEZL_OUT ||
2550 dst->ops == current_instruction_table.BGEZL_IDLE ||
2551 dst->ops == current_instruction_table.BLTZAL ||
2552 dst->ops == current_instruction_table.BLTZAL_OUT ||
2553 dst->ops == current_instruction_table.BLTZAL_IDLE ||
2554 dst->ops == current_instruction_table.BGEZAL ||
2555 dst->ops == current_instruction_table.BGEZAL_OUT ||
2556 dst->ops == current_instruction_table.BGEZAL_IDLE ||
2557 dst->ops == current_instruction_table.BLTZALL ||
2558 dst->ops == current_instruction_table.BLTZALL_OUT ||
2559 dst->ops == current_instruction_table.BLTZALL_IDLE ||
2560 dst->ops == current_instruction_table.BGEZALL ||
2561 dst->ops == current_instruction_table.BGEZALL_OUT ||
2562 dst->ops == current_instruction_table.BGEZALL_IDLE ||
2563 dst->ops == current_instruction_table.BC1F ||
2564 dst->ops == current_instruction_table.BC1F_OUT ||
2565 dst->ops == current_instruction_table.BC1F_IDLE ||
2566 dst->ops == current_instruction_table.BC1T ||
2567 dst->ops == current_instruction_table.BC1T_OUT ||
2568 dst->ops == current_instruction_table.BC1T_IDLE ||
2569 dst->ops == current_instruction_table.BC1FL ||
2570 dst->ops == current_instruction_table.BC1FL_OUT ||
2571 dst->ops == current_instruction_table.BC1FL_IDLE ||
2572 dst->ops == current_instruction_table.BC1TL ||
2573 dst->ops == current_instruction_table.BC1TL_OUT ||
2574 dst->ops == current_instruction_table.BC1TL_IDLE);
2577 /**********************************************************************
2578 ************ recompile only one opcode (use for delay slot) **********
2579 **********************************************************************/
2580 void recompile_opcode(void)
2585 dst->addr = (dst-1)->addr + 4;
2586 dst->reg_cache_infos.need_map = 0;
2589 #if defined(PROFILE_R4300)
2590 long x86addr = (long) ((*inst_pointer) + code_length);
2591 if (fwrite(&src, 1, 4, pfProfile) != 4 || // write 4-byte MIPS opcode
2592 fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) // write pointer to dynamically generated x86 code for this MIPS instruction
2593 DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
2596 recomp_ops[((src >> 26) & 0x3F)]();
2597 if (r4300emu == CORE_DYNAREC) recomp_func();
2602 if (r4300emu == CORE_DYNAREC) recomp_func();
2604 delay_slot_compiled = 2;
2607 /**********************************************************************
2608 ************** decode one opcode (for the interpreter) ***************
2609 **********************************************************************/
2610 void prefetch_opcode(unsigned int op, unsigned int nextop)
2614 check_nop = nextop == 0;
2615 recomp_ops[((src >> 26) & 0x3F)]();
2618 /**********************************************************************
2619 ************** allocate memory with executable bit set ***************
2620 **********************************************************************/
2621 static void *malloc_exec(size_t size)
2624 return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
2625 #elif defined(__GNUC__)
2627 #ifndef MAP_ANONYMOUS
2629 #define MAP_ANONYMOUS MAP_ANON
2633 void *block = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
2634 if (block == MAP_FAILED)
2635 { DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate %zi byte block of aligned RWX memory.", size); return NULL; }
2639 return malloc(size);
2643 /**********************************************************************
2644 ************* reallocate memory with executable bit set **************
2645 **********************************************************************/
2646 void *realloc_exec(void *ptr, size_t oldsize, size_t newsize)
2648 void* block = malloc_exec(newsize);
2652 if (oldsize < newsize)
2656 memcpy(block, ptr, copysize);
2658 free_exec(ptr, oldsize);
2662 /**********************************************************************
2663 **************** frees memory with executable bit set ****************
2664 **********************************************************************/
2665 static void free_exec(void *ptr, size_t length)
2668 VirtualFree(ptr, 0, MEM_RELEASE);
2669 #elif defined(__GNUC__)
2670 munmap(ptr, length);