Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / recomp.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - recomp.h                                                *
3  *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
4  *   Copyright (C) 2002 Hacktarux                                          *
5  *                                                                         *
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.                                   *
10  *                                                                         *
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.                          *
15  *                                                                         *
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  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #if defined(__GNUC__)
26 #include <unistd.h>
27 #ifndef __MINGW32__
28 #include <sys/mman.h>
29 #endif
30 #endif
31
32 #include "api/m64p_types.h"
33 #include "api/callbacks.h"
34 #include "memory/memory.h"
35
36 #include "recomp.h"
37 #include "recomph.h" //include for function prototypes
38 #include "macros.h"
39 #include "r4300.h"
40 #include "ops.h"
41
42 static void *malloc_exec(size_t size);
43 static void free_exec(void *ptr, size_t length);
44
45 // global variables :
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
52 int fast_memory;
53
54 static void (*recomp_func)(void); // pointer to the dynarec's generator
55                                   // function for the latest decoded opcode
56
57 #if defined(PROFILE_R4300)
58 FILE *pfProfile;
59 #endif
60
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;
64
65
66
67 static void RSV(void)
68 {
69    dst->ops = current_instruction_table.RESERVED;
70    recomp_func = genreserved;
71 }
72
73 static void RFIN_BLOCK(void)
74 {
75    dst->ops = current_instruction_table.FIN_BLOCK;
76    recomp_func = genfin_block;
77 }
78
79 static void RNOTCOMPILED(void)
80 {
81    dst->ops = current_instruction_table.NOTCOMPILED;
82    recomp_func = gennotcompiled;
83 }
84
85 static void recompile_standard_i_type(void)
86 {
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;
90 }
91
92 static void recompile_standard_j_type(void)
93 {
94    dst->f.j.inst_index = src & 0x3FFFFFF;
95 }
96
97 static void recompile_standard_r_type(void)
98 {
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;
103 }
104
105 static void recompile_standard_lf_type(void)
106 {
107    dst->f.lf.base = (src >> 21) & 0x1F;
108    dst->f.lf.ft = (src >> 16) & 0x1F;
109    dst->f.lf.offset = src & 0xFFFF;
110 }
111
112 static void recompile_standard_cf_type(void)
113 {
114    dst->f.cf.ft = (src >> 16) & 0x1F;
115    dst->f.cf.fs = (src >> 11) & 0x1F;
116    dst->f.cf.fd = (src >>  6) & 0x1F;
117 }
118
119 //-------------------------------------------------------------------------
120 //                                  SPECIAL                                
121 //-------------------------------------------------------------------------
122
123 static void RNOP(void)
124 {
125    dst->ops = current_instruction_table.NOP;
126    recomp_func = gennop;
127 }
128
129 static void RSLL(void)
130 {
131    dst->ops = current_instruction_table.SLL;
132    recomp_func = gensll;
133    recompile_standard_r_type();
134    if (dst->f.r.rd == reg) RNOP();
135 }
136
137 static void RSRL(void)
138 {
139    dst->ops = current_instruction_table.SRL;
140    recomp_func = gensrl;
141    recompile_standard_r_type();
142    if (dst->f.r.rd == reg) RNOP();
143 }
144
145 static void RSRA(void)
146 {
147    dst->ops = current_instruction_table.SRA;
148    recomp_func = gensra;
149    recompile_standard_r_type();
150    if (dst->f.r.rd == reg) RNOP();
151 }
152
153 static void RSLLV(void)
154 {
155    dst->ops = current_instruction_table.SLLV;
156    recomp_func = gensllv;
157    recompile_standard_r_type();
158    if (dst->f.r.rd == reg) RNOP();
159 }
160
161 static void RSRLV(void)
162 {
163    dst->ops = current_instruction_table.SRLV;
164    recomp_func = gensrlv;
165    recompile_standard_r_type();
166    if (dst->f.r.rd == reg) RNOP();
167 }
168
169 static void RSRAV(void)
170 {
171    dst->ops = current_instruction_table.SRAV;
172    recomp_func = gensrav;
173    recompile_standard_r_type();
174    if (dst->f.r.rd == reg) RNOP();
175 }
176
177 static void RJR(void)
178 {
179    dst->ops = current_instruction_table.JR;
180    recomp_func = genjr;
181    recompile_standard_i_type();
182 }
183
184 static void RJALR(void)
185 {
186    dst->ops = current_instruction_table.JALR;
187    recomp_func = genjalr;
188    recompile_standard_r_type();
189 }
190
191 static void RSYSCALL(void)
192 {
193    dst->ops = current_instruction_table.SYSCALL;
194    recomp_func = gensyscall;
195 }
196
197 static void RBREAK(void)
198 {
199    dst->ops = current_instruction_table.NI;
200    recomp_func = genni;
201 }
202
203 static void RSYNC(void)
204 {
205    dst->ops = current_instruction_table.SYNC;
206    recomp_func = gensync;
207 }
208
209 static void RMFHI(void)
210 {
211    dst->ops = current_instruction_table.MFHI;
212    recomp_func = genmfhi;
213    recompile_standard_r_type();
214    if (dst->f.r.rd == reg) RNOP();
215 }
216
217 static void RMTHI(void)
218 {
219    dst->ops = current_instruction_table.MTHI;
220    recomp_func = genmthi;
221    recompile_standard_r_type();
222 }
223
224 static void RMFLO(void)
225 {
226    dst->ops = current_instruction_table.MFLO;
227    recomp_func = genmflo;
228    recompile_standard_r_type();
229    if (dst->f.r.rd == reg) RNOP();
230 }
231
232 static void RMTLO(void)
233 {
234    dst->ops = current_instruction_table.MTLO;
235    recomp_func = genmtlo;
236    recompile_standard_r_type();
237 }
238
239 static void RDSLLV(void)
240 {
241    dst->ops = current_instruction_table.DSLLV;
242    recomp_func = gendsllv;
243    recompile_standard_r_type();
244    if (dst->f.r.rd == reg) RNOP();
245 }
246
247 static void RDSRLV(void)
248 {
249    dst->ops = current_instruction_table.DSRLV;
250    recomp_func = gendsrlv;
251    recompile_standard_r_type();
252    if (dst->f.r.rd == reg) RNOP();
253 }
254
255 static void RDSRAV(void)
256 {
257    dst->ops = current_instruction_table.DSRAV;
258    recomp_func = gendsrav;
259    recompile_standard_r_type();
260    if (dst->f.r.rd == reg) RNOP();
261 }
262
263 static void RMULT(void)
264 {
265    dst->ops = current_instruction_table.MULT;
266    recomp_func = genmult;
267    recompile_standard_r_type();
268 }
269
270 static void RMULTU(void)
271 {
272    dst->ops = current_instruction_table.MULTU;
273    recomp_func = genmultu;
274    recompile_standard_r_type();
275 }
276
277 static void RDIV(void)
278 {
279    dst->ops = current_instruction_table.DIV;
280    recomp_func = gendiv;
281    recompile_standard_r_type();
282 }
283
284 static void RDIVU(void)
285 {
286    dst->ops = current_instruction_table.DIVU;
287    recomp_func = gendivu;
288    recompile_standard_r_type();
289 }
290
291 static void RDMULT(void)
292 {
293    dst->ops = current_instruction_table.DMULT;
294    recomp_func = gendmult;
295    recompile_standard_r_type();
296 }
297
298 static void RDMULTU(void)
299 {
300    dst->ops = current_instruction_table.DMULTU;
301    recomp_func = gendmultu;
302    recompile_standard_r_type();
303 }
304
305 static void RDDIV(void)
306 {
307    dst->ops = current_instruction_table.DDIV;
308    recomp_func = genddiv;
309    recompile_standard_r_type();
310 }
311
312 static void RDDIVU(void)
313 {
314    dst->ops = current_instruction_table.DDIVU;
315    recomp_func = genddivu;
316    recompile_standard_r_type();
317 }
318
319 static void RADD(void)
320 {
321    dst->ops = current_instruction_table.ADD;
322    recomp_func = genadd;
323    recompile_standard_r_type();
324    if (dst->f.r.rd == reg) RNOP();
325 }
326
327 static void RADDU(void)
328 {
329    dst->ops = current_instruction_table.ADDU;
330    recomp_func = genaddu;
331    recompile_standard_r_type();
332    if (dst->f.r.rd == reg) RNOP();
333 }
334
335 static void RSUB(void)
336 {
337    dst->ops = current_instruction_table.SUB;
338    recomp_func = gensub;
339    recompile_standard_r_type();
340    if (dst->f.r.rd == reg) RNOP();
341 }
342
343 static void RSUBU(void)
344 {
345    dst->ops = current_instruction_table.SUBU;
346    recomp_func = gensubu;
347    recompile_standard_r_type();
348    if (dst->f.r.rd == reg) RNOP();
349 }
350
351 static void RAND(void)
352 {
353    dst->ops = current_instruction_table.AND;
354    recomp_func = genand;
355    recompile_standard_r_type();
356    if(dst->f.r.rd == reg) RNOP();
357 }
358
359 static void ROR(void)
360 {
361    dst->ops = current_instruction_table.OR;
362    recomp_func = genor;
363    recompile_standard_r_type();
364    if(dst->f.r.rd == reg) RNOP();
365 }
366
367 static void RXOR(void)
368 {
369    dst->ops = current_instruction_table.XOR;
370    recomp_func = genxor;
371    recompile_standard_r_type();
372    if(dst->f.r.rd == reg) RNOP();
373 }
374
375 static void RNOR(void)
376 {
377    dst->ops = current_instruction_table.NOR;
378    recomp_func = gennor;
379    recompile_standard_r_type();
380    if(dst->f.r.rd == reg) RNOP();
381 }
382
383 static void RSLT(void)
384 {
385    dst->ops = current_instruction_table.SLT;
386    recomp_func = genslt;
387    recompile_standard_r_type();
388    if(dst->f.r.rd == reg) RNOP();
389 }
390
391 static void RSLTU(void)
392 {
393    dst->ops = current_instruction_table.SLTU;
394    recomp_func = gensltu;
395    recompile_standard_r_type();
396    if(dst->f.r.rd == reg) RNOP();
397 }
398
399 static void RDADD(void)
400 {
401    dst->ops = current_instruction_table.DADD;
402    recomp_func = gendadd;
403    recompile_standard_r_type();
404    if (dst->f.r.rd == reg) RNOP();
405 }
406
407 static void RDADDU(void)
408 {
409    dst->ops = current_instruction_table.DADDU;
410    recomp_func = gendaddu;
411    recompile_standard_r_type();
412    if (dst->f.r.rd == reg) RNOP();
413 }
414
415 static void RDSUB(void)
416 {
417    dst->ops = current_instruction_table.DSUB;
418    recomp_func = gendsub;
419    recompile_standard_r_type();
420    if (dst->f.r.rd == reg) RNOP();
421 }
422
423 static void RDSUBU(void)
424 {
425    dst->ops = current_instruction_table.DSUBU;
426    recomp_func = gendsubu;
427    recompile_standard_r_type();
428    if (dst->f.r.rd == reg) RNOP();
429 }
430
431 static void RTGE(void)
432 {
433    dst->ops = current_instruction_table.NI;
434    recomp_func = genni;
435 }
436
437 static void RTGEU(void)
438 {
439    dst->ops = current_instruction_table.NI;
440    recomp_func = genni;
441 }
442
443 static void RTLT(void)
444 {
445    dst->ops = current_instruction_table.NI;
446    recomp_func = genni;
447 }
448
449 static void RTLTU(void)
450 {
451    dst->ops = current_instruction_table.NI;
452    recomp_func = genni;
453 }
454
455 static void RTEQ(void)
456 {
457    dst->ops = current_instruction_table.TEQ;
458    recomp_func = genteq;
459    recompile_standard_r_type();
460 }
461
462 static void RTNE(void)
463 {
464    dst->ops = current_instruction_table.NI;
465    recomp_func = genni;
466 }
467
468 static void RDSLL(void)
469 {
470    dst->ops = current_instruction_table.DSLL;
471    recomp_func = gendsll;
472    recompile_standard_r_type();
473    if (dst->f.r.rd == reg) RNOP();
474 }
475
476 static void RDSRL(void)
477 {
478    dst->ops = current_instruction_table.DSRL;
479    recomp_func = gendsrl;
480    recompile_standard_r_type();
481    if (dst->f.r.rd == reg) RNOP();
482 }
483
484 static void RDSRA(void)
485 {
486    dst->ops = current_instruction_table.DSRA;
487    recomp_func = gendsra;
488    recompile_standard_r_type();
489    if (dst->f.r.rd == reg) RNOP();
490 }
491
492 static void RDSLL32(void)
493 {
494    dst->ops = current_instruction_table.DSLL32;
495    recomp_func = gendsll32;
496    recompile_standard_r_type();
497    if (dst->f.r.rd == reg) RNOP();
498 }
499
500 static void RDSRL32(void)
501 {
502    dst->ops = current_instruction_table.DSRL32;
503    recomp_func = gendsrl32;
504    recompile_standard_r_type();
505    if (dst->f.r.rd == reg) RNOP();
506 }
507
508 static void RDSRA32(void)
509 {
510    dst->ops = current_instruction_table.DSRA32;
511    recomp_func = gendsra32;
512    recompile_standard_r_type();
513    if (dst->f.r.rd == reg) RNOP();
514 }
515
516 static void (*recomp_special[64])(void) =
517 {
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
526 };
527
528 //-------------------------------------------------------------------------
529 //                                   REGIMM                                
530 //-------------------------------------------------------------------------
531
532 static void RBLTZ(void)
533 {
534    unsigned int target;
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)
540    {
541       if (check_nop)
542       {
543          dst->ops = current_instruction_table.BLTZ_IDLE;
544          recomp_func = genbltz_idle;
545       }
546    }
547    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
548    {
549       dst->ops = current_instruction_table.BLTZ_OUT;
550       recomp_func = genbltz_out;
551    }
552 }
553
554 static void RBGEZ(void)
555 {
556    unsigned int target;
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)
562    {
563       if (check_nop)
564       {
565          dst->ops = current_instruction_table.BGEZ_IDLE;
566          recomp_func = genbgez_idle;
567       }
568    }
569    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
570    {
571       dst->ops = current_instruction_table.BGEZ_OUT;
572       recomp_func = genbgez_out;
573    }
574 }
575
576 static void RBLTZL(void)
577 {
578    unsigned int target;
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)
584    {
585       if (check_nop)
586       {
587          dst->ops = current_instruction_table.BLTZL_IDLE;
588          recomp_func = genbltzl_idle;
589       }
590    }
591    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
592    {
593       dst->ops = current_instruction_table.BLTZL_OUT;
594       recomp_func = genbltzl_out;
595    }
596 }
597
598 static void RBGEZL(void)
599 {
600    unsigned int target;
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)
606    {
607       if (check_nop)
608       {
609          dst->ops = current_instruction_table.BGEZL_IDLE;
610          recomp_func = genbgezl_idle;
611       }
612    }
613    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
614    {
615       dst->ops = current_instruction_table.BGEZL_OUT;
616       recomp_func = genbgezl_out;
617    }
618 }
619
620 static void RTGEI(void)
621 {
622    dst->ops = current_instruction_table.NI;
623    recomp_func = genni;
624 }
625
626 static void RTGEIU(void)
627 {
628    dst->ops = current_instruction_table.NI;
629    recomp_func = genni;
630 }
631
632 static void RTLTI(void)
633 {
634    dst->ops = current_instruction_table.NI;
635    recomp_func = genni;
636 }
637
638 static void RTLTIU(void)
639 {
640    dst->ops = current_instruction_table.NI;
641    recomp_func = genni;
642 }
643
644 static void RTEQI(void)
645 {
646    dst->ops = current_instruction_table.NI;
647    recomp_func = genni;
648 }
649
650 static void RTNEI(void)
651 {
652    dst->ops = current_instruction_table.NI;
653    recomp_func = genni;
654 }
655
656 static void RBLTZAL(void)
657 {
658    unsigned int target;
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)
664    {
665       if (check_nop)
666       {
667          dst->ops = current_instruction_table.BLTZAL_IDLE;
668          recomp_func = genbltzal_idle;
669       }
670    }
671    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
672    {
673       dst->ops = current_instruction_table.BLTZAL_OUT;
674       recomp_func = genbltzal_out;
675    }
676 }
677
678 static void RBGEZAL(void)
679 {
680    unsigned int target;
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)
686    {
687       if (check_nop)
688       {
689          dst->ops = current_instruction_table.BGEZAL_IDLE;
690          recomp_func = genbgezal_idle;
691       }
692    }
693    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
694    {
695       dst->ops = current_instruction_table.BGEZAL_OUT;
696       recomp_func = genbgezal_out;
697    }
698 }
699
700 static void RBLTZALL(void)
701 {
702    unsigned int target;
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)
708    {
709       if (check_nop)
710       {
711          dst->ops = current_instruction_table.BLTZALL_IDLE;
712          recomp_func = genbltzall_idle;
713       }
714    }
715    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
716    {
717       dst->ops = current_instruction_table.BLTZALL_OUT;
718       recomp_func = genbltzall_out;
719    }
720 }
721
722 static void RBGEZALL(void)
723 {
724    unsigned int target;
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)
730    {
731       if (check_nop)
732       {
733          dst->ops = current_instruction_table.BGEZALL_IDLE;
734          recomp_func = genbgezall_idle;
735       }
736    }
737    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
738    {
739       dst->ops = current_instruction_table.BGEZALL_OUT;
740       recomp_func = genbgezall_out;
741    }
742 }
743
744 static void (*recomp_regimm[32])(void) =
745 {
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
750 };
751
752 //-------------------------------------------------------------------------
753 //                                     TLB                                 
754 //-------------------------------------------------------------------------
755
756 static void RTLBR(void)
757 {
758    dst->ops = current_instruction_table.TLBR;
759    recomp_func = gentlbr;
760 }
761
762 static void RTLBWI(void)
763 {
764    dst->ops = current_instruction_table.TLBWI;
765    recomp_func = gentlbwi;
766 }
767
768 static void RTLBWR(void)
769 {
770    dst->ops = current_instruction_table.TLBWR;
771    recomp_func = gentlbwr;
772 }
773
774 static void RTLBP(void)
775 {
776    dst->ops = current_instruction_table.TLBP;
777    recomp_func = gentlbp;
778 }
779
780 static void RERET(void)
781 {
782    dst->ops = current_instruction_table.ERET;
783    recomp_func = generet;
784 }
785
786 static void (*recomp_tlb[64])(void) =
787 {
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
796 };
797
798 //-------------------------------------------------------------------------
799 //                                    COP0                                 
800 //-------------------------------------------------------------------------
801
802 static void RMFC0(void)
803 {
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();
810 }
811
812 static void RMTC0(void)
813 {
814    dst->ops = current_instruction_table.MTC0;
815    recomp_func = genmtc0;
816    recompile_standard_r_type();
817    dst->f.r.nrd = (src >> 11) & 0x1F;
818 }
819
820 static void RTLB(void)
821 {
822    recomp_tlb[(src & 0x3F)]();
823 }
824
825 static void (*recomp_cop0[32])(void) =
826 {
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
831 };
832
833 //-------------------------------------------------------------------------
834 //                                     BC                                  
835 //-------------------------------------------------------------------------
836
837 static void RBC1F(void)
838 {
839    unsigned int target;
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)
845    {
846       if (check_nop)
847       {
848          dst->ops = current_instruction_table.BC1F_IDLE;
849          recomp_func = genbc1f_idle;
850       }
851    }
852    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
853    {
854       dst->ops = current_instruction_table.BC1F_OUT;
855       recomp_func = genbc1f_out;
856    }
857 }
858
859 static void RBC1T(void)
860 {
861    unsigned int target;
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)
867    {
868       if (check_nop)
869       {
870          dst->ops = current_instruction_table.BC1T_IDLE;
871          recomp_func = genbc1t_idle;
872       }
873    }
874    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
875    {
876       dst->ops = current_instruction_table.BC1T_OUT;
877       recomp_func = genbc1t_out;
878    }
879 }
880
881 static void RBC1FL(void)
882 {
883    unsigned int target;
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)
889    {
890       if (check_nop)
891       {
892          dst->ops = current_instruction_table.BC1FL_IDLE;
893          recomp_func = genbc1fl_idle;
894       }
895    }
896    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
897    {
898       dst->ops = current_instruction_table.BC1FL_OUT;
899       recomp_func = genbc1fl_out;
900    }
901 }
902
903 static void RBC1TL(void)
904 {
905    unsigned int target;
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)
911    {
912       if (check_nop)
913       {
914          dst->ops = current_instruction_table.BC1TL_IDLE;
915          recomp_func = genbc1tl_idle;
916       }
917    }
918    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
919    {
920       dst->ops = current_instruction_table.BC1TL_OUT;
921       recomp_func = genbc1tl_out;
922    }
923 }
924
925 static void (*recomp_bc[4])(void) =
926 {
927    RBC1F , RBC1T ,
928    RBC1FL, RBC1TL
929 };
930
931 //-------------------------------------------------------------------------
932 //                                     S                                   
933 //-------------------------------------------------------------------------
934
935 static void RADD_S(void)
936 {
937    dst->ops = current_instruction_table.ADD_S;
938    recomp_func = genadd_s;
939    recompile_standard_cf_type();
940 }
941
942 static void RSUB_S(void)
943 {
944    dst->ops = current_instruction_table.SUB_S;
945    recomp_func = gensub_s;
946    recompile_standard_cf_type();
947 }
948
949 static void RMUL_S(void)
950 {
951    dst->ops = current_instruction_table.MUL_S;
952    recomp_func = genmul_s;
953    recompile_standard_cf_type();
954 }
955
956 static void RDIV_S(void)
957 {
958    dst->ops = current_instruction_table.DIV_S;
959    recomp_func = gendiv_s;
960    recompile_standard_cf_type();
961 }
962
963 static void RSQRT_S(void)
964 {
965    dst->ops = current_instruction_table.SQRT_S;
966    recomp_func = gensqrt_s;
967    recompile_standard_cf_type();
968 }
969
970 static void RABS_S(void)
971 {
972    dst->ops = current_instruction_table.ABS_S;
973    recomp_func = genabs_s;
974    recompile_standard_cf_type();
975 }
976
977 static void RMOV_S(void)
978 {
979    dst->ops = current_instruction_table.MOV_S;
980    recomp_func = genmov_s;
981    recompile_standard_cf_type();
982 }
983
984 static void RNEG_S(void)
985 {
986    dst->ops = current_instruction_table.NEG_S;
987    recomp_func = genneg_s;
988    recompile_standard_cf_type();
989 }
990
991 static void RROUND_L_S(void)
992 {
993    dst->ops = current_instruction_table.ROUND_L_S;
994    recomp_func = genround_l_s;
995    recompile_standard_cf_type();
996 }
997
998 static void RTRUNC_L_S(void)
999 {
1000    dst->ops = current_instruction_table.TRUNC_L_S;
1001    recomp_func = gentrunc_l_s;
1002    recompile_standard_cf_type();
1003 }
1004
1005 static void RCEIL_L_S(void)
1006 {
1007    dst->ops = current_instruction_table.CEIL_L_S;
1008    recomp_func = genceil_l_s;
1009    recompile_standard_cf_type();
1010 }
1011
1012 static void RFLOOR_L_S(void)
1013 {
1014    dst->ops = current_instruction_table.FLOOR_L_S;
1015    recomp_func = genfloor_l_s;
1016    recompile_standard_cf_type();
1017 }
1018
1019 static void RROUND_W_S(void)
1020 {
1021    dst->ops = current_instruction_table.ROUND_W_S;
1022    recomp_func = genround_w_s;
1023    recompile_standard_cf_type();
1024 }
1025
1026 static void RTRUNC_W_S(void)
1027 {
1028    dst->ops = current_instruction_table.TRUNC_W_S;
1029    recomp_func = gentrunc_w_s;
1030    recompile_standard_cf_type();
1031 }
1032
1033 static void RCEIL_W_S(void)
1034 {
1035    dst->ops = current_instruction_table.CEIL_W_S;
1036    recomp_func = genceil_w_s;
1037    recompile_standard_cf_type();
1038 }
1039
1040 static void RFLOOR_W_S(void)
1041 {
1042    dst->ops = current_instruction_table.FLOOR_W_S;
1043    recomp_func = genfloor_w_s;
1044    recompile_standard_cf_type();
1045 }
1046
1047 static void RCVT_D_S(void)
1048 {
1049    dst->ops = current_instruction_table.CVT_D_S;
1050    recomp_func = gencvt_d_s;
1051    recompile_standard_cf_type();
1052 }
1053
1054 static void RCVT_W_S(void)
1055 {
1056    dst->ops = current_instruction_table.CVT_W_S;
1057    recomp_func = gencvt_w_s;
1058    recompile_standard_cf_type();
1059 }
1060
1061 static void RCVT_L_S(void)
1062 {
1063    dst->ops = current_instruction_table.CVT_L_S;
1064    recomp_func = gencvt_l_s;
1065    recompile_standard_cf_type();
1066 }
1067
1068 static void RC_F_S(void)
1069 {
1070    dst->ops = current_instruction_table.C_F_S;
1071    recomp_func = genc_f_s;
1072    recompile_standard_cf_type();
1073 }
1074
1075 static void RC_UN_S(void)
1076 {
1077    dst->ops = current_instruction_table.C_UN_S;
1078    recomp_func = genc_un_s;
1079    recompile_standard_cf_type();
1080 }
1081
1082 static void RC_EQ_S(void)
1083 {
1084    dst->ops = current_instruction_table.C_EQ_S;
1085    recomp_func = genc_eq_s;
1086    recompile_standard_cf_type();
1087 }
1088
1089 static void RC_UEQ_S(void)
1090 {
1091    dst->ops = current_instruction_table.C_UEQ_S;
1092    recomp_func = genc_ueq_s;
1093    recompile_standard_cf_type();
1094 }
1095
1096 static void RC_OLT_S(void)
1097 {
1098    dst->ops = current_instruction_table.C_OLT_S;
1099    recomp_func = genc_olt_s;
1100    recompile_standard_cf_type();
1101 }
1102
1103 static void RC_ULT_S(void)
1104 {
1105    dst->ops = current_instruction_table.C_ULT_S;
1106    recomp_func = genc_ult_s;
1107    recompile_standard_cf_type();
1108 }
1109
1110 static void RC_OLE_S(void)
1111 {
1112    dst->ops = current_instruction_table.C_OLE_S;
1113    recomp_func = genc_ole_s;
1114    recompile_standard_cf_type();
1115 }
1116
1117 static void RC_ULE_S(void)
1118 {
1119    dst->ops = current_instruction_table.C_ULE_S;
1120    recomp_func = genc_ule_s;
1121    recompile_standard_cf_type();
1122 }
1123
1124 static void RC_SF_S(void)
1125 {
1126    dst->ops = current_instruction_table.C_SF_S;
1127    recomp_func = genc_sf_s;
1128    recompile_standard_cf_type();
1129 }
1130
1131 static void RC_NGLE_S(void)
1132 {
1133    dst->ops = current_instruction_table.C_NGLE_S;
1134    recomp_func = genc_ngle_s;
1135    recompile_standard_cf_type();
1136 }
1137
1138 static void RC_SEQ_S(void)
1139 {
1140    dst->ops = current_instruction_table.C_SEQ_S;
1141    recomp_func = genc_seq_s;
1142    recompile_standard_cf_type();
1143 }
1144
1145 static void RC_NGL_S(void)
1146 {
1147    dst->ops = current_instruction_table.C_NGL_S;
1148    recomp_func = genc_ngl_s;
1149    recompile_standard_cf_type();
1150 }
1151
1152 static void RC_LT_S(void)
1153 {
1154    dst->ops = current_instruction_table.C_LT_S;
1155    recomp_func = genc_lt_s;
1156    recompile_standard_cf_type();
1157 }
1158
1159 static void RC_NGE_S(void)
1160 {
1161    dst->ops = current_instruction_table.C_NGE_S;
1162    recomp_func = genc_nge_s;
1163    recompile_standard_cf_type();
1164 }
1165
1166 static void RC_LE_S(void)
1167 {
1168    dst->ops = current_instruction_table.C_LE_S;
1169    recomp_func = genc_le_s;
1170    recompile_standard_cf_type();
1171 }
1172
1173 static void RC_NGT_S(void)
1174 {
1175    dst->ops = current_instruction_table.C_NGT_S;
1176    recomp_func = genc_ngt_s;
1177    recompile_standard_cf_type();
1178 }
1179
1180 static void (*recomp_s[64])(void) =
1181 {
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
1190 };
1191
1192 //-------------------------------------------------------------------------
1193 //                                     D                                   
1194 //-------------------------------------------------------------------------
1195
1196 static void RADD_D(void)
1197 {
1198    dst->ops = current_instruction_table.ADD_D;
1199    recomp_func = genadd_d;
1200    recompile_standard_cf_type();
1201 }
1202
1203 static void RSUB_D(void)
1204 {
1205    dst->ops = current_instruction_table.SUB_D;
1206    recomp_func = gensub_d;
1207    recompile_standard_cf_type();
1208 }
1209
1210 static void RMUL_D(void)
1211 {
1212    dst->ops = current_instruction_table.MUL_D;
1213    recomp_func = genmul_d;
1214    recompile_standard_cf_type();
1215 }
1216
1217 static void RDIV_D(void)
1218 {
1219    dst->ops = current_instruction_table.DIV_D;
1220    recomp_func = gendiv_d;
1221    recompile_standard_cf_type();
1222 }
1223
1224 static void RSQRT_D(void)
1225 {
1226    dst->ops = current_instruction_table.SQRT_D;
1227    recomp_func = gensqrt_d;
1228    recompile_standard_cf_type();
1229 }
1230
1231 static void RABS_D(void)
1232 {
1233    dst->ops = current_instruction_table.ABS_D;
1234    recomp_func = genabs_d;
1235    recompile_standard_cf_type();
1236 }
1237
1238 static void RMOV_D(void)
1239 {
1240    dst->ops = current_instruction_table.MOV_D;
1241    recomp_func = genmov_d;
1242    recompile_standard_cf_type();
1243 }
1244
1245 static void RNEG_D(void)
1246 {
1247    dst->ops = current_instruction_table.NEG_D;
1248    recomp_func = genneg_d;
1249    recompile_standard_cf_type();
1250 }
1251
1252 static void RROUND_L_D(void)
1253 {
1254    dst->ops = current_instruction_table.ROUND_L_D;
1255    recomp_func = genround_l_d;
1256    recompile_standard_cf_type();
1257 }
1258
1259 static void RTRUNC_L_D(void)
1260 {
1261    dst->ops = current_instruction_table.TRUNC_L_D;
1262    recomp_func = gentrunc_l_d;
1263    recompile_standard_cf_type();
1264 }
1265
1266 static void RCEIL_L_D(void)
1267 {
1268    dst->ops = current_instruction_table.CEIL_L_D;
1269    recomp_func = genceil_l_d;
1270    recompile_standard_cf_type();
1271 }
1272
1273 static void RFLOOR_L_D(void)
1274 {
1275    dst->ops = current_instruction_table.FLOOR_L_D;
1276    recomp_func = genfloor_l_d;
1277    recompile_standard_cf_type();
1278 }
1279
1280 static void RROUND_W_D(void)
1281 {
1282    dst->ops = current_instruction_table.ROUND_W_D;
1283    recomp_func = genround_w_d;
1284    recompile_standard_cf_type();
1285 }
1286
1287 static void RTRUNC_W_D(void)
1288 {
1289    dst->ops = current_instruction_table.TRUNC_W_D;
1290    recomp_func = gentrunc_w_d;
1291    recompile_standard_cf_type();
1292 }
1293
1294 static void RCEIL_W_D(void)
1295 {
1296    dst->ops = current_instruction_table.CEIL_W_D;
1297    recomp_func = genceil_w_d;
1298    recompile_standard_cf_type();
1299 }
1300
1301 static void RFLOOR_W_D(void)
1302 {
1303    dst->ops = current_instruction_table.FLOOR_W_D;
1304    recomp_func = genfloor_w_d;
1305    recompile_standard_cf_type();
1306 }
1307
1308 static void RCVT_S_D(void)
1309 {
1310    dst->ops = current_instruction_table.CVT_S_D;
1311    recomp_func = gencvt_s_d;
1312    recompile_standard_cf_type();
1313 }
1314
1315 static void RCVT_W_D(void)
1316 {
1317    dst->ops = current_instruction_table.CVT_W_D;
1318    recomp_func = gencvt_w_d;
1319    recompile_standard_cf_type();
1320 }
1321
1322 static void RCVT_L_D(void)
1323 {
1324    dst->ops = current_instruction_table.CVT_L_D;
1325    recomp_func = gencvt_l_d;
1326    recompile_standard_cf_type();
1327 }
1328
1329 static void RC_F_D(void)
1330 {
1331    dst->ops = current_instruction_table.C_F_D;
1332    recomp_func = genc_f_d;
1333    recompile_standard_cf_type();
1334 }
1335
1336 static void RC_UN_D(void)
1337 {
1338    dst->ops = current_instruction_table.C_UN_D;
1339    recomp_func = genc_un_d;
1340    recompile_standard_cf_type();
1341 }
1342
1343 static void RC_EQ_D(void)
1344 {
1345    dst->ops = current_instruction_table.C_EQ_D;
1346    recomp_func = genc_eq_d;
1347    recompile_standard_cf_type();
1348 }
1349
1350 static void RC_UEQ_D(void)
1351 {
1352    dst->ops = current_instruction_table.C_UEQ_D;
1353    recomp_func = genc_ueq_d;
1354    recompile_standard_cf_type();
1355 }
1356
1357 static void RC_OLT_D(void)
1358 {
1359    dst->ops = current_instruction_table.C_OLT_D;
1360    recomp_func = genc_olt_d;
1361    recompile_standard_cf_type();
1362 }
1363
1364 static void RC_ULT_D(void)
1365 {
1366    dst->ops = current_instruction_table.C_ULT_D;
1367    recomp_func = genc_ult_d;
1368    recompile_standard_cf_type();
1369 }
1370
1371 static void RC_OLE_D(void)
1372 {
1373    dst->ops = current_instruction_table.C_OLE_D;
1374    recomp_func = genc_ole_d;
1375    recompile_standard_cf_type();
1376 }
1377
1378 static void RC_ULE_D(void)
1379 {
1380    dst->ops = current_instruction_table.C_ULE_D;
1381    recomp_func = genc_ule_d;
1382    recompile_standard_cf_type();
1383 }
1384
1385 static void RC_SF_D(void)
1386 {
1387    dst->ops = current_instruction_table.C_SF_D;
1388    recomp_func = genc_sf_d;
1389    recompile_standard_cf_type();
1390 }
1391
1392 static void RC_NGLE_D(void)
1393 {
1394    dst->ops = current_instruction_table.C_NGLE_D;
1395    recomp_func = genc_ngle_d;
1396    recompile_standard_cf_type();
1397 }
1398
1399 static void RC_SEQ_D(void)
1400 {
1401    dst->ops = current_instruction_table.C_SEQ_D;
1402    recomp_func = genc_seq_d;
1403    recompile_standard_cf_type();
1404 }
1405
1406 static void RC_NGL_D(void)
1407 {
1408    dst->ops = current_instruction_table.C_NGL_D;
1409    recomp_func = genc_ngl_d;
1410    recompile_standard_cf_type();
1411 }
1412
1413 static void RC_LT_D(void)
1414 {
1415    dst->ops = current_instruction_table.C_LT_D;
1416    recomp_func = genc_lt_d;
1417    recompile_standard_cf_type();
1418 }
1419
1420 static void RC_NGE_D(void)
1421 {
1422    dst->ops = current_instruction_table.C_NGE_D;
1423    recomp_func = genc_nge_d;
1424    recompile_standard_cf_type();
1425 }
1426
1427 static void RC_LE_D(void)
1428 {
1429    dst->ops = current_instruction_table.C_LE_D;
1430    recomp_func = genc_le_d;
1431    recompile_standard_cf_type();
1432 }
1433
1434 static void RC_NGT_D(void)
1435 {
1436    dst->ops = current_instruction_table.C_NGT_D;
1437    recomp_func = genc_ngt_d;
1438    recompile_standard_cf_type();
1439 }
1440
1441 static void (*recomp_d[64])(void) =
1442 {
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
1451 };
1452
1453 //-------------------------------------------------------------------------
1454 //                                     W                                   
1455 //-------------------------------------------------------------------------
1456
1457 static void RCVT_S_W(void)
1458 {
1459    dst->ops = current_instruction_table.CVT_S_W;
1460    recomp_func = gencvt_s_w;
1461    recompile_standard_cf_type();
1462 }
1463
1464 static void RCVT_D_W(void)
1465 {
1466    dst->ops = current_instruction_table.CVT_D_W;
1467    recomp_func = gencvt_d_w;
1468    recompile_standard_cf_type();
1469 }
1470
1471 static void (*recomp_w[64])(void) =
1472 {
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
1481 };
1482
1483 //-------------------------------------------------------------------------
1484 //                                     L                                   
1485 //-------------------------------------------------------------------------
1486
1487 static void RCVT_S_L(void)
1488 {
1489    dst->ops = current_instruction_table.CVT_S_L;
1490    recomp_func = gencvt_s_l;
1491    recompile_standard_cf_type();
1492 }
1493
1494 static void RCVT_D_L(void)
1495 {
1496    dst->ops = current_instruction_table.CVT_D_L;
1497    recomp_func = gencvt_d_l;
1498    recompile_standard_cf_type();
1499 }
1500
1501 static void (*recomp_l[64])(void) =
1502 {
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, 
1511 };
1512
1513 //-------------------------------------------------------------------------
1514 //                                    COP1                                 
1515 //-------------------------------------------------------------------------
1516
1517 static void RMFC1(void)
1518 {
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();
1524 }
1525
1526 static void RDMFC1(void)
1527 {
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();
1533 }
1534
1535 static void RCFC1(void)
1536 {
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();
1542 }
1543
1544 static void RMTC1(void)
1545 {
1546    dst->ops = current_instruction_table.MTC1;
1547    recompile_standard_r_type();
1548    recomp_func = genmtc1;
1549    dst->f.r.nrd = (src >> 11) & 0x1F;
1550 }
1551
1552 static void RDMTC1(void)
1553 {
1554    dst->ops = current_instruction_table.DMTC1;
1555    recompile_standard_r_type();
1556    recomp_func = gendmtc1;
1557    dst->f.r.nrd = (src >> 11) & 0x1F;
1558 }
1559
1560 static void RCTC1(void)
1561 {
1562    dst->ops = current_instruction_table.CTC1;
1563    recompile_standard_r_type();
1564    recomp_func = genctc1;
1565    dst->f.r.nrd = (src >> 11) & 0x1F;
1566 }
1567
1568 static void RBC(void)
1569 {
1570    recomp_bc[((src >> 16) & 3)]();
1571 }
1572
1573 static void RS(void)
1574 {
1575    recomp_s[(src & 0x3F)]();
1576 }
1577
1578 static void RD(void)
1579 {
1580    recomp_d[(src & 0x3F)]();
1581 }
1582
1583 static void RW(void)
1584 {
1585    recomp_w[(src & 0x3F)]();
1586 }
1587
1588 static void RL(void)
1589 {
1590    recomp_l[(src & 0x3F)]();
1591 }
1592
1593 static void (*recomp_cop1[32])(void) =
1594 {
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
1599 };
1600
1601 //-------------------------------------------------------------------------
1602 //                                   R4300                                 
1603 //-------------------------------------------------------------------------
1604
1605 static void RSPECIAL(void)
1606 {
1607    recomp_special[(src & 0x3F)]();
1608 }
1609
1610 static void RREGIMM(void)
1611 {
1612    recomp_regimm[((src >> 16) & 0x1F)]();
1613 }
1614
1615 static void RJ(void)
1616 {
1617    unsigned int target;
1618    dst->ops = current_instruction_table.J;
1619    recomp_func = genj;
1620    recompile_standard_j_type();
1621    target = (dst->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
1622    if (target == dst->addr)
1623    {
1624       if (check_nop)
1625       {
1626          dst->ops = current_instruction_table.J_IDLE;
1627          recomp_func = genj_idle;
1628       }
1629    }
1630    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1631    {
1632       dst->ops = current_instruction_table.J_OUT;
1633       recomp_func = genj_out;
1634    }
1635 }
1636
1637 static void RJAL(void)
1638 {
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)
1645    {
1646       if (check_nop)
1647       {
1648          dst->ops = current_instruction_table.JAL_IDLE;
1649          recomp_func = genjal_idle;
1650       }
1651    }
1652    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1653    {
1654       dst->ops = current_instruction_table.JAL_OUT;
1655       recomp_func = genjal_out;
1656    }
1657 }
1658
1659 static void RBEQ(void)
1660 {
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)
1667    {
1668       if (check_nop)
1669       {
1670          dst->ops = current_instruction_table.BEQ_IDLE;
1671          recomp_func = genbeq_idle;
1672       }
1673    }
1674    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1675    {
1676       dst->ops = current_instruction_table.BEQ_OUT;
1677       recomp_func = genbeq_out;
1678    }
1679 }
1680
1681 static void RBNE(void)
1682 {
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)
1689    {
1690       if (check_nop)
1691       {
1692          dst->ops = current_instruction_table.BNE_IDLE;
1693          recomp_func = genbne_idle;
1694       }
1695    }
1696    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1697    {
1698       dst->ops = current_instruction_table.BNE_OUT;
1699       recomp_func = genbne_out;
1700    }
1701 }
1702
1703 static void RBLEZ(void)
1704 {
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)
1711    {
1712       if (check_nop)
1713       {
1714          dst->ops = current_instruction_table.BLEZ_IDLE;
1715          recomp_func = genblez_idle;
1716       }
1717    }
1718    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1719    {
1720       dst->ops = current_instruction_table.BLEZ_OUT;
1721       recomp_func = genblez_out;
1722    }
1723 }
1724
1725 static void RBGTZ(void)
1726 {
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)
1733    {
1734       if (check_nop)
1735       {
1736          dst->ops = current_instruction_table.BGTZ_IDLE;
1737          recomp_func = genbgtz_idle;
1738       }
1739    }
1740    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1741    {
1742       dst->ops = current_instruction_table.BGTZ_OUT;
1743       recomp_func = genbgtz_out;
1744    }
1745 }
1746
1747 static void RADDI(void)
1748 {
1749    dst->ops = current_instruction_table.ADDI;
1750    recomp_func = genaddi;
1751    recompile_standard_i_type();
1752    if(dst->f.i.rt == reg) RNOP();
1753 }
1754
1755 static void RADDIU(void)
1756 {
1757    dst->ops = current_instruction_table.ADDIU;
1758    recomp_func = genaddiu;
1759    recompile_standard_i_type();
1760    if(dst->f.i.rt == reg) RNOP();
1761 }
1762
1763 static void RSLTI(void)
1764 {
1765    dst->ops = current_instruction_table.SLTI;
1766    recomp_func = genslti;
1767    recompile_standard_i_type();
1768    if(dst->f.i.rt == reg) RNOP();
1769 }
1770
1771 static void RSLTIU(void)
1772 {
1773    dst->ops = current_instruction_table.SLTIU;
1774    recomp_func = gensltiu;
1775    recompile_standard_i_type();
1776    if(dst->f.i.rt == reg) RNOP();
1777 }
1778
1779 static void RANDI(void)
1780 {
1781    dst->ops = current_instruction_table.ANDI;
1782    recomp_func = genandi;
1783    recompile_standard_i_type();
1784    if(dst->f.i.rt == reg) RNOP();
1785 }
1786
1787 static void RORI(void)
1788 {
1789    dst->ops = current_instruction_table.ORI;
1790    recomp_func = genori;
1791    recompile_standard_i_type();
1792    if (dst->f.i.rt == reg) RNOP();
1793 }
1794
1795 static void RXORI(void)
1796 {
1797    dst->ops = current_instruction_table.XORI;
1798    recomp_func = genxori;
1799    recompile_standard_i_type();
1800    if (dst->f.i.rt == reg) RNOP();
1801 }
1802
1803 static void RLUI(void)
1804 {
1805    dst->ops = current_instruction_table.LUI;
1806    recomp_func = genlui;
1807    recompile_standard_i_type();
1808    if (dst->f.i.rt == reg) RNOP();
1809 }
1810
1811 static void RCOP0(void)
1812 {
1813    recomp_cop0[((src >> 21) & 0x1F)]();
1814 }
1815
1816 static void RCOP1(void)
1817 {
1818    recomp_cop1[((src >> 21) & 0x1F)]();
1819 }
1820
1821 static void RBEQL(void)
1822 {
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)
1829    {
1830       if (check_nop)
1831       {
1832          dst->ops = current_instruction_table.BEQL_IDLE;
1833          recomp_func = genbeql_idle;
1834       }
1835    }
1836    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1837    {
1838       dst->ops = current_instruction_table.BEQL_OUT;
1839       recomp_func = genbeql_out;
1840    }
1841 }
1842
1843 static void RBNEL(void)
1844 {
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)
1851    {
1852       if (check_nop)
1853       {
1854          dst->ops = current_instruction_table.BNEL_IDLE;
1855          recomp_func = genbnel_idle;
1856       }
1857    }
1858    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1859    {
1860       dst->ops = current_instruction_table.BNEL_OUT;
1861       recomp_func = genbnel_out;
1862    }
1863 }
1864
1865 static void RBLEZL(void)
1866 {
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)
1873    {
1874       if (check_nop)
1875       {
1876          dst->ops = current_instruction_table.BLEZL_IDLE;
1877          recomp_func = genblezl_idle;
1878       }
1879    }
1880    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1881    {
1882       dst->ops = current_instruction_table.BLEZL_OUT;
1883       recomp_func = genblezl_out;
1884    }
1885 }
1886
1887 static void RBGTZL(void)
1888 {
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)
1895    {
1896       if (check_nop)
1897       {
1898          dst->ops = current_instruction_table.BGTZL_IDLE;
1899          recomp_func = genbgtzl_idle;
1900       }
1901    }
1902    else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
1903    {
1904       dst->ops = current_instruction_table.BGTZL_OUT;
1905       recomp_func = genbgtzl_out;
1906    }
1907 }
1908
1909 static void RDADDI(void)
1910 {
1911    dst->ops = current_instruction_table.DADDI;
1912    recomp_func = gendaddi;
1913    recompile_standard_i_type();
1914    if(dst->f.i.rt == reg) RNOP();
1915 }
1916
1917 static void RDADDIU(void)
1918 {
1919    dst->ops = current_instruction_table.DADDIU;
1920    recomp_func = gendaddiu;
1921    recompile_standard_i_type();
1922    if(dst->f.i.rt == reg) RNOP();
1923 }
1924
1925 static void RLDL(void)
1926 {
1927    dst->ops = current_instruction_table.LDL;
1928    recomp_func = genldl;
1929    recompile_standard_i_type();
1930    if(dst->f.i.rt == reg) RNOP();
1931 }
1932
1933 static void RLDR(void)
1934 {
1935    dst->ops = current_instruction_table.LDR;
1936    recomp_func = genldr;
1937    recompile_standard_i_type();
1938    if(dst->f.i.rt == reg) RNOP();
1939 }
1940
1941 static void RLB(void)
1942 {
1943    dst->ops = current_instruction_table.LB;
1944    recomp_func = genlb;
1945    recompile_standard_i_type();
1946    if (dst->f.i.rt == reg) RNOP();
1947 }
1948
1949 static void RLH(void)
1950 {
1951    dst->ops = current_instruction_table.LH;
1952    recomp_func = genlh;
1953    recompile_standard_i_type();
1954    if (dst->f.i.rt == reg) RNOP();
1955 }
1956
1957 static void RLWL(void)
1958 {
1959    dst->ops = current_instruction_table.LWL;
1960    recomp_func = genlwl;
1961    recompile_standard_i_type();
1962    if (dst->f.i.rt == reg) RNOP();
1963 }
1964
1965 static void RLW(void)
1966 {
1967    dst->ops = current_instruction_table.LW;
1968    recomp_func = genlw;
1969    recompile_standard_i_type();
1970    if (dst->f.i.rt == reg) RNOP();
1971 }
1972
1973 static void RLBU(void)
1974 {
1975    dst->ops = current_instruction_table.LBU;
1976    recomp_func = genlbu;
1977    recompile_standard_i_type();
1978    if(dst->f.i.rt == reg) RNOP();
1979 }
1980
1981 static void RLHU(void)
1982 {
1983    dst->ops = current_instruction_table.LHU;
1984    recomp_func = genlhu;
1985    recompile_standard_i_type();
1986    if(dst->f.i.rt == reg) RNOP();
1987 }
1988
1989 static void RLWR(void)
1990 {
1991    dst->ops = current_instruction_table.LWR;
1992    recomp_func = genlwr;
1993    recompile_standard_i_type();
1994    if(dst->f.i.rt == reg) RNOP();
1995 }
1996
1997 static void RLWU(void)
1998 {
1999    dst->ops = current_instruction_table.LWU;
2000    recomp_func = genlwu;
2001    recompile_standard_i_type();
2002    if(dst->f.i.rt == reg) RNOP();
2003 }
2004
2005 static void RSB(void)
2006 {
2007    dst->ops = current_instruction_table.SB;
2008    recomp_func = gensb;
2009    recompile_standard_i_type();
2010 }
2011
2012 static void RSH(void)
2013 {
2014    dst->ops = current_instruction_table.SH;
2015    recomp_func = gensh;
2016    recompile_standard_i_type();
2017 }
2018
2019 static void RSWL(void)
2020 {
2021    dst->ops = current_instruction_table.SWL;
2022    recomp_func = genswl;
2023    recompile_standard_i_type();
2024 }
2025
2026 static void RSW(void)
2027 {
2028    dst->ops = current_instruction_table.SW;
2029    recomp_func = gensw;
2030    recompile_standard_i_type();
2031 }
2032
2033 static void RSDL(void)
2034 {
2035    dst->ops = current_instruction_table.SDL;
2036    recomp_func = gensdl;
2037    recompile_standard_i_type();
2038 }
2039
2040 static void RSDR(void)
2041 {
2042    dst->ops = current_instruction_table.SDR;
2043    recomp_func = gensdr;
2044    recompile_standard_i_type();
2045 }
2046
2047 static void RSWR(void)
2048 {
2049    dst->ops = current_instruction_table.SWR;
2050    recomp_func = genswr;
2051    recompile_standard_i_type();
2052 }
2053
2054 static void RCACHE(void)
2055 {
2056    recomp_func = gencache;
2057    dst->ops = current_instruction_table.CACHE;
2058 }
2059
2060 static void RLL(void)
2061 {
2062    recomp_func = genll;
2063    dst->ops = current_instruction_table.LL;
2064    recompile_standard_i_type();
2065    if(dst->f.i.rt == reg) RNOP();
2066 }
2067
2068 static void RLWC1(void)
2069 {
2070    dst->ops = current_instruction_table.LWC1;
2071    recomp_func = genlwc1;
2072    recompile_standard_lf_type();
2073 }
2074
2075 static void RLLD(void)
2076 {
2077    dst->ops = current_instruction_table.NI;
2078    recomp_func = genni;
2079    recompile_standard_i_type();
2080 }
2081
2082 static void RLDC1(void)
2083 {
2084    dst->ops = current_instruction_table.LDC1;
2085    recomp_func = genldc1;
2086    recompile_standard_lf_type();
2087 }
2088
2089 static void RLD(void)
2090 {
2091    dst->ops = current_instruction_table.LD;
2092    recomp_func = genld;
2093    recompile_standard_i_type();
2094    if (dst->f.i.rt == reg) RNOP();
2095 }
2096
2097 static void RSC(void)
2098 {
2099    dst->ops = current_instruction_table.SC;
2100    recomp_func = gensc;
2101    recompile_standard_i_type();
2102    if (dst->f.i.rt == reg) RNOP();
2103 }
2104
2105 static void RSWC1(void)
2106 {
2107    dst->ops = current_instruction_table.SWC1;
2108    recomp_func = genswc1;
2109    recompile_standard_lf_type();
2110 }
2111
2112 static void RSCD(void)
2113 {
2114    dst->ops = current_instruction_table.NI;
2115    recomp_func = genni;
2116    recompile_standard_i_type();
2117 }
2118
2119 static void RSDC1(void)
2120 {
2121    dst->ops = current_instruction_table.SDC1;
2122    recomp_func = gensdc1;
2123    recompile_standard_lf_type();
2124 }
2125
2126 static void RSD(void)
2127 {
2128    dst->ops = current_instruction_table.SD;
2129    recomp_func = gensd;
2130    recompile_standard_i_type();
2131 }
2132
2133 static void (*recomp_ops[64])(void) =
2134 {
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
2143 };
2144
2145 static int get_block_length(const precomp_block *block)
2146 {
2147   return (block->end-block->start)/4;
2148 }
2149
2150 static size_t get_block_memsize(const precomp_block *block)
2151 {
2152   int length = get_block_length(block);
2153   return ((length+1)+(length>>2)) * sizeof(precomp_instr);
2154 }
2155
2156 /**********************************************************************
2157  ******************** initialize an empty block ***********************
2158  **********************************************************************/
2159 void init_block(precomp_block *block)
2160 {
2161   int i, length, already_exist = 1;
2162   static int init_length;
2163   start_section(COMPILER_SECTION);
2164 #ifdef CORE_DBG
2165   DebugMessage(M64MSG_INFO, "init block %x - %x", (int) block->start, (int) block->end);
2166 #endif
2167
2168   length = get_block_length(block);
2169    
2170   if (!block->block)
2171   {
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.");
2177             return;
2178         }
2179     }
2180     else {
2181         block->block = (precomp_instr *) malloc(memsize);
2182         if (!block->block) {
2183             DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate memory for cached interpreter.");
2184             return;
2185         }
2186     }
2187
2188     memset(block->block, 0, memsize);
2189     already_exist = 0;
2190   }
2191
2192   if (r4300emu == CORE_DYNAREC)
2193   {
2194     if (!block->code)
2195     {
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                */
2199 #else
2200       max_code_length = 32768;
2201 #endif
2202       block->code = (unsigned char *) malloc_exec(max_code_length);
2203     }
2204     else
2205     {
2206       max_code_length = block->max_code_length;
2207     }
2208     code_length = 0;
2209     inst_pointer = &block->code;
2210     
2211     if (block->jumps_table)
2212     {
2213       free(block->jumps_table);
2214       block->jumps_table = NULL;
2215     }
2216     if (block->riprel_table)
2217     {
2218       free(block->riprel_table);
2219       block->riprel_table = NULL;
2220     }
2221     init_assembler(NULL, 0, NULL, 0);
2222     init_cache(block->block);
2223   }
2224    
2225   if (!already_exist)
2226   {
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");
2234 #endif
2235
2236     for (i=0; i<length; i++)
2237     {
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;
2242 #ifdef COMPARE_CORE
2243       if (r4300emu == CORE_DYNAREC) gendebug();
2244 #endif
2245       RNOTCOMPILED();
2246       if (r4300emu == CORE_DYNAREC) recomp_func();
2247     }
2248 #if defined(PROFILE_R4300)
2249   fclose(pfProfile);
2250   pfProfile = NULL;
2251 #endif
2252   init_length = code_length;
2253   }
2254   else
2255   {
2256 #if defined(PROFILE_R4300)
2257     code_length = block->code_length; /* leave old instructions in their place */
2258 #else
2259     code_length = init_length; /* recompile everything, overwrite old recompiled instructions */
2260 #endif
2261     for (i=0; i<length; i++)
2262     {
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;
2267     }
2268   }
2269    
2270   if (r4300emu == CORE_DYNAREC)
2271   {
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);
2278   }
2279    
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.
2282    */
2283   invalid_code[block->start>>12] = 0;
2284   if (block->end < 0x80000000 || block->start >= 0xc0000000)
2285   { 
2286     unsigned int paddr;
2287     
2288     paddr = virtual_to_physical_address(block->start, 2);
2289     invalid_code[paddr>>12] = 0;
2290     if (!blocks[paddr>>12])
2291     {
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;
2299     }
2300     init_block(blocks[paddr>>12]);
2301     
2302     paddr += block->end - block->start - 4;
2303     invalid_code[paddr>>12] = 0;
2304     if (!blocks[paddr>>12])
2305     {
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;
2313     }
2314     init_block(blocks[paddr>>12]);
2315   }
2316   else
2317   {
2318     if (block->start >= 0x80000000 && block->end < 0xa0000000 && invalid_code[(block->start+0x20000000)>>12])
2319     {
2320       if (!blocks[(block->start+0x20000000)>>12])
2321       {
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;
2329       }
2330       init_block(blocks[(block->start+0x20000000)>>12]);
2331     }
2332     if (block->start >= 0xa0000000 && block->end < 0xc0000000 && invalid_code[(block->start-0x20000000)>>12])
2333     {
2334       if (!blocks[(block->start-0x20000000)>>12])
2335       {
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;
2343       }
2344       init_block(blocks[(block->start-0x20000000)>>12]);
2345     }
2346   }
2347   end_section(COMPILER_SECTION);
2348 }
2349
2350 void free_block(precomp_block *block)
2351 {
2352     size_t memsize = get_block_memsize(block);
2353
2354     if (block->block) {
2355         if (r4300emu == CORE_DYNAREC)
2356             free_exec(block->block, memsize);
2357         else
2358             free(block->block);
2359         block->block = NULL;
2360     }
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; }
2364 }
2365
2366 /**********************************************************************
2367  ********************* recompile a block of code **********************
2368  **********************************************************************/
2369 void recompile_block(int *source, precomp_block *block, unsigned int func)
2370 {
2371    int i, length, finished=0;
2372    start_section(COMPILER_SECTION);
2373    length = (block->end-block->start)/4;
2374    dst_block = block;
2375    
2376    //for (i=0; i<16; i++) block->md5[i] = 0;
2377    block->adler32 = 0;
2378    
2379    if (r4300emu == CORE_DYNAREC)
2380      {
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);
2386      }
2387
2388 #if defined(PROFILE_R4300)
2389    pfProfile = fopen("instructionaddrs.dat", "ab");
2390 #endif
2391
2392    for (i = (func & 0xFFF) / 4; finished != 2; i++)
2393      {
2394     if(block->start < 0x80000000 || block->start >= 0xc0000000)
2395       {
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;
2400       }
2401     
2402     SRC = source + i;
2403     src = source[i];
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;
2409 #ifdef COMPARE_CORE
2410     if (r4300emu == CORE_DYNAREC) gendebug();
2411 #endif
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");
2417 #endif
2418     recomp_func = NULL;
2419     recomp_ops[((src >> 26) & 0x3F)]();
2420     if (r4300emu == CORE_DYNAREC) recomp_func();
2421     dst = block->block + i;
2422
2423     /*if ((dst+1)->ops != NOTCOMPILED && !delay_slot_compiled &&
2424         i < length)
2425       {
2426          if (r4300emu == CORE_DYNAREC) genlink_subblock();
2427          finished = 2;
2428       }*/
2429     if (delay_slot_compiled) 
2430       {
2431          delay_slot_compiled--;
2432          free_all_registers();
2433       }
2434     
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)))
2446       finished = 1;
2447      }
2448
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");
2455 #endif
2456
2457    if (i >= length)
2458      {
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;
2463 #ifdef COMPARE_CORE
2464     if (r4300emu == CORE_DYNAREC) gendebug();
2465 #endif
2466     RFIN_BLOCK();
2467     if (r4300emu == CORE_DYNAREC) recomp_func();
2468     i++;
2469     if (i < length-1+(length>>2)) // useful when last opcode is a jump
2470       {
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;
2475 #ifdef COMPARE_CORE
2476          if (r4300emu == CORE_DYNAREC) gendebug();
2477 #endif
2478          RFIN_BLOCK();
2479          if (r4300emu == CORE_DYNAREC) recomp_func();
2480          i++;
2481       }
2482      }
2483    else if (r4300emu == CORE_DYNAREC) genlink_subblock();
2484
2485    if (r4300emu == CORE_DYNAREC)
2486      {
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);
2492      }
2493 #ifdef CORE_DBG
2494    DebugMessage(M64MSG_INFO, "block recompiled (%x-%x)", (int)func, (int)(block->start+i*4));
2495 #endif
2496 #if defined(PROFILE_R4300)
2497    fclose(pfProfile);
2498    pfProfile = NULL;
2499 #endif
2500    end_section(COMPILER_SECTION);
2501 }
2502
2503 static int is_jump(void)
2504 {
2505    recomp_ops[((src >> 26) & 0x3F)]();
2506    return
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);
2575 }
2576
2577 /**********************************************************************
2578  ************ recompile only one opcode (use for delay slot) **********
2579  **********************************************************************/
2580 void recompile_opcode(void)
2581 {
2582    SRC++;
2583    src = *SRC;
2584    dst++;
2585    dst->addr = (dst-1)->addr + 4;
2586    dst->reg_cache_infos.need_map = 0;
2587    if(!is_jump())
2588    {
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");
2594 #endif
2595      recomp_func = NULL;
2596      recomp_ops[((src >> 26) & 0x3F)]();
2597      if (r4300emu == CORE_DYNAREC) recomp_func();
2598    }
2599    else
2600    {
2601      RNOP();
2602      if (r4300emu == CORE_DYNAREC) recomp_func();
2603    }
2604    delay_slot_compiled = 2;
2605 }
2606
2607 /**********************************************************************
2608  ************** decode one opcode (for the interpreter) ***************
2609  **********************************************************************/
2610 void prefetch_opcode(unsigned int op, unsigned int nextop)
2611 {
2612    dst = PC;
2613    src = op;
2614    check_nop = nextop == 0;
2615    recomp_ops[((src >> 26) & 0x3F)]();
2616 }
2617
2618 /**********************************************************************
2619  ************** allocate memory with executable bit set ***************
2620  **********************************************************************/
2621 static void *malloc_exec(size_t size)
2622 {
2623 #if defined(WIN32)
2624    return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
2625 #elif defined(__GNUC__)
2626
2627    #ifndef  MAP_ANONYMOUS
2628       #ifdef MAP_ANON
2629          #define MAP_ANONYMOUS MAP_ANON
2630       #endif
2631    #endif
2632
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; }
2636
2637    return block;
2638 #else
2639    return malloc(size);
2640 #endif
2641 }
2642
2643 /**********************************************************************
2644  ************* reallocate memory with executable bit set **************
2645  **********************************************************************/
2646 void *realloc_exec(void *ptr, size_t oldsize, size_t newsize)
2647 {
2648    void* block = malloc_exec(newsize);
2649    if (block != NULL)
2650    {
2651       size_t copysize;
2652       if (oldsize < newsize)
2653          copysize = oldsize;
2654       else
2655          copysize = newsize;
2656       memcpy(block, ptr, copysize);
2657    }
2658    free_exec(ptr, oldsize);
2659    return block;
2660 }
2661
2662 /**********************************************************************
2663  **************** frees memory with executable bit set ****************
2664  **********************************************************************/
2665 static void free_exec(void *ptr, size_t length)
2666 {
2667 #if defined(WIN32)
2668    VirtualFree(ptr, 0, MEM_RELEASE);
2669 #elif defined(__GNUC__)
2670    munmap(ptr, length);
2671 #else
2672    free(ptr);
2673 #endif
2674 }