enum { OP_DADDI=030, OP_DADDIU, OP_LDL, OP_LDR, OP__FN2=034, OP__FN3=037 };
 enum { OP_LB=040, OP_LH, OP_LWL, OP_LW, OP_LBU, OP_LHU, OP_LWR, OP_LWU };
 enum { OP_SB=050, OP_SH, OP_SWL, OP_SW, OP_SDL, OP_SDR, OP_SWR };
-enum { OP_SD=067, OP_LD=077 };
+enum { OP_LD=067, OP_SD=077 };
 // function field (encoded in fn if opcode = OP__FN)
 enum { FN_SLL=000, __(01), FN_SRL, FN_SRA, FN_SLLV, __(05), FN_SRLV, FN_SRAV };
 enum { FN_JR=010, FN_JALR, FN_MOVZ, FN_MOVN, FN_SYNC=017 };
 #define emith_eor_r_r_lsr(d, s, lsrimm) \
        emith_eor_r_r_r_lsr(d, d, s, lsrimm)
 
+#define emith_add_r_r_r_ptr(d, s1, s2) \
+       emith_add_r_r_r_lsl_ptr(d, s1, s2, 0)
 #define emith_add_r_r_r(d, s1, s2) \
        emith_add_r_r_r_lsl(d, s1, s2, 0)
 
        emith_move_imm(r, (uintptr_t)(imm))
 
 #define emith_move_r_imm(r, imm) \
-       emith_move_imm(r, (u32)(imm))
+       emith_move_imm(r, (s32)(imm))
 #define emith_move_r_imm_c(cond, r, imm) \
        emith_move_r_imm(r, imm)
 
        emith_read_r_r_offs(r, rs, offs)
  
 #define emith_read_r_r_r_ptr(r, rs, rm) do { \
-       emith_add_r_r_r(AT, rs, rm); \
+       emith_add_r_r_r_ptr(AT, rs, rm); \
        EMIT(MIPS_OP_IMM(OP_LP, r, AT, 0)); \
 } while (0)
 
 #define emith_read_r_r_r(r, rs, rm) do { \
-       emith_add_r_r_r(AT, rs, rm); \
+       emith_add_r_r_r_ptr(AT, rs, rm); \
        EMIT(MIPS_LW(r, AT, 0)); \
 } while (0)
 #define emith_read_r_r_r_c(cond, r, rs, rm) \
        emith_read8_r_r_offs(r, rs, offs)
 
 #define emith_read8_r_r_r(r, rs, rm) do { \
-       emith_add_r_r_r(AT, rs, rm); \
+       emith_add_r_r_r_ptr(AT, rs, rm); \
        EMIT(MIPS_LBU(r, AT, 0)); \
 } while (0)
 #define emith_read8_r_r_r_c(cond, r, rs, rm) \
        emith_read16_r_r_offs(r, rs, offs)
 
 #define emith_read16_r_r_r(r, rs, rm) do { \
-       emith_add_r_r_r(AT, rs, rm); \
+       emith_add_r_r_r_ptr(AT, rs, rm); \
        EMIT(MIPS_LHU(r, AT, 0)); \
 } while (0)
 #define emith_read16_r_r_r_c(cond, r, rs, rm) \
        emith_read8s_r_r_offs(r, rs, offs)
 
 #define emith_read8s_r_r_r(r, rs, rm) do { \
-       emith_add_r_r_r(AT, rs, rm); \
+       emith_add_r_r_r_ptr(AT, rs, rm); \
        EMIT(MIPS_LB(r, AT, 0)); \
 } while (0)
 #define emith_read8s_r_r_r_c(cond, r, rs, rm) \
        emith_read16s_r_r_offs(r, rs, offs)
 
 #define emith_read16s_r_r_r(r, rs, rm) do { \
