Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / recomp.c
diff --git a/source/mupen64plus-core/src/r4300/recomp.c b/source/mupen64plus-core/src/r4300/recomp.c
new file mode 100644 (file)
index 0000000..dfca49a
--- /dev/null
@@ -0,0 +1,2674 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *   Mupen64plus - recomp.h                                                *
+ *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
+ *   Copyright (C) 2002 Hacktarux                                          *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(__GNUC__)
+#include <unistd.h>
+#ifndef __MINGW32__
+#include <sys/mman.h>
+#endif
+#endif
+
+#include "api/m64p_types.h"
+#include "api/callbacks.h"
+#include "memory/memory.h"
+
+#include "recomp.h"
+#include "recomph.h" //include for function prototypes
+#include "macros.h"
+#include "r4300.h"
+#include "ops.h"
+
+static void *malloc_exec(size_t size);
+static void free_exec(void *ptr, size_t length);
+
+// global variables :
+precomp_instr *dst; // destination structure for the recompiled instruction
+int code_length; // current real recompiled code length
+int max_code_length; // current recompiled code's buffer length
+unsigned char **inst_pointer; // output buffer for recompiled code
+precomp_block *dst_block; // the current block that we are recompiling
+int src; // the current recompiled instruction
+int fast_memory;
+
+static void (*recomp_func)(void); // pointer to the dynarec's generator
+                                  // function for the latest decoded opcode
+
+#if defined(PROFILE_R4300)
+FILE *pfProfile;
+#endif
+
+static int *SRC; // currently recompiled instruction in the input stream
+static int check_nop; // next instruction is nop ?
+static int delay_slot_compiled = 0;
+
+
+
+static void RSV(void)
+{
+   dst->ops = current_instruction_table.RESERVED;
+   recomp_func = genreserved;
+}
+
+static void RFIN_BLOCK(void)
+{
+   dst->ops = current_instruction_table.FIN_BLOCK;
+   recomp_func = genfin_block;
+}
+
+static void RNOTCOMPILED(void)
+{
+   dst->ops = current_instruction_table.NOTCOMPILED;
+   recomp_func = gennotcompiled;
+}
+
+static void recompile_standard_i_type(void)
+{
+   dst->f.i.rs = reg + ((src >> 21) & 0x1F);
+   dst->f.i.rt = reg + ((src >> 16) & 0x1F);
+   dst->f.i.immediate = src & 0xFFFF;
+}
+
+static void recompile_standard_j_type(void)
+{
+   dst->f.j.inst_index = src & 0x3FFFFFF;
+}
+
+static void recompile_standard_r_type(void)
+{
+   dst->f.r.rs = reg + ((src >> 21) & 0x1F);
+   dst->f.r.rt = reg + ((src >> 16) & 0x1F);
+   dst->f.r.rd = reg + ((src >> 11) & 0x1F);
+   dst->f.r.sa = (src >>  6) & 0x1F;
+}
+
+static void recompile_standard_lf_type(void)
+{
+   dst->f.lf.base = (src >> 21) & 0x1F;
+   dst->f.lf.ft = (src >> 16) & 0x1F;
+   dst->f.lf.offset = src & 0xFFFF;
+}
+
+static void recompile_standard_cf_type(void)
+{
+   dst->f.cf.ft = (src >> 16) & 0x1F;
+   dst->f.cf.fs = (src >> 11) & 0x1F;
+   dst->f.cf.fd = (src >>  6) & 0x1F;
+}
+
+//-------------------------------------------------------------------------
+//                                  SPECIAL                                
+//-------------------------------------------------------------------------
+
+static void RNOP(void)
+{
+   dst->ops = current_instruction_table.NOP;
+   recomp_func = gennop;
+}
+
+static void RSLL(void)
+{
+   dst->ops = current_instruction_table.SLL;
+   recomp_func = gensll;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RSRL(void)
+{
+   dst->ops = current_instruction_table.SRL;
+   recomp_func = gensrl;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RSRA(void)
+{
+   dst->ops = current_instruction_table.SRA;
+   recomp_func = gensra;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RSLLV(void)
+{
+   dst->ops = current_instruction_table.SLLV;
+   recomp_func = gensllv;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RSRLV(void)
+{
+   dst->ops = current_instruction_table.SRLV;
+   recomp_func = gensrlv;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RSRAV(void)
+{
+   dst->ops = current_instruction_table.SRAV;
+   recomp_func = gensrav;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RJR(void)
+{
+   dst->ops = current_instruction_table.JR;
+   recomp_func = genjr;
+   recompile_standard_i_type();
+}
+
+static void RJALR(void)
+{
+   dst->ops = current_instruction_table.JALR;
+   recomp_func = genjalr;
+   recompile_standard_r_type();
+}
+
+static void RSYSCALL(void)
+{
+   dst->ops = current_instruction_table.SYSCALL;
+   recomp_func = gensyscall;
+}
+
+static void RBREAK(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RSYNC(void)
+{
+   dst->ops = current_instruction_table.SYNC;
+   recomp_func = gensync;
+}
+
+static void RMFHI(void)
+{
+   dst->ops = current_instruction_table.MFHI;
+   recomp_func = genmfhi;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RMTHI(void)
+{
+   dst->ops = current_instruction_table.MTHI;
+   recomp_func = genmthi;
+   recompile_standard_r_type();
+}
+
+static void RMFLO(void)
+{
+   dst->ops = current_instruction_table.MFLO;
+   recomp_func = genmflo;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RMTLO(void)
+{
+   dst->ops = current_instruction_table.MTLO;
+   recomp_func = genmtlo;
+   recompile_standard_r_type();
+}
+
+static void RDSLLV(void)
+{
+   dst->ops = current_instruction_table.DSLLV;
+   recomp_func = gendsllv;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDSRLV(void)
+{
+   dst->ops = current_instruction_table.DSRLV;
+   recomp_func = gendsrlv;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDSRAV(void)
+{
+   dst->ops = current_instruction_table.DSRAV;
+   recomp_func = gendsrav;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RMULT(void)
+{
+   dst->ops = current_instruction_table.MULT;
+   recomp_func = genmult;
+   recompile_standard_r_type();
+}
+
+static void RMULTU(void)
+{
+   dst->ops = current_instruction_table.MULTU;
+   recomp_func = genmultu;
+   recompile_standard_r_type();
+}
+
+static void RDIV(void)
+{
+   dst->ops = current_instruction_table.DIV;
+   recomp_func = gendiv;
+   recompile_standard_r_type();
+}
+
+static void RDIVU(void)
+{
+   dst->ops = current_instruction_table.DIVU;
+   recomp_func = gendivu;
+   recompile_standard_r_type();
+}
+
+static void RDMULT(void)
+{
+   dst->ops = current_instruction_table.DMULT;
+   recomp_func = gendmult;
+   recompile_standard_r_type();
+}
+
+static void RDMULTU(void)
+{
+   dst->ops = current_instruction_table.DMULTU;
+   recomp_func = gendmultu;
+   recompile_standard_r_type();
+}
+
+static void RDDIV(void)
+{
+   dst->ops = current_instruction_table.DDIV;
+   recomp_func = genddiv;
+   recompile_standard_r_type();
+}
+
+static void RDDIVU(void)
+{
+   dst->ops = current_instruction_table.DDIVU;
+   recomp_func = genddivu;
+   recompile_standard_r_type();
+}
+
+static void RADD(void)
+{
+   dst->ops = current_instruction_table.ADD;
+   recomp_func = genadd;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RADDU(void)
+{
+   dst->ops = current_instruction_table.ADDU;
+   recomp_func = genaddu;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RSUB(void)
+{
+   dst->ops = current_instruction_table.SUB;
+   recomp_func = gensub;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RSUBU(void)
+{
+   dst->ops = current_instruction_table.SUBU;
+   recomp_func = gensubu;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RAND(void)
+{
+   dst->ops = current_instruction_table.AND;
+   recomp_func = genand;
+   recompile_standard_r_type();
+   if(dst->f.r.rd == reg) RNOP();
+}
+
+static void ROR(void)
+{
+   dst->ops = current_instruction_table.OR;
+   recomp_func = genor;
+   recompile_standard_r_type();
+   if(dst->f.r.rd == reg) RNOP();
+}
+
+static void RXOR(void)
+{
+   dst->ops = current_instruction_table.XOR;
+   recomp_func = genxor;
+   recompile_standard_r_type();
+   if(dst->f.r.rd == reg) RNOP();
+}
+
+static void RNOR(void)
+{
+   dst->ops = current_instruction_table.NOR;
+   recomp_func = gennor;
+   recompile_standard_r_type();
+   if(dst->f.r.rd == reg) RNOP();
+}
+
+static void RSLT(void)
+{
+   dst->ops = current_instruction_table.SLT;
+   recomp_func = genslt;
+   recompile_standard_r_type();
+   if(dst->f.r.rd == reg) RNOP();
+}
+
+static void RSLTU(void)
+{
+   dst->ops = current_instruction_table.SLTU;
+   recomp_func = gensltu;
+   recompile_standard_r_type();
+   if(dst->f.r.rd == reg) RNOP();
+}
+
+static void RDADD(void)
+{
+   dst->ops = current_instruction_table.DADD;
+   recomp_func = gendadd;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDADDU(void)
+{
+   dst->ops = current_instruction_table.DADDU;
+   recomp_func = gendaddu;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDSUB(void)
+{
+   dst->ops = current_instruction_table.DSUB;
+   recomp_func = gendsub;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDSUBU(void)
+{
+   dst->ops = current_instruction_table.DSUBU;
+   recomp_func = gendsubu;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RTGE(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RTGEU(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RTLT(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RTLTU(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RTEQ(void)
+{
+   dst->ops = current_instruction_table.TEQ;
+   recomp_func = genteq;
+   recompile_standard_r_type();
+}
+
+static void RTNE(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RDSLL(void)
+{
+   dst->ops = current_instruction_table.DSLL;
+   recomp_func = gendsll;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDSRL(void)
+{
+   dst->ops = current_instruction_table.DSRL;
+   recomp_func = gendsrl;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDSRA(void)
+{
+   dst->ops = current_instruction_table.DSRA;
+   recomp_func = gendsra;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDSLL32(void)
+{
+   dst->ops = current_instruction_table.DSLL32;
+   recomp_func = gendsll32;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDSRL32(void)
+{
+   dst->ops = current_instruction_table.DSRL32;
+   recomp_func = gendsrl32;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void RDSRA32(void)
+{
+   dst->ops = current_instruction_table.DSRA32;
+   recomp_func = gendsra32;
+   recompile_standard_r_type();
+   if (dst->f.r.rd == reg) RNOP();
+}
+
+static void (*recomp_special[64])(void) =
+{
+   RSLL , RSV   , RSRL , RSRA , RSLLV   , RSV    , RSRLV  , RSRAV  ,
+   RJR  , RJALR , RSV  , RSV  , RSYSCALL, RBREAK , RSV    , RSYNC  ,
+   RMFHI, RMTHI , RMFLO, RMTLO, RDSLLV  , RSV    , RDSRLV , RDSRAV ,
+   RMULT, RMULTU, RDIV , RDIVU, RDMULT  , RDMULTU, RDDIV  , RDDIVU ,
+   RADD , RADDU , RSUB , RSUBU, RAND    , ROR    , RXOR   , RNOR   ,
+   RSV  , RSV   , RSLT , RSLTU, RDADD   , RDADDU , RDSUB  , RDSUBU ,
+   RTGE , RTGEU , RTLT , RTLTU, RTEQ    , RSV    , RTNE   , RSV    ,
+   RDSLL, RSV   , RDSRL, RDSRA, RDSLL32 , RSV    , RDSRL32, RDSRA32
+};
+
+//-------------------------------------------------------------------------
+//                                   REGIMM                                
+//-------------------------------------------------------------------------
+
+static void RBLTZ(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BLTZ;
+   recomp_func = genbltz;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BLTZ_IDLE;
+         recomp_func = genbltz_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BLTZ_OUT;
+      recomp_func = genbltz_out;
+   }
+}
+
+static void RBGEZ(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BGEZ;
+   recomp_func = genbgez;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BGEZ_IDLE;
+         recomp_func = genbgez_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BGEZ_OUT;
+      recomp_func = genbgez_out;
+   }
+}
+
+static void RBLTZL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BLTZL;
+   recomp_func = genbltzl;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BLTZL_IDLE;
+         recomp_func = genbltzl_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BLTZL_OUT;
+      recomp_func = genbltzl_out;
+   }
+}
+
+static void RBGEZL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BGEZL;
+   recomp_func = genbgezl;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BGEZL_IDLE;
+         recomp_func = genbgezl_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BGEZL_OUT;
+      recomp_func = genbgezl_out;
+   }
+}
+
+static void RTGEI(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RTGEIU(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RTLTI(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RTLTIU(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RTEQI(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RTNEI(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+}
+
+static void RBLTZAL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BLTZAL;
+   recomp_func = genbltzal;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BLTZAL_IDLE;
+         recomp_func = genbltzal_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BLTZAL_OUT;
+      recomp_func = genbltzal_out;
+   }
+}
+
+static void RBGEZAL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BGEZAL;
+   recomp_func = genbgezal;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BGEZAL_IDLE;
+         recomp_func = genbgezal_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BGEZAL_OUT;
+      recomp_func = genbgezal_out;
+   }
+}
+
+static void RBLTZALL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BLTZALL;
+   recomp_func = genbltzall;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BLTZALL_IDLE;
+         recomp_func = genbltzall_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BLTZALL_OUT;
+      recomp_func = genbltzall_out;
+   }
+}
+
+static void RBGEZALL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BGEZALL;
+   recomp_func = genbgezall;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BGEZALL_IDLE;
+         recomp_func = genbgezall_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BGEZALL_OUT;
+      recomp_func = genbgezall_out;
+   }
+}
+
+static void (*recomp_regimm[32])(void) =
+{
+   RBLTZ  , RBGEZ  , RBLTZL  , RBGEZL  , RSV  , RSV, RSV  , RSV,
+   RTGEI  , RTGEIU , RTLTI   , RTLTIU  , RTEQI, RSV, RTNEI, RSV,
+   RBLTZAL, RBGEZAL, RBLTZALL, RBGEZALL, RSV  , RSV, RSV  , RSV,
+   RSV    , RSV    , RSV     , RSV     , RSV  , RSV, RSV  , RSV
+};
+
+//-------------------------------------------------------------------------
+//                                     TLB                                 
+//-------------------------------------------------------------------------
+
+static void RTLBR(void)
+{
+   dst->ops = current_instruction_table.TLBR;
+   recomp_func = gentlbr;
+}
+
+static void RTLBWI(void)
+{
+   dst->ops = current_instruction_table.TLBWI;
+   recomp_func = gentlbwi;
+}
+
+static void RTLBWR(void)
+{
+   dst->ops = current_instruction_table.TLBWR;
+   recomp_func = gentlbwr;
+}
+
+static void RTLBP(void)
+{
+   dst->ops = current_instruction_table.TLBP;
+   recomp_func = gentlbp;
+}
+
+static void RERET(void)
+{
+   dst->ops = current_instruction_table.ERET;
+   recomp_func = generet;
+}
+
+static void (*recomp_tlb[64])(void) =
+{
+   RSV  , RTLBR, RTLBWI, RSV, RSV, RSV, RTLBWR, RSV, 
+   RTLBP, RSV  , RSV   , RSV, RSV, RSV, RSV   , RSV, 
+   RSV  , RSV  , RSV   , RSV, RSV, RSV, RSV   , RSV, 
+   RERET, RSV  , RSV   , RSV, RSV, RSV, RSV   , RSV, 
+   RSV  , RSV  , RSV   , RSV, RSV, RSV, RSV   , RSV, 
+   RSV  , RSV  , RSV   , RSV, RSV, RSV, RSV   , RSV, 
+   RSV  , RSV  , RSV   , RSV, RSV, RSV, RSV   , RSV, 
+   RSV  , RSV  , RSV   , RSV, RSV, RSV, RSV   , RSV
+};
+
+//-------------------------------------------------------------------------
+//                                    COP0                                 
+//-------------------------------------------------------------------------
+
+static void RMFC0(void)
+{
+   dst->ops = current_instruction_table.MFC0;
+   recomp_func = genmfc0;
+   recompile_standard_r_type();
+   dst->f.r.rd = (long long*)(reg_cop0 + ((src >> 11) & 0x1F));
+   dst->f.r.nrd = (src >> 11) & 0x1F;
+   if (dst->f.r.rt == reg) RNOP();
+}
+
+static void RMTC0(void)
+{
+   dst->ops = current_instruction_table.MTC0;
+   recomp_func = genmtc0;
+   recompile_standard_r_type();
+   dst->f.r.nrd = (src >> 11) & 0x1F;
+}
+
+static void RTLB(void)
+{
+   recomp_tlb[(src & 0x3F)]();
+}
+
+static void (*recomp_cop0[32])(void) =
+{
+   RMFC0, RSV, RSV, RSV, RMTC0, RSV, RSV, RSV,
+   RSV  , RSV, RSV, RSV, RSV  , RSV, RSV, RSV,
+   RTLB , RSV, RSV, RSV, RSV  , RSV, RSV, RSV,
+   RSV  , RSV, RSV, RSV, RSV  , RSV, RSV, RSV
+};
+
+//-------------------------------------------------------------------------
+//                                     BC                                  
+//-------------------------------------------------------------------------
+
+static void RBC1F(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BC1F;
+   recomp_func = genbc1f;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BC1F_IDLE;
+         recomp_func = genbc1f_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BC1F_OUT;
+      recomp_func = genbc1f_out;
+   }
+}
+
+static void RBC1T(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BC1T;
+   recomp_func = genbc1t;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BC1T_IDLE;
+         recomp_func = genbc1t_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BC1T_OUT;
+      recomp_func = genbc1t_out;
+   }
+}
+
+static void RBC1FL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BC1FL;
+   recomp_func = genbc1fl;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BC1FL_IDLE;
+         recomp_func = genbc1fl_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BC1FL_OUT;
+      recomp_func = genbc1fl_out;
+   }
+}
+
+static void RBC1TL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BC1TL;
+   recomp_func = genbc1tl;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BC1TL_IDLE;
+         recomp_func = genbc1tl_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BC1TL_OUT;
+      recomp_func = genbc1tl_out;
+   }
+}
+
+static void (*recomp_bc[4])(void) =
+{
+   RBC1F , RBC1T ,
+   RBC1FL, RBC1TL
+};
+
+//-------------------------------------------------------------------------
+//                                     S                                   
+//-------------------------------------------------------------------------
+
+static void RADD_S(void)
+{
+   dst->ops = current_instruction_table.ADD_S;
+   recomp_func = genadd_s;
+   recompile_standard_cf_type();
+}
+
+static void RSUB_S(void)
+{
+   dst->ops = current_instruction_table.SUB_S;
+   recomp_func = gensub_s;
+   recompile_standard_cf_type();
+}
+
+static void RMUL_S(void)
+{
+   dst->ops = current_instruction_table.MUL_S;
+   recomp_func = genmul_s;
+   recompile_standard_cf_type();
+}
+
+static void RDIV_S(void)
+{
+   dst->ops = current_instruction_table.DIV_S;
+   recomp_func = gendiv_s;
+   recompile_standard_cf_type();
+}
+
+static void RSQRT_S(void)
+{
+   dst->ops = current_instruction_table.SQRT_S;
+   recomp_func = gensqrt_s;
+   recompile_standard_cf_type();
+}
+
+static void RABS_S(void)
+{
+   dst->ops = current_instruction_table.ABS_S;
+   recomp_func = genabs_s;
+   recompile_standard_cf_type();
+}
+
+static void RMOV_S(void)
+{
+   dst->ops = current_instruction_table.MOV_S;
+   recomp_func = genmov_s;
+   recompile_standard_cf_type();
+}
+
+static void RNEG_S(void)
+{
+   dst->ops = current_instruction_table.NEG_S;
+   recomp_func = genneg_s;
+   recompile_standard_cf_type();
+}
+
+static void RROUND_L_S(void)
+{
+   dst->ops = current_instruction_table.ROUND_L_S;
+   recomp_func = genround_l_s;
+   recompile_standard_cf_type();
+}
+
+static void RTRUNC_L_S(void)
+{
+   dst->ops = current_instruction_table.TRUNC_L_S;
+   recomp_func = gentrunc_l_s;
+   recompile_standard_cf_type();
+}
+
+static void RCEIL_L_S(void)
+{
+   dst->ops = current_instruction_table.CEIL_L_S;
+   recomp_func = genceil_l_s;
+   recompile_standard_cf_type();
+}
+
+static void RFLOOR_L_S(void)
+{
+   dst->ops = current_instruction_table.FLOOR_L_S;
+   recomp_func = genfloor_l_s;
+   recompile_standard_cf_type();
+}
+
+static void RROUND_W_S(void)
+{
+   dst->ops = current_instruction_table.ROUND_W_S;
+   recomp_func = genround_w_s;
+   recompile_standard_cf_type();
+}
+
+static void RTRUNC_W_S(void)
+{
+   dst->ops = current_instruction_table.TRUNC_W_S;
+   recomp_func = gentrunc_w_s;
+   recompile_standard_cf_type();
+}
+
+static void RCEIL_W_S(void)
+{
+   dst->ops = current_instruction_table.CEIL_W_S;
+   recomp_func = genceil_w_s;
+   recompile_standard_cf_type();
+}
+
+static void RFLOOR_W_S(void)
+{
+   dst->ops = current_instruction_table.FLOOR_W_S;
+   recomp_func = genfloor_w_s;
+   recompile_standard_cf_type();
+}
+
+static void RCVT_D_S(void)
+{
+   dst->ops = current_instruction_table.CVT_D_S;
+   recomp_func = gencvt_d_s;
+   recompile_standard_cf_type();
+}
+
+static void RCVT_W_S(void)
+{
+   dst->ops = current_instruction_table.CVT_W_S;
+   recomp_func = gencvt_w_s;
+   recompile_standard_cf_type();
+}
+
+static void RCVT_L_S(void)
+{
+   dst->ops = current_instruction_table.CVT_L_S;
+   recomp_func = gencvt_l_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_F_S(void)
+{
+   dst->ops = current_instruction_table.C_F_S;
+   recomp_func = genc_f_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_UN_S(void)
+{
+   dst->ops = current_instruction_table.C_UN_S;
+   recomp_func = genc_un_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_EQ_S(void)
+{
+   dst->ops = current_instruction_table.C_EQ_S;
+   recomp_func = genc_eq_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_UEQ_S(void)
+{
+   dst->ops = current_instruction_table.C_UEQ_S;
+   recomp_func = genc_ueq_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_OLT_S(void)
+{
+   dst->ops = current_instruction_table.C_OLT_S;
+   recomp_func = genc_olt_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_ULT_S(void)
+{
+   dst->ops = current_instruction_table.C_ULT_S;
+   recomp_func = genc_ult_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_OLE_S(void)
+{
+   dst->ops = current_instruction_table.C_OLE_S;
+   recomp_func = genc_ole_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_ULE_S(void)
+{
+   dst->ops = current_instruction_table.C_ULE_S;
+   recomp_func = genc_ule_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_SF_S(void)
+{
+   dst->ops = current_instruction_table.C_SF_S;
+   recomp_func = genc_sf_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_NGLE_S(void)
+{
+   dst->ops = current_instruction_table.C_NGLE_S;
+   recomp_func = genc_ngle_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_SEQ_S(void)
+{
+   dst->ops = current_instruction_table.C_SEQ_S;
+   recomp_func = genc_seq_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_NGL_S(void)
+{
+   dst->ops = current_instruction_table.C_NGL_S;
+   recomp_func = genc_ngl_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_LT_S(void)
+{
+   dst->ops = current_instruction_table.C_LT_S;
+   recomp_func = genc_lt_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_NGE_S(void)
+{
+   dst->ops = current_instruction_table.C_NGE_S;
+   recomp_func = genc_nge_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_LE_S(void)
+{
+   dst->ops = current_instruction_table.C_LE_S;
+   recomp_func = genc_le_s;
+   recompile_standard_cf_type();
+}
+
+static void RC_NGT_S(void)
+{
+   dst->ops = current_instruction_table.C_NGT_S;
+   recomp_func = genc_ngt_s;
+   recompile_standard_cf_type();
+}
+
+static void (*recomp_s[64])(void) =
+{
+   RADD_S    , RSUB_S    , RMUL_S   , RDIV_S    , RSQRT_S   , RABS_S    , RMOV_S   , RNEG_S    , 
+   RROUND_L_S, RTRUNC_L_S, RCEIL_L_S, RFLOOR_L_S, RROUND_W_S, RTRUNC_W_S, RCEIL_W_S, RFLOOR_W_S, 
+   RSV       , RSV       , RSV      , RSV       , RSV       , RSV       , RSV      , RSV       , 
+   RSV       , RSV       , RSV      , RSV       , RSV       , RSV       , RSV      , RSV       , 
+   RSV       , RCVT_D_S  , RSV      , RSV       , RCVT_W_S  , RCVT_L_S  , RSV      , RSV       , 
+   RSV       , RSV       , RSV      , RSV       , RSV       , RSV       , RSV      , RSV       , 
+   RC_F_S    , RC_UN_S   , RC_EQ_S  , RC_UEQ_S  , RC_OLT_S  , RC_ULT_S  , RC_OLE_S , RC_ULE_S  , 
+   RC_SF_S   , RC_NGLE_S , RC_SEQ_S , RC_NGL_S  , RC_LT_S   , RC_NGE_S  , RC_LE_S  , RC_NGT_S
+};
+
+//-------------------------------------------------------------------------
+//                                     D                                   
+//-------------------------------------------------------------------------
+
+static void RADD_D(void)
+{
+   dst->ops = current_instruction_table.ADD_D;
+   recomp_func = genadd_d;
+   recompile_standard_cf_type();
+}
+
+static void RSUB_D(void)
+{
+   dst->ops = current_instruction_table.SUB_D;
+   recomp_func = gensub_d;
+   recompile_standard_cf_type();
+}
+
+static void RMUL_D(void)
+{
+   dst->ops = current_instruction_table.MUL_D;
+   recomp_func = genmul_d;
+   recompile_standard_cf_type();
+}
+
+static void RDIV_D(void)
+{
+   dst->ops = current_instruction_table.DIV_D;
+   recomp_func = gendiv_d;
+   recompile_standard_cf_type();
+}
+
+static void RSQRT_D(void)
+{
+   dst->ops = current_instruction_table.SQRT_D;
+   recomp_func = gensqrt_d;
+   recompile_standard_cf_type();
+}
+
+static void RABS_D(void)
+{
+   dst->ops = current_instruction_table.ABS_D;
+   recomp_func = genabs_d;
+   recompile_standard_cf_type();
+}
+
+static void RMOV_D(void)
+{
+   dst->ops = current_instruction_table.MOV_D;
+   recomp_func = genmov_d;
+   recompile_standard_cf_type();
+}
+
+static void RNEG_D(void)
+{
+   dst->ops = current_instruction_table.NEG_D;
+   recomp_func = genneg_d;
+   recompile_standard_cf_type();
+}
+
+static void RROUND_L_D(void)
+{
+   dst->ops = current_instruction_table.ROUND_L_D;
+   recomp_func = genround_l_d;
+   recompile_standard_cf_type();
+}
+
+static void RTRUNC_L_D(void)
+{
+   dst->ops = current_instruction_table.TRUNC_L_D;
+   recomp_func = gentrunc_l_d;
+   recompile_standard_cf_type();
+}
+
+static void RCEIL_L_D(void)
+{
+   dst->ops = current_instruction_table.CEIL_L_D;
+   recomp_func = genceil_l_d;
+   recompile_standard_cf_type();
+}
+
+static void RFLOOR_L_D(void)
+{
+   dst->ops = current_instruction_table.FLOOR_L_D;
+   recomp_func = genfloor_l_d;
+   recompile_standard_cf_type();
+}
+
+static void RROUND_W_D(void)
+{
+   dst->ops = current_instruction_table.ROUND_W_D;
+   recomp_func = genround_w_d;
+   recompile_standard_cf_type();
+}
+
+static void RTRUNC_W_D(void)
+{
+   dst->ops = current_instruction_table.TRUNC_W_D;
+   recomp_func = gentrunc_w_d;
+   recompile_standard_cf_type();
+}
+
+static void RCEIL_W_D(void)
+{
+   dst->ops = current_instruction_table.CEIL_W_D;
+   recomp_func = genceil_w_d;
+   recompile_standard_cf_type();
+}
+
+static void RFLOOR_W_D(void)
+{
+   dst->ops = current_instruction_table.FLOOR_W_D;
+   recomp_func = genfloor_w_d;
+   recompile_standard_cf_type();
+}
+
+static void RCVT_S_D(void)
+{
+   dst->ops = current_instruction_table.CVT_S_D;
+   recomp_func = gencvt_s_d;
+   recompile_standard_cf_type();
+}
+
+static void RCVT_W_D(void)
+{
+   dst->ops = current_instruction_table.CVT_W_D;
+   recomp_func = gencvt_w_d;
+   recompile_standard_cf_type();
+}
+
+static void RCVT_L_D(void)
+{
+   dst->ops = current_instruction_table.CVT_L_D;
+   recomp_func = gencvt_l_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_F_D(void)
+{
+   dst->ops = current_instruction_table.C_F_D;
+   recomp_func = genc_f_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_UN_D(void)
+{
+   dst->ops = current_instruction_table.C_UN_D;
+   recomp_func = genc_un_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_EQ_D(void)
+{
+   dst->ops = current_instruction_table.C_EQ_D;
+   recomp_func = genc_eq_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_UEQ_D(void)
+{
+   dst->ops = current_instruction_table.C_UEQ_D;
+   recomp_func = genc_ueq_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_OLT_D(void)
+{
+   dst->ops = current_instruction_table.C_OLT_D;
+   recomp_func = genc_olt_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_ULT_D(void)
+{
+   dst->ops = current_instruction_table.C_ULT_D;
+   recomp_func = genc_ult_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_OLE_D(void)
+{
+   dst->ops = current_instruction_table.C_OLE_D;
+   recomp_func = genc_ole_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_ULE_D(void)
+{
+   dst->ops = current_instruction_table.C_ULE_D;
+   recomp_func = genc_ule_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_SF_D(void)
+{
+   dst->ops = current_instruction_table.C_SF_D;
+   recomp_func = genc_sf_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_NGLE_D(void)
+{
+   dst->ops = current_instruction_table.C_NGLE_D;
+   recomp_func = genc_ngle_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_SEQ_D(void)
+{
+   dst->ops = current_instruction_table.C_SEQ_D;
+   recomp_func = genc_seq_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_NGL_D(void)
+{
+   dst->ops = current_instruction_table.C_NGL_D;
+   recomp_func = genc_ngl_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_LT_D(void)
+{
+   dst->ops = current_instruction_table.C_LT_D;
+   recomp_func = genc_lt_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_NGE_D(void)
+{
+   dst->ops = current_instruction_table.C_NGE_D;
+   recomp_func = genc_nge_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_LE_D(void)
+{
+   dst->ops = current_instruction_table.C_LE_D;
+   recomp_func = genc_le_d;
+   recompile_standard_cf_type();
+}
+
+static void RC_NGT_D(void)
+{
+   dst->ops = current_instruction_table.C_NGT_D;
+   recomp_func = genc_ngt_d;
+   recompile_standard_cf_type();
+}
+
+static void (*recomp_d[64])(void) =
+{
+   RADD_D    , RSUB_D    , RMUL_D   , RDIV_D    , RSQRT_D   , RABS_D    , RMOV_D   , RNEG_D    ,
+   RROUND_L_D, RTRUNC_L_D, RCEIL_L_D, RFLOOR_L_D, RROUND_W_D, RTRUNC_W_D, RCEIL_W_D, RFLOOR_W_D,
+   RSV       , RSV       , RSV      , RSV       , RSV       , RSV       , RSV      , RSV       ,
+   RSV       , RSV       , RSV      , RSV       , RSV       , RSV       , RSV      , RSV       ,
+   RCVT_S_D  , RSV       , RSV      , RSV       , RCVT_W_D  , RCVT_L_D  , RSV      , RSV       ,
+   RSV       , RSV       , RSV      , RSV       , RSV       , RSV       , RSV      , RSV       ,
+   RC_F_D    , RC_UN_D   , RC_EQ_D  , RC_UEQ_D  , RC_OLT_D  , RC_ULT_D  , RC_OLE_D , RC_ULE_D  ,
+   RC_SF_D   , RC_NGLE_D , RC_SEQ_D , RC_NGL_D  , RC_LT_D   , RC_NGE_D  , RC_LE_D  , RC_NGT_D
+};
+
+//-------------------------------------------------------------------------
+//                                     W                                   
+//-------------------------------------------------------------------------
+
+static void RCVT_S_W(void)
+{
+   dst->ops = current_instruction_table.CVT_S_W;
+   recomp_func = gencvt_s_w;
+   recompile_standard_cf_type();
+}
+
+static void RCVT_D_W(void)
+{
+   dst->ops = current_instruction_table.CVT_D_W;
+   recomp_func = gencvt_d_w;
+   recompile_standard_cf_type();
+}
+
+static void (*recomp_w[64])(void) =
+{
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RCVT_S_W, RCVT_D_W, RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV
+};
+
+//-------------------------------------------------------------------------
+//                                     L                                   
+//-------------------------------------------------------------------------
+
+static void RCVT_S_L(void)
+{
+   dst->ops = current_instruction_table.CVT_S_L;
+   recomp_func = gencvt_s_l;
+   recompile_standard_cf_type();
+}
+
+static void RCVT_D_L(void)
+{
+   dst->ops = current_instruction_table.CVT_D_L;
+   recomp_func = gencvt_d_l;
+   recompile_standard_cf_type();
+}
+
+static void (*recomp_l[64])(void) =
+{
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV,
+   RCVT_S_L, RCVT_D_L, RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+   RSV     , RSV     , RSV, RSV, RSV, RSV, RSV, RSV, 
+};
+
+//-------------------------------------------------------------------------
+//                                    COP1                                 
+//-------------------------------------------------------------------------
+
+static void RMFC1(void)
+{
+   dst->ops = current_instruction_table.MFC1;
+   recomp_func = genmfc1;
+   recompile_standard_r_type();
+   dst->f.r.nrd = (src >> 11) & 0x1F;
+   if (dst->f.r.rt == reg) RNOP();
+}
+
+static void RDMFC1(void)
+{
+   dst->ops = current_instruction_table.DMFC1;
+   recomp_func = gendmfc1;
+   recompile_standard_r_type();
+   dst->f.r.nrd = (src >> 11) & 0x1F;
+   if (dst->f.r.rt == reg) RNOP();
+}
+
+static void RCFC1(void)
+{
+   dst->ops = current_instruction_table.CFC1;
+   recomp_func = gencfc1;
+   recompile_standard_r_type();
+   dst->f.r.nrd = (src >> 11) & 0x1F;
+   if (dst->f.r.rt == reg) RNOP();
+}
+
+static void RMTC1(void)
+{
+   dst->ops = current_instruction_table.MTC1;
+   recompile_standard_r_type();
+   recomp_func = genmtc1;
+   dst->f.r.nrd = (src >> 11) & 0x1F;
+}
+
+static void RDMTC1(void)
+{
+   dst->ops = current_instruction_table.DMTC1;
+   recompile_standard_r_type();
+   recomp_func = gendmtc1;
+   dst->f.r.nrd = (src >> 11) & 0x1F;
+}
+
+static void RCTC1(void)
+{
+   dst->ops = current_instruction_table.CTC1;
+   recompile_standard_r_type();
+   recomp_func = genctc1;
+   dst->f.r.nrd = (src >> 11) & 0x1F;
+}
+
+static void RBC(void)
+{
+   recomp_bc[((src >> 16) & 3)]();
+}
+
+static void RS(void)
+{
+   recomp_s[(src & 0x3F)]();
+}
+
+static void RD(void)
+{
+   recomp_d[(src & 0x3F)]();
+}
+
+static void RW(void)
+{
+   recomp_w[(src & 0x3F)]();
+}
+
+static void RL(void)
+{
+   recomp_l[(src & 0x3F)]();
+}
+
+static void (*recomp_cop1[32])(void) =
+{
+   RMFC1, RDMFC1, RCFC1, RSV, RMTC1, RDMTC1, RCTC1, RSV,
+   RBC  , RSV   , RSV  , RSV, RSV  , RSV   , RSV  , RSV,
+   RS   , RD    , RSV  , RSV, RW   , RL    , RSV  , RSV,
+   RSV  , RSV   , RSV  , RSV, RSV  , RSV   , RSV  , RSV
+};
+
+//-------------------------------------------------------------------------
+//                                   R4300                                 
+//-------------------------------------------------------------------------
+
+static void RSPECIAL(void)
+{
+   recomp_special[(src & 0x3F)]();
+}
+
+static void RREGIMM(void)
+{
+   recomp_regimm[((src >> 16) & 0x1F)]();
+}
+
+static void RJ(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.J;
+   recomp_func = genj;
+   recompile_standard_j_type();
+   target = (dst->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.J_IDLE;
+         recomp_func = genj_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.J_OUT;
+      recomp_func = genj_out;
+   }
+}
+
+static void RJAL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.JAL;
+   recomp_func = genjal;
+   recompile_standard_j_type();
+   target = (dst->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.JAL_IDLE;
+         recomp_func = genjal_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.JAL_OUT;
+      recomp_func = genjal_out;
+   }
+}
+
+static void RBEQ(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BEQ;
+   recomp_func = genbeq;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BEQ_IDLE;
+         recomp_func = genbeq_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BEQ_OUT;
+      recomp_func = genbeq_out;
+   }
+}
+
+static void RBNE(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BNE;
+   recomp_func = genbne;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BNE_IDLE;
+         recomp_func = genbne_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BNE_OUT;
+      recomp_func = genbne_out;
+   }
+}
+
+static void RBLEZ(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BLEZ;
+   recomp_func = genblez;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BLEZ_IDLE;
+         recomp_func = genblez_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BLEZ_OUT;
+      recomp_func = genblez_out;
+   }
+}
+
+static void RBGTZ(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BGTZ;
+   recomp_func = genbgtz;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BGTZ_IDLE;
+         recomp_func = genbgtz_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BGTZ_OUT;
+      recomp_func = genbgtz_out;
+   }
+}
+
+static void RADDI(void)
+{
+   dst->ops = current_instruction_table.ADDI;
+   recomp_func = genaddi;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RADDIU(void)
+{
+   dst->ops = current_instruction_table.ADDIU;
+   recomp_func = genaddiu;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RSLTI(void)
+{
+   dst->ops = current_instruction_table.SLTI;
+   recomp_func = genslti;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RSLTIU(void)
+{
+   dst->ops = current_instruction_table.SLTIU;
+   recomp_func = gensltiu;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RANDI(void)
+{
+   dst->ops = current_instruction_table.ANDI;
+   recomp_func = genandi;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RORI(void)
+{
+   dst->ops = current_instruction_table.ORI;
+   recomp_func = genori;
+   recompile_standard_i_type();
+   if (dst->f.i.rt == reg) RNOP();
+}
+
+static void RXORI(void)
+{
+   dst->ops = current_instruction_table.XORI;
+   recomp_func = genxori;
+   recompile_standard_i_type();
+   if (dst->f.i.rt == reg) RNOP();
+}
+
+static void RLUI(void)
+{
+   dst->ops = current_instruction_table.LUI;
+   recomp_func = genlui;
+   recompile_standard_i_type();
+   if (dst->f.i.rt == reg) RNOP();
+}
+
+static void RCOP0(void)
+{
+   recomp_cop0[((src >> 21) & 0x1F)]();
+}
+
+static void RCOP1(void)
+{
+   recomp_cop1[((src >> 21) & 0x1F)]();
+}
+
+static void RBEQL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BEQL;
+   recomp_func = genbeql;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BEQL_IDLE;
+         recomp_func = genbeql_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BEQL_OUT;
+      recomp_func = genbeql_out;
+   }
+}
+
+static void RBNEL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BNEL;
+   recomp_func = genbnel;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BNEL_IDLE;
+         recomp_func = genbnel_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BNEL_OUT;
+      recomp_func = genbnel_out;
+   }
+}
+
+static void RBLEZL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BLEZL;
+   recomp_func = genblezl;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BLEZL_IDLE;
+         recomp_func = genblezl_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BLEZL_OUT;
+      recomp_func = genblezl_out;
+   }
+}
+
+static void RBGTZL(void)
+{
+   unsigned int target;
+   dst->ops = current_instruction_table.BGTZL;
+   recomp_func = genbgtzl;
+   recompile_standard_i_type();
+   target = dst->addr + dst->f.i.immediate*4 + 4;
+   if (target == dst->addr)
+   {
+      if (check_nop)
+      {
+         dst->ops = current_instruction_table.BGTZL_IDLE;
+         recomp_func = genbgtzl_idle;
+      }
+   }
+   else if (r4300emu != CORE_PURE_INTERPRETER && (target < dst_block->start || target >= dst_block->end || dst->addr == (dst_block->end-4)))
+   {
+      dst->ops = current_instruction_table.BGTZL_OUT;
+      recomp_func = genbgtzl_out;
+   }
+}
+
+static void RDADDI(void)
+{
+   dst->ops = current_instruction_table.DADDI;
+   recomp_func = gendaddi;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RDADDIU(void)
+{
+   dst->ops = current_instruction_table.DADDIU;
+   recomp_func = gendaddiu;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RLDL(void)
+{
+   dst->ops = current_instruction_table.LDL;
+   recomp_func = genldl;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RLDR(void)
+{
+   dst->ops = current_instruction_table.LDR;
+   recomp_func = genldr;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RLB(void)
+{
+   dst->ops = current_instruction_table.LB;
+   recomp_func = genlb;
+   recompile_standard_i_type();
+   if (dst->f.i.rt == reg) RNOP();
+}
+
+static void RLH(void)
+{
+   dst->ops = current_instruction_table.LH;
+   recomp_func = genlh;
+   recompile_standard_i_type();
+   if (dst->f.i.rt == reg) RNOP();
+}
+
+static void RLWL(void)
+{
+   dst->ops = current_instruction_table.LWL;
+   recomp_func = genlwl;
+   recompile_standard_i_type();
+   if (dst->f.i.rt == reg) RNOP();
+}
+
+static void RLW(void)
+{
+   dst->ops = current_instruction_table.LW;
+   recomp_func = genlw;
+   recompile_standard_i_type();
+   if (dst->f.i.rt == reg) RNOP();
+}
+
+static void RLBU(void)
+{
+   dst->ops = current_instruction_table.LBU;
+   recomp_func = genlbu;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RLHU(void)
+{
+   dst->ops = current_instruction_table.LHU;
+   recomp_func = genlhu;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RLWR(void)
+{
+   dst->ops = current_instruction_table.LWR;
+   recomp_func = genlwr;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RLWU(void)
+{
+   dst->ops = current_instruction_table.LWU;
+   recomp_func = genlwu;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RSB(void)
+{
+   dst->ops = current_instruction_table.SB;
+   recomp_func = gensb;
+   recompile_standard_i_type();
+}
+
+static void RSH(void)
+{
+   dst->ops = current_instruction_table.SH;
+   recomp_func = gensh;
+   recompile_standard_i_type();
+}
+
+static void RSWL(void)
+{
+   dst->ops = current_instruction_table.SWL;
+   recomp_func = genswl;
+   recompile_standard_i_type();
+}
+
+static void RSW(void)
+{
+   dst->ops = current_instruction_table.SW;
+   recomp_func = gensw;
+   recompile_standard_i_type();
+}
+
+static void RSDL(void)
+{
+   dst->ops = current_instruction_table.SDL;
+   recomp_func = gensdl;
+   recompile_standard_i_type();
+}
+
+static void RSDR(void)
+{
+   dst->ops = current_instruction_table.SDR;
+   recomp_func = gensdr;
+   recompile_standard_i_type();
+}
+
+static void RSWR(void)
+{
+   dst->ops = current_instruction_table.SWR;
+   recomp_func = genswr;
+   recompile_standard_i_type();
+}
+
+static void RCACHE(void)
+{
+   recomp_func = gencache;
+   dst->ops = current_instruction_table.CACHE;
+}
+
+static void RLL(void)
+{
+   recomp_func = genll;
+   dst->ops = current_instruction_table.LL;
+   recompile_standard_i_type();
+   if(dst->f.i.rt == reg) RNOP();
+}
+
+static void RLWC1(void)
+{
+   dst->ops = current_instruction_table.LWC1;
+   recomp_func = genlwc1;
+   recompile_standard_lf_type();
+}
+
+static void RLLD(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+   recompile_standard_i_type();
+}
+
+static void RLDC1(void)
+{
+   dst->ops = current_instruction_table.LDC1;
+   recomp_func = genldc1;
+   recompile_standard_lf_type();
+}
+
+static void RLD(void)
+{
+   dst->ops = current_instruction_table.LD;
+   recomp_func = genld;
+   recompile_standard_i_type();
+   if (dst->f.i.rt == reg) RNOP();
+}
+
+static void RSC(void)
+{
+   dst->ops = current_instruction_table.SC;
+   recomp_func = gensc;
+   recompile_standard_i_type();
+   if (dst->f.i.rt == reg) RNOP();
+}
+
+static void RSWC1(void)
+{
+   dst->ops = current_instruction_table.SWC1;
+   recomp_func = genswc1;
+   recompile_standard_lf_type();
+}
+
+static void RSCD(void)
+{
+   dst->ops = current_instruction_table.NI;
+   recomp_func = genni;
+   recompile_standard_i_type();
+}
+
+static void RSDC1(void)
+{
+   dst->ops = current_instruction_table.SDC1;
+   recomp_func = gensdc1;
+   recompile_standard_lf_type();
+}
+
+static void RSD(void)
+{
+   dst->ops = current_instruction_table.SD;
+   recomp_func = gensd;
+   recompile_standard_i_type();
+}
+
+static void (*recomp_ops[64])(void) =
+{
+   RSPECIAL, RREGIMM, RJ   , RJAL  , RBEQ , RBNE , RBLEZ , RBGTZ ,
+   RADDI   , RADDIU , RSLTI, RSLTIU, RANDI, RORI , RXORI , RLUI  ,
+   RCOP0   , RCOP1  , RSV  , RSV   , RBEQL, RBNEL, RBLEZL, RBGTZL,
+   RDADDI  , RDADDIU, RLDL , RLDR  , RSV  , RSV  , RSV   , RSV   ,
+   RLB     , RLH    , RLWL , RLW   , RLBU , RLHU , RLWR  , RLWU  ,
+   RSB     , RSH    , RSWL , RSW   , RSDL , RSDR , RSWR  , RCACHE,
+   RLL     , RLWC1  , RSV  , RSV   , RLLD , RLDC1, RSV   , RLD   ,
+   RSC     , RSWC1  , RSV  , RSV   , RSCD , RSDC1, RSV   , RSD
+};
+
+static int get_block_length(const precomp_block *block)
+{
+  return (block->end-block->start)/4;
+}
+
+static size_t get_block_memsize(const precomp_block *block)
+{
+  int length = get_block_length(block);
+  return ((length+1)+(length>>2)) * sizeof(precomp_instr);
+}
+
+/**********************************************************************
+ ******************** initialize an empty block ***********************
+ **********************************************************************/
+void init_block(precomp_block *block)
+{
+  int i, length, already_exist = 1;
+  static int init_length;
+  start_section(COMPILER_SECTION);
+#ifdef CORE_DBG
+  DebugMessage(M64MSG_INFO, "init block %x - %x", (int) block->start, (int) block->end);
+#endif
+
+  length = get_block_length(block);
+   
+  if (!block->block)
+  {
+    size_t memsize = get_block_memsize(block);
+    if (r4300emu == CORE_DYNAREC) {
+        block->block = (precomp_instr *) malloc_exec(memsize);
+        if (!block->block) {
+            DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate executable memory for dynamic recompiler. Try to use an interpreter mode.");
+            return;
+        }
+    }
+    else {
+        block->block = (precomp_instr *) malloc(memsize);
+        if (!block->block) {
+            DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate memory for cached interpreter.");
+            return;
+        }
+    }
+
+    memset(block->block, 0, memsize);
+    already_exist = 0;
+  }
+
+  if (r4300emu == CORE_DYNAREC)
+  {
+    if (!block->code)
+    {
+#if defined(PROFILE_R4300)
+      max_code_length = 524288; /* allocate so much code space that we'll never have to realloc(), because this may */
+                                /* cause instruction locations to move, and break our profiling data                */
+#else
+      max_code_length = 32768;
+#endif
+      block->code = (unsigned char *) malloc_exec(max_code_length);
+    }
+    else
+    {
+      max_code_length = block->max_code_length;
+    }
+    code_length = 0;
+    inst_pointer = &block->code;
+    
+    if (block->jumps_table)
+    {
+      free(block->jumps_table);
+      block->jumps_table = NULL;
+    }
+    if (block->riprel_table)
+    {
+      free(block->riprel_table);
+      block->riprel_table = NULL;
+    }
+    init_assembler(NULL, 0, NULL, 0);
+    init_cache(block->block);
+  }
+   
+  if (!already_exist)
+  {
+#if defined(PROFILE_R4300)
+    pfProfile = fopen("instructionaddrs.dat", "ab");
+    long x86addr = (long) block->code;
+    int mipsop = -2; /* -2 == NOTCOMPILED block at beginning of x86 code */
+    if (fwrite(&mipsop, 1, 4, pfProfile) != 4 || // write 4-byte MIPS opcode
+        fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) // write pointer to dynamically generated x86 code for this MIPS instruction
+        DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
+#endif
+
+    for (i=0; i<length; i++)
+    {
+      dst = block->block + i;
+      dst->addr = block->start + i*4;
+      dst->reg_cache_infos.need_map = 0;
+      dst->local_addr = code_length;
+#ifdef COMPARE_CORE
+      if (r4300emu == CORE_DYNAREC) gendebug();
+#endif
+      RNOTCOMPILED();
+      if (r4300emu == CORE_DYNAREC) recomp_func();
+    }
+#if defined(PROFILE_R4300)
+  fclose(pfProfile);
+  pfProfile = NULL;
+#endif
+  init_length = code_length;
+  }
+  else
+  {
+#if defined(PROFILE_R4300)
+    code_length = block->code_length; /* leave old instructions in their place */
+#else
+    code_length = init_length; /* recompile everything, overwrite old recompiled instructions */
+#endif
+    for (i=0; i<length; i++)
+    {
+      dst = block->block + i;
+      dst->reg_cache_infos.need_map = 0;
+      dst->local_addr = i * (init_length / length);
+      dst->ops = current_instruction_table.NOTCOMPILED;
+    }
+  }
+   
+  if (r4300emu == CORE_DYNAREC)
+  {
+    free_all_registers();
+    /* calling pass2 of the assembler is not necessary here because all of the code emitted by
+       gennotcompiled() and gendebug() is position-independent and contains no jumps . */
+    block->code_length = code_length;
+    block->max_code_length = max_code_length;
+    free_assembler(&block->jumps_table, &block->jumps_number, &block->riprel_table, &block->riprel_number);
+  }
+   
+  /* here we're marking the block as a valid code even if it's not compiled
+   * yet as the game should have already set up the code correctly.
+   */
+  invalid_code[block->start>>12] = 0;
+  if (block->end < 0x80000000 || block->start >= 0xc0000000)
+  { 
+    unsigned int paddr;
+    
+    paddr = virtual_to_physical_address(block->start, 2);
+    invalid_code[paddr>>12] = 0;
+    if (!blocks[paddr>>12])
+    {
+      blocks[paddr>>12] = (precomp_block *) malloc(sizeof(precomp_block));
+      blocks[paddr>>12]->code = NULL;
+      blocks[paddr>>12]->block = NULL;
+      blocks[paddr>>12]->jumps_table = NULL;
+      blocks[paddr>>12]->riprel_table = NULL;
+      blocks[paddr>>12]->start = paddr & ~0xFFF;
+      blocks[paddr>>12]->end = (paddr & ~0xFFF) + 0x1000;
+    }
+    init_block(blocks[paddr>>12]);
+    
+    paddr += block->end - block->start - 4;
+    invalid_code[paddr>>12] = 0;
+    if (!blocks[paddr>>12])
+    {
+      blocks[paddr>>12] = (precomp_block *) malloc(sizeof(precomp_block));
+      blocks[paddr>>12]->code = NULL;
+      blocks[paddr>>12]->block = NULL;
+      blocks[paddr>>12]->jumps_table = NULL;
+      blocks[paddr>>12]->riprel_table = NULL;
+      blocks[paddr>>12]->start = paddr & ~0xFFF;
+      blocks[paddr>>12]->end = (paddr & ~0xFFF) + 0x1000;
+    }
+    init_block(blocks[paddr>>12]);
+  }
+  else
+  {
+    if (block->start >= 0x80000000 && block->end < 0xa0000000 && invalid_code[(block->start+0x20000000)>>12])
+    {
+      if (!blocks[(block->start+0x20000000)>>12])
+      {
+        blocks[(block->start+0x20000000)>>12] = (precomp_block *) malloc(sizeof(precomp_block));
+        blocks[(block->start+0x20000000)>>12]->code = NULL;
+        blocks[(block->start+0x20000000)>>12]->block = NULL;
+        blocks[(block->start+0x20000000)>>12]->jumps_table = NULL;
+        blocks[(block->start+0x20000000)>>12]->riprel_table = NULL;
+        blocks[(block->start+0x20000000)>>12]->start = (block->start+0x20000000) & ~0xFFF;
+        blocks[(block->start+0x20000000)>>12]->end = ((block->start+0x20000000) & ~0xFFF) + 0x1000;
+      }
+      init_block(blocks[(block->start+0x20000000)>>12]);
+    }
+    if (block->start >= 0xa0000000 && block->end < 0xc0000000 && invalid_code[(block->start-0x20000000)>>12])
+    {
+      if (!blocks[(block->start-0x20000000)>>12])
+      {
+        blocks[(block->start-0x20000000)>>12] = (precomp_block *) malloc(sizeof(precomp_block));
+        blocks[(block->start-0x20000000)>>12]->code = NULL;
+        blocks[(block->start-0x20000000)>>12]->block = NULL;
+        blocks[(block->start-0x20000000)>>12]->jumps_table = NULL;
+        blocks[(block->start-0x20000000)>>12]->riprel_table = NULL;
+        blocks[(block->start-0x20000000)>>12]->start = (block->start-0x20000000) & ~0xFFF;
+        blocks[(block->start-0x20000000)>>12]->end = ((block->start-0x20000000) & ~0xFFF) + 0x1000;
+      }
+      init_block(blocks[(block->start-0x20000000)>>12]);
+    }
+  }
+  end_section(COMPILER_SECTION);
+}
+
+void free_block(precomp_block *block)
+{
+    size_t memsize = get_block_memsize(block);
+
+    if (block->block) {
+        if (r4300emu == CORE_DYNAREC)
+            free_exec(block->block, memsize);
+        else
+            free(block->block);
+        block->block = NULL;
+    }
+    if (block->code) { free_exec(block->code, block->max_code_length); block->code = NULL; }
+    if (block->jumps_table) { free(block->jumps_table); block->jumps_table = NULL; }
+    if (block->riprel_table) { free(block->riprel_table); block->riprel_table = NULL; }
+}
+
+/**********************************************************************
+ ********************* recompile a block of code **********************
+ **********************************************************************/
+void recompile_block(int *source, precomp_block *block, unsigned int func)
+{
+   int i, length, finished=0;
+   start_section(COMPILER_SECTION);
+   length = (block->end-block->start)/4;
+   dst_block = block;
+   
+   //for (i=0; i<16; i++) block->md5[i] = 0;
+   block->adler32 = 0;
+   
+   if (r4300emu == CORE_DYNAREC)
+     {
+    code_length = block->code_length;
+    max_code_length = block->max_code_length;
+    inst_pointer = &block->code;
+    init_assembler(block->jumps_table, block->jumps_number, block->riprel_table, block->riprel_number);
+    init_cache(block->block + (func & 0xFFF) / 4);
+     }
+
+#if defined(PROFILE_R4300)
+   pfProfile = fopen("instructionaddrs.dat", "ab");
+#endif
+
+   for (i = (func & 0xFFF) / 4; finished != 2; i++)
+     {
+    if(block->start < 0x80000000 || block->start >= 0xc0000000)
+      {
+          unsigned int address2 =
+           virtual_to_physical_address(block->start + i*4, 0);
+         if(blocks[address2>>12]->block[(address2&0xFFF)/4].ops == current_instruction_table.NOTCOMPILED)
+           blocks[address2>>12]->block[(address2&0xFFF)/4].ops = current_instruction_table.NOTCOMPILED2;
+      }
+    
+    SRC = source + i;
+    src = source[i];
+    check_nop = source[i+1] == 0;
+    dst = block->block + i;
+    dst->addr = block->start + i*4;
+    dst->reg_cache_infos.need_map = 0;
+    dst->local_addr = code_length;
+#ifdef COMPARE_CORE
+    if (r4300emu == CORE_DYNAREC) gendebug();
+#endif
+#if defined(PROFILE_R4300)
+    long x86addr = (long) (block->code + block->block[i].local_addr);
+    if (fwrite(source + i, 1, 4, pfProfile) != 4 || // write 4-byte MIPS opcode
+        fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) // write pointer to dynamically generated x86 code for this MIPS instruction
+        DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
+#endif
+    recomp_func = NULL;
+    recomp_ops[((src >> 26) & 0x3F)]();
+    if (r4300emu == CORE_DYNAREC) recomp_func();
+    dst = block->block + i;
+
+    /*if ((dst+1)->ops != NOTCOMPILED && !delay_slot_compiled &&
+        i < length)
+      {
+         if (r4300emu == CORE_DYNAREC) genlink_subblock();
+         finished = 2;
+      }*/
+    if (delay_slot_compiled) 
+      {
+         delay_slot_compiled--;
+         free_all_registers();
+      }
+    
+    if (i >= length-2+(length>>2)) finished = 2;
+    if (i >= (length-1) && (block->start == 0xa4000000 ||
+                block->start >= 0xc0000000 ||
+                block->end   <  0x80000000)) finished = 2;
+    if (dst->ops == current_instruction_table.ERET || finished == 1) finished = 2;
+    if (/*i >= length &&*/ 
+        (dst->ops == current_instruction_table.J ||
+         dst->ops == current_instruction_table.J_OUT ||
+         dst->ops == current_instruction_table.JR) &&
+        !(i >= (length-1) && (block->start >= 0xc0000000 ||
+                  block->end   <  0x80000000)))
+      finished = 1;
+     }
+
+#if defined(PROFILE_R4300)
+    long x86addr = (long) (block->code + code_length);
+    int mipsop = -3; /* -3 == block-postfix */
+    if (fwrite(&mipsop, 1, 4, pfProfile) != 4 || // write 4-byte MIPS opcode
+        fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) // write pointer to dynamically generated x86 code for this MIPS instruction
+        DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
+#endif
+
+   if (i >= length)
+     {
+    dst = block->block + i;
+    dst->addr = block->start + i*4;
+    dst->reg_cache_infos.need_map = 0;
+    dst->local_addr = code_length;
+#ifdef COMPARE_CORE
+    if (r4300emu == CORE_DYNAREC) gendebug();
+#endif
+    RFIN_BLOCK();
+    if (r4300emu == CORE_DYNAREC) recomp_func();
+    i++;
+    if (i < length-1+(length>>2)) // useful when last opcode is a jump
+      {
+         dst = block->block + i;
+         dst->addr = block->start + i*4;
+         dst->reg_cache_infos.need_map = 0;
+         dst->local_addr = code_length;
+#ifdef COMPARE_CORE
+         if (r4300emu == CORE_DYNAREC) gendebug();
+#endif
+         RFIN_BLOCK();
+         if (r4300emu == CORE_DYNAREC) recomp_func();
+         i++;
+      }
+     }
+   else if (r4300emu == CORE_DYNAREC) genlink_subblock();
+
+   if (r4300emu == CORE_DYNAREC)
+     {
+    free_all_registers();
+    passe2(block->block, (func&0xFFF)/4, i, block);
+    block->code_length = code_length;
+    block->max_code_length = max_code_length;
+    free_assembler(&block->jumps_table, &block->jumps_number, &block->riprel_table, &block->riprel_number);
+     }
+#ifdef CORE_DBG
+   DebugMessage(M64MSG_INFO, "block recompiled (%x-%x)", (int)func, (int)(block->start+i*4));
+#endif
+#if defined(PROFILE_R4300)
+   fclose(pfProfile);
+   pfProfile = NULL;
+#endif
+   end_section(COMPILER_SECTION);
+}
+
+static int is_jump(void)
+{
+   recomp_ops[((src >> 26) & 0x3F)]();
+   return
+      (dst->ops == current_instruction_table.J ||
+       dst->ops == current_instruction_table.J_OUT ||
+       dst->ops == current_instruction_table.J_IDLE ||
+       dst->ops == current_instruction_table.JAL ||
+       dst->ops == current_instruction_table.JAL_OUT ||
+       dst->ops == current_instruction_table.JAL_IDLE ||
+       dst->ops == current_instruction_table.BEQ ||
+       dst->ops == current_instruction_table.BEQ_OUT ||
+       dst->ops == current_instruction_table.BEQ_IDLE ||
+       dst->ops == current_instruction_table.BNE ||
+       dst->ops == current_instruction_table.BNE_OUT ||
+       dst->ops == current_instruction_table.BNE_IDLE ||
+       dst->ops == current_instruction_table.BLEZ ||
+       dst->ops == current_instruction_table.BLEZ_OUT ||
+       dst->ops == current_instruction_table.BLEZ_IDLE ||
+       dst->ops == current_instruction_table.BGTZ ||
+       dst->ops == current_instruction_table.BGTZ_OUT ||
+       dst->ops == current_instruction_table.BGTZ_IDLE ||
+       dst->ops == current_instruction_table.BEQL ||
+       dst->ops == current_instruction_table.BEQL_OUT ||
+       dst->ops == current_instruction_table.BEQL_IDLE ||
+       dst->ops == current_instruction_table.BNEL ||
+       dst->ops == current_instruction_table.BNEL_OUT ||
+       dst->ops == current_instruction_table.BNEL_IDLE ||
+       dst->ops == current_instruction_table.BLEZL ||
+       dst->ops == current_instruction_table.BLEZL_OUT ||
+       dst->ops == current_instruction_table.BLEZL_IDLE ||
+       dst->ops == current_instruction_table.BGTZL ||
+       dst->ops == current_instruction_table.BGTZL_OUT ||
+       dst->ops == current_instruction_table.BGTZL_IDLE ||
+       dst->ops == current_instruction_table.JR ||
+       dst->ops == current_instruction_table.JALR ||
+       dst->ops == current_instruction_table.BLTZ ||
+       dst->ops == current_instruction_table.BLTZ_OUT ||
+       dst->ops == current_instruction_table.BLTZ_IDLE ||
+       dst->ops == current_instruction_table.BGEZ ||
+       dst->ops == current_instruction_table.BGEZ_OUT ||
+       dst->ops == current_instruction_table.BGEZ_IDLE ||
+       dst->ops == current_instruction_table.BLTZL ||
+       dst->ops == current_instruction_table.BLTZL_OUT ||
+       dst->ops == current_instruction_table.BLTZL_IDLE ||
+       dst->ops == current_instruction_table.BGEZL ||
+       dst->ops == current_instruction_table.BGEZL_OUT ||
+       dst->ops == current_instruction_table.BGEZL_IDLE ||
+       dst->ops == current_instruction_table.BLTZAL ||
+       dst->ops == current_instruction_table.BLTZAL_OUT ||
+       dst->ops == current_instruction_table.BLTZAL_IDLE ||
+       dst->ops == current_instruction_table.BGEZAL ||
+       dst->ops == current_instruction_table.BGEZAL_OUT ||
+       dst->ops == current_instruction_table.BGEZAL_IDLE ||
+       dst->ops == current_instruction_table.BLTZALL ||
+       dst->ops == current_instruction_table.BLTZALL_OUT ||
+       dst->ops == current_instruction_table.BLTZALL_IDLE ||
+       dst->ops == current_instruction_table.BGEZALL ||
+       dst->ops == current_instruction_table.BGEZALL_OUT ||
+       dst->ops == current_instruction_table.BGEZALL_IDLE ||
+       dst->ops == current_instruction_table.BC1F ||
+       dst->ops == current_instruction_table.BC1F_OUT ||
+       dst->ops == current_instruction_table.BC1F_IDLE ||
+       dst->ops == current_instruction_table.BC1T ||
+       dst->ops == current_instruction_table.BC1T_OUT ||
+       dst->ops == current_instruction_table.BC1T_IDLE ||
+       dst->ops == current_instruction_table.BC1FL ||
+       dst->ops == current_instruction_table.BC1FL_OUT ||
+       dst->ops == current_instruction_table.BC1FL_IDLE ||
+       dst->ops == current_instruction_table.BC1TL ||
+       dst->ops == current_instruction_table.BC1TL_OUT ||
+       dst->ops == current_instruction_table.BC1TL_IDLE);
+}
+
+/**********************************************************************
+ ************ recompile only one opcode (use for delay slot) **********
+ **********************************************************************/
+void recompile_opcode(void)
+{
+   SRC++;
+   src = *SRC;
+   dst++;
+   dst->addr = (dst-1)->addr + 4;
+   dst->reg_cache_infos.need_map = 0;
+   if(!is_jump())
+   {
+#if defined(PROFILE_R4300)
+     long x86addr = (long) ((*inst_pointer) + code_length);
+     if (fwrite(&src, 1, 4, pfProfile) != 4 || // write 4-byte MIPS opcode
+         fwrite(&x86addr, 1, sizeof(char *), pfProfile) != sizeof(char *)) // write pointer to dynamically generated x86 code for this MIPS instruction
+        DebugMessage(M64MSG_ERROR, "Error writing R4300 instruction address profiling data");
+#endif
+     recomp_func = NULL;
+     recomp_ops[((src >> 26) & 0x3F)]();
+     if (r4300emu == CORE_DYNAREC) recomp_func();
+   }
+   else
+   {
+     RNOP();
+     if (r4300emu == CORE_DYNAREC) recomp_func();
+   }
+   delay_slot_compiled = 2;
+}
+
+/**********************************************************************
+ ************** decode one opcode (for the interpreter) ***************
+ **********************************************************************/
+void prefetch_opcode(unsigned int op, unsigned int nextop)
+{
+   dst = PC;
+   src = op;
+   check_nop = nextop == 0;
+   recomp_ops[((src >> 26) & 0x3F)]();
+}
+
+/**********************************************************************
+ ************** allocate memory with executable bit set ***************
+ **********************************************************************/
+static void *malloc_exec(size_t size)
+{
+#if defined(WIN32)
+   return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+#elif defined(__GNUC__)
+
+   #ifndef  MAP_ANONYMOUS
+      #ifdef MAP_ANON
+         #define MAP_ANONYMOUS MAP_ANON
+      #endif
+   #endif
+
+   void *block = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+   if (block == MAP_FAILED)
+       { DebugMessage(M64MSG_ERROR, "Memory error: couldn't allocate %zi byte block of aligned RWX memory.", size); return NULL; }
+
+   return block;
+#else
+   return malloc(size);
+#endif
+}
+
+/**********************************************************************
+ ************* reallocate memory with executable bit set **************
+ **********************************************************************/
+void *realloc_exec(void *ptr, size_t oldsize, size_t newsize)
+{
+   void* block = malloc_exec(newsize);
+   if (block != NULL)
+   {
+      size_t copysize;
+      if (oldsize < newsize)
+         copysize = oldsize;
+      else
+         copysize = newsize;
+      memcpy(block, ptr, copysize);
+   }
+   free_exec(ptr, oldsize);
+   return block;
+}
+
+/**********************************************************************
+ **************** frees memory with executable bit set ****************
+ **********************************************************************/
+static void free_exec(void *ptr, size_t length)
+{
+#if defined(WIN32)
+   VirtualFree(ptr, 0, MEM_RELEASE);
+#elif defined(__GNUC__)
+   munmap(ptr, length);
+#else
+   free(ptr);
+#endif
+}