-       emith_add_r_r_r(AT, rs, rm); \
+       emith_add_r_r_r_ptr(AT, rs, rm); \
        EMIT(MIPS_LH(r, AT, 0)); \
 } while (0)
 #define emith_read16s_r_r_r_c(cond, r, rs, rm) \
        emith_write_r_r_offs_ptr(r, rs, offs)
 
 #define emith_write_r_r_r_ptr(r, rs, rm) do { \
-       emith_add_r_r_r(AT, rs, rm); \
+       emith_add_r_r_r_ptr(AT, rs, rm); \
        EMIT(MIPS_OP_IMM(OP_SP, r, AT, 0)); \
 } while (0)
 #define emith_write_r_r_r_ptr_c(cond, r, rs, rm) \
        emith_write_r_r_offs(r, rs, offs)
 
 #define emith_write_r_r_r(r, rs, rm) do { \
-       emith_add_r_r_r(AT, rs, rm); \
+       emith_add_r_r_r_ptr(AT, rs, rm); \
        EMIT(MIPS_SW(r, AT, 0)); \
 } while (0)
 #define emith_write_r_r_r_c(cond, r, rs, rm) \
 #define emith_sh2_wcall(a, val, tab, func) do { \
        emith_lsr(func, a, SH2_WRITE_SHIFT); \
        emith_lsl(func, func, PTR_SCALE); \
-       emith_read_r_r_r_ptr(func, tab, func); \
+       emith_read_r_r_r_ptr(CR, tab, func); \
        emith_move_r_r_ptr(6, CONTEXT_REG); /* arg2 */ \
-       emith_abijump_reg(func); \
+       emith_abijump_reg(CR); \
 } while (0)
 
 #define emith_sh2_delay_loop(cycles, reg) do {                 \
 
 #define LOOP_DETECTION          1
 #define LOOP_OPTIMIZER          1
 #define T_OPTIMIZER             1
-#define DIV_OPTIMIZER           0
+#define DIV_OPTIMIZER           1
 
 #define MAX_LITERAL_OFFSET      0x200  // max. MOVA, MOV @(PC) offset
 #define MAX_LOCAL_TARGETS       (BLOCK_INSN_LIMIT / 4)
 {
 #if CPU_IS_LE
   if (cond == -1)
-               emith_ror(r, r, 16);
+    emith_ror(r, r, 16);
   else
-               emith_ror_c(cond, r, r, 16);
+    emith_ror_c(cond, r, r, 16);
 #endif
 }
 
 {
 #if CPU_IS_LE
   if (cond == -1)
-                emith_eor_r_imm_ptr(r, 1);
+    emith_eor_r_imm_ptr(r, 1);
   else
-                emith_eor_r_imm_ptr_c(cond, r, 1);
+    emith_eor_r_imm_ptr_c(cond, r, 1);
 #endif
 }
 
         else
           u = (s16)FETCH_OP(opd->imm);
         // tweak for Blackthorne: avoid stack overwriting
-        if (GET_Rn() == SHR_SP && u == 0x0603f800) u = 0x0603f880;
+        if (GET_Rn() == SHR_SP && u == 0x0603f800) u = 0x0603f900;
         gconst_new(GET_Rn(), u);
       }
       else
             // divide 64/32
             tmp4 = rcache_get_reg(div(opd).ro, RC_GR_READ, NULL);
             emith_ctx_write(tmp4, offsetof(SH2, drc_tmp));
+            rcache_free(tmp4);
             tmp = rcache_get_tmp_arg(1);
             emith_add_r_r_ptr_imm(tmp, CONTEXT_REG, offsetof(SH2, drc_tmp));
             rcache_get_reg_arg(0, div(opd).rn, NULL);
           // divide 64/32
           tmp4 = rcache_get_reg(div(opd).ro, RC_GR_READ, NULL);
           emith_ctx_write(tmp4, offsetof(SH2, drc_tmp));
+          rcache_free(tmp4);
           tmp  = rcache_get_reg_arg(0, div(opd).rn, NULL);
           tmp2 = rcache_get_reg_arg(2, div(opd).rm, NULL);
           tmp3 = rcache_get_tmp_arg(1);