32x: drc: first implementation finished, no more interpreter dep
authornotaz <notasas@gmail.com>
Thu, 12 Nov 2009 16:42:42 +0000 (16:42 +0000)
committernotaz <notasas@gmail.com>
Thu, 12 Nov 2009 16:42:42 +0000 (16:42 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@832 be3aeb3a-fb24-0410-a615-afba39da0efa

cpu/drc/emit_arm.c
cpu/drc/emit_x86.c
cpu/sh2/compiler.c
cpu/sh2/mame/sh2.c
cpu/sh2/mame/sh2pico.c
cpu/sh2/sh2.c
cpu/sh2/sh2.h
platform/common/common.mak [new file with mode: 0644]
platform/common/common_arm.mak
platform/gp2x/Makefile
platform/linux/Makefile

index db6f86a..135274a 100644 (file)
 
 #define EOP_BX(rm) EOP_C_BX(A_COND_AL,rm)
 
+#define EOP_C_B_PTR(ptr,cond,l,signed_immed_24) \
+       EMIT_PTR(ptr, ((cond)<<28) | 0x0a000000 | ((l)<<24) | (signed_immed_24))
+
 #define EOP_C_B(cond,l,signed_immed_24) \
-       EMIT(((cond)<<28) | 0x0a000000 | ((l)<<24) | (signed_immed_24))
+       EOP_C_B_PTR(tcache_ptr,cond,l,signed_immed_24)
 
 #define EOP_B( signed_immed_24) EOP_C_B(A_COND_AL,0,signed_immed_24)
 #define EOP_BL(signed_immed_24) EOP_C_B(A_COND_AL,1,signed_immed_24)
 #define EOP_C_SMULL(cond,s,rdhi,rdlo,rs,rm) \
        EMIT(((cond)<<28) | 0x00c00000 | ((s)<<20) | ((rdhi)<<16) | ((rdlo)<<12) | ((rs)<<8) | 0x90 | (rm))
 
+#define EOP_C_SMLAL(cond,s,rdhi,rdlo,rs,rm) \
+       EMIT(((cond)<<28) | 0x00e00000 | ((s)<<20) | ((rdhi)<<16) | ((rdlo)<<12) | ((rs)<<8) | 0x90 | (rm))
+
 #define EOP_MUL(rd,rm,rs) EOP_C_MUL(A_COND_AL,0,rd,rs,rm) // note: rd != rm
 
 #define EOP_C_MRS(cond,rd) \
@@ -308,6 +314,15 @@ static int emith_xbranch(int cond, void *target, int is_call)
 #define emith_eor_r_r_r_lsl(d, s1, s2, lslimm) \
        EOP_EOR_REG(A_COND_AL,0,d,s1,s2,A_AM1_LSL,lslimm)
 
+#define emith_eor_r_r_r_lsr(d, s1, s2, lsrimm) \
+       EOP_EOR_REG(A_COND_AL,0,d,s1,s2,A_AM1_LSR,lsrimm)
+
+#define emith_or_r_r_lsl(d, s, lslimm) \
+       emith_or_r_r_r_lsl(d, d, s, lslimm)
+
+#define emith_eor_r_r_lsr(d, s, lsrimm) \
+       emith_eor_r_r_r_lsr(d, d, s, lsrimm)
+
 #define emith_or_r_r_r(d, s1, s2) \
        emith_or_r_r_r_lsl(d, s1, s2, 0)
 
@@ -390,6 +405,9 @@ static int emith_xbranch(int cond, void *target, int is_call)
 #define emith_or_r_imm_c(cond, r, imm) \
        emith_op_imm(cond, 0, A_OP_ORR, r, imm)
 
+#define emith_eor_r_imm_c(cond, r, imm) \
+       emith_op_imm(cond, 0, A_OP_EOR, r, imm)
+
 #define emith_bic_r_imm_c(cond, r, imm) \
        emith_op_imm(cond, 0, A_OP_BIC, r, imm)
 
@@ -459,6 +477,9 @@ static int emith_xbranch(int cond, void *target, int is_call)
 #define emith_mul_s64(dlo, dhi, s1, s2) \
        EOP_C_SMULL(A_COND_AL,0,dhi,dlo,s1,s2)
 
+#define emith_mula_s64(dlo, dhi, s1, s2) \
+       EOP_C_SMLAL(A_COND_AL,0,dhi,dlo,s1,s2)
+
 // misc
 #define emith_ctx_read(r, offs) \
        EOP_LDR_IMM(r, CONTEXT_REG, offs)
@@ -466,27 +487,42 @@ static int emith_xbranch(int cond, void *target, int is_call)
 #define emith_ctx_write(r, offs) \
        EOP_STR_IMM(r, CONTEXT_REG, offs)
 
-#define emith_clear_msb(d, s, count) { \
+#define emith_clear_msb_c(cond, d, s, count) { \
        u32 t; \
        if ((count) <= 8) { \
                t = (count) - 8; \
                t = (0xff << t) & 0xff; \
                EOP_BIC_IMM(d,s,8/2,t); \
+               EOP_C_DOP_IMM(cond,A_OP_BIC,0,s,d,8/2,t); \
        } else if ((count) >= 24) { \
                t = (count) - 24; \
                t = 0xff >> t; \
                EOP_AND_IMM(d,s,0,t); \
+               EOP_C_DOP_IMM(cond,A_OP_AND,0,s,d,0,t); \
        } else { \
-               EOP_MOV_REG_LSL(d,s,count); \
-               EOP_MOV_REG_LSR(d,d,count); \
+               EOP_MOV_REG(cond,0,d,s,A_AM1_LSL,count); \
+               EOP_MOV_REG(cond,0,d,d,A_AM1_LSR,count); \
        } \
 }
 
+#define emith_clear_msb(d, s, count) \
+       emith_clear_msb_c(A_COND_AL, d, s, count)
+
 #define emith_sext(d, s, bits) { \
        EOP_MOV_REG_LSL(d,s,32 - (bits)); \
        EOP_MOV_REG_ASR(d,d,32 - (bits)); \
 }
 
+#define JMP_POS(ptr) \
+       ptr = tcache_ptr; \
+       tcache_ptr += sizeof(u32)
+
+#define JMP_EMIT(cond, ptr) { \
+       int val = (u32 *)tcache_ptr - (u32 *)(ptr) - 2; \
+       EOP_C_B_PTR(ptr, cond, 0, val & 0xffffff); \
+}
+
+// _r_r
 // put bit0 of r0 to carry
 #define emith_set_carry(r0) \
        EOP_TST_REG(A_COND_AL,r0,r0,A_AM1_LSR,1) /* shift out to carry */ \
@@ -564,3 +600,24 @@ static int emith_xbranch(int cond, void *target, int is_call)
                emith_bic_r_imm_c(A_COND_CC, srr, 1); \
        } \
 }
+
+/*
+ * if Q
+ *   t = carry(Rn += Rm)
+ * else
+ *   t = carry(Rn -= Rm)
+ * T ^= t
+ */
+#define emith_sh2_div1_step(rn, rm, sr) {         \
+       void *jmp0, *jmp1;                        \
+       emith_tst_r_imm(sr, Q);  /* if (Q ^ M) */ \
+       JMP_POS(jmp0);           /* beq do_sub */ \
+       emith_addf_r_r(rn, rm);                   \
+       emith_eor_r_imm_c(A_COND_CS, sr, T);      \
+       JMP_POS(jmp1);           /* b done */     \
+       JMP_EMIT(A_COND_EQ, jmp0); /* do_sub: */  \
+       emith_subf_r_r(rn, rm);                   \
+       emith_eor_r_imm_c(A_COND_CC, sr, T);      \
+       JMP_EMIT(A_COND_AL, jmp1); /* done: */    \
+}
+
index 0ca6120..6ef8ede 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * note about silly things like emith_or_r_r_r_lsl:
+ * note about silly things like emith_eor_r_r_r:
  * these are here because the compiler was designed
  * for ARM as it's primary target.
  */
@@ -9,6 +9,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 
 #define CONTEXT_REG xBP
 
+#define IOP_JMP 0xeb
 #define IOP_JO  0x70
 #define IOP_JNO 0x71
 #define IOP_JB  0x72
@@ -56,6 +57,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 #define EMIT_MODRM(mod,r,rm) \
        EMIT(((mod)<<6) | ((r)<<3) | (rm), u8)
 
+#define EMIT_SIB(scale,index,base) \
+       EMIT(((scale)<<6) | ((index)<<3) | (base), u8)
+
 #define EMIT_OP_MODRM(op,mod,r,rm) { \
        EMIT_OP(op); \
        EMIT_MODRM(mod, r, rm); \
@@ -139,14 +143,22 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
        } \
 }
 
-#define emith_or_r_r_r_lsl(d, s1, s2, lslimm) { \
+// _r_r_shift
+#define emith_or_r_r_lsl(d, s, lslimm) { \
        int tmp_ = rcache_get_tmp(); \
-       emith_lsl(tmp_, s2, lslimm); \
-       emith_or_r_r(tmp_, s1); \
-       emith_move_r_r(d, tmp_); \
+       emith_lsl(tmp_, s, lslimm); \
+       emith_or_r_r(d, tmp_); \
        rcache_free_tmp(tmp_); \
 }
 
+// d != s
+#define emith_eor_r_r_lsr(d, s, lsrimm) { \
+       emith_push(s); \
+       emith_lsr(s, s, lsrimm); \
+       emith_eor_r_r(d, s); \
+       emith_pop(s); \
+}
+
 // _r_imm
 #define emith_move_r_imm(r, imm) { \
        EMIT_OP(0xb8 + (r)); \
@@ -200,6 +212,11 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
        emith_or_r_imm(r, imm); \
 }
 
+#define emith_eor_r_imm_c(cond, r, imm) { \
+       (void)(cond); \
+       emith_eor_r_imm(r, imm); \
+}
+
 #define emith_sub_r_imm_c(cond, r, imm) { \
        (void)(cond); \
        emith_sub_r_imm(r, imm); \
@@ -264,11 +281,22 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
        emith_and_r_imm(d, t); \
 }
 
+#define emith_clear_msb_c(cond, d, s, count) { \
+       (void)(cond); \
+       emith_clear_msb(d, s, count); \
+}
+
 #define emith_sext(d, s, bits) { \
        emith_lsl(d, s, 32 - (bits)); \
        emith_asr(d, d, 32 - (bits)); \
 }
 
+#define emith_setc(r) { \
+       EMIT_OP(0x0f); \
+       EMIT(0x92, u8); \
+       EMIT_MODRM(3, 0, r); /* SETC r */ \
+}
+
 // put bit0 of r0 to carry
 #define emith_set_carry(r0) { \
        emith_tst_r_imm(r0, 1); /* clears C */ \
@@ -318,6 +346,19 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 #define emith_mul(d, s1, s2) \
        emith_mul_(4, d, -1, s1, s2)
 
+// (dlo,dhi) += signed(s1) * signed(s2)
+#define emith_mula_s64(dlo, dhi, s1, s2) { \
+       emith_push(dhi); \
+       emith_push(dlo); \
+       emith_mul_(5, dlo, dhi, s1, s2); \
+       EMIT_OP_MODRM(0x03, 0, dlo, 4); \
+       EMIT_SIB(0, 4, 4); /* add dlo, [esp] */ \
+       EMIT_OP_MODRM(0x13, 1, dhi, 4); \
+       EMIT_SIB(0, 4, 4); \
+       EMIT(4, u8); /* adc dhi, [esp+4] */ \
+       emith_add_r_imm(xSP, 4*2); \
+}
+
 // "flag" instructions are the same
 #define emith_subf_r_imm emith_sub_r_imm
 #define emith_addf_r_r   emith_add_r_r
@@ -357,6 +398,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
        EMIT(disp, u32); \
 }
 
+#define emith_call_cond(cond, ptr) \
+       emith_call(ptr)
+
 // "simple" or "short" jump
 #define EMITH_SJMP_START(cond) { \
        u8 *cond_ptr; \
@@ -429,11 +473,31 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 
 #define emith_carry_to_t(srr, is_sub) { \
        int tmp_ = rcache_get_tmp(); \
-       EMIT_OP(0x0f); \
-       EMIT(0x92, u8); \
-       EMIT_MODRM(3, 0, tmp_); /* SETC */ \
+       emith_setc(tmp_); \
        emith_bic_r_imm(srr, 1); \
        EMIT_OP_MODRM(0x08, 3, tmp_, srr); /* OR srrl, tmpl */ \
        rcache_free_tmp(tmp_); \
 }
 
+/*
+ * if Q
+ *   t = carry(Rn += Rm)
+ * else
+ *   t = carry(Rn -= Rm)
+ * T ^= t
+ */
+#define emith_sh2_div1_step(rn, rm, sr) {         \
+       u8 *jmp0, *jmp1;                          \
+       int tmp_ = rcache_get_tmp();              \
+       emith_tst_r_imm(sr, Q);  /* if (Q ^ M) */ \
+       JMP8_POS(jmp0);          /* je do_sub */  \
+       emith_add_r_r(rn, rm);                    \
+       JMP8_POS(jmp1);          /* jmp done */   \
+       JMP8_EMIT(IOP_JE, jmp0); /* do_sub: */    \
+       emith_sub_r_r(rn, rm);                    \
+       JMP8_EMIT(IOP_JMP, jmp1);/* done: */      \
+       emith_setc(tmp_);                         \
+       EMIT_OP_MODRM(0x30, 3, tmp_, sr); /* T = Q1 ^ Q2 (byte) */ \
+       rcache_free_tmp(tmp_);                    \
+}
+
index 1f142dd..02add39 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * vim:shiftwidth=2:expandtab
  */
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
@@ -125,6 +126,9 @@ static temp_reg_t reg_temp[] = {
 #define Q      0x00000100
 #define M      0x00000200
 
+#define Q_SHIFT 8
+#define M_SHIFT 9
+
 typedef enum {
   SHR_R0 = 0, SHR_SP = 15,
   SHR_PC,  SHR_PPC, SHR_PR,   SHR_SR,
@@ -517,6 +521,58 @@ static void emit_indirect_indexed_write(int rx, int ry, int wr, int size)
   emit_memhandler_write(size);
 }
 
+// read @Rn, @rm
+static void emit_indirect_read_double(u32 *rnr, u32 *rmr, int rn, int rm, int size)
+{
+  int tmp;
+
+  rcache_clean();
+  rcache_get_reg_arg(0, rn);
+  tmp = emit_memhandler_read(size);
+  emith_ctx_write(tmp, offsetof(SH2, drc_tmp));
+  rcache_free_tmp(tmp);
+  tmp = rcache_get_reg(rn, RC_GR_RMW);
+  emith_add_r_imm(tmp, 1 << size);
+
+  rcache_clean();
+  rcache_get_reg_arg(0, rm);
+  *rmr = emit_memhandler_read(size);
+  *rnr = rcache_get_tmp();
+  emith_ctx_read(*rnr, offsetof(SH2, drc_tmp));
+  tmp = rcache_get_reg(rm, RC_GR_RMW);
+  emith_add_r_imm(tmp, 1 << size);
+}
+// fixup for saturated MAC, to be called from generated code
+// FIXME: statically alloced regs need to be fixed
+static void sh2_macl_sat_fixup(void)
+{
+  if ((signed int)sh2->mach < 0 && sh2->mach < 0xffff8000)
+  {
+    sh2->mach = 0x00008000;
+    sh2->macl = 0x00000000;
+  }
+  else if ((signed int)sh2->mach > 0 && sh2->mach > 0x00007fff)
+  {
+    sh2->mach = 0x00007fff;
+    sh2->macl = 0xffffffff;
+  }
+}
+
+static void sh2_macw_sat_fixup(void)
+{
+  signed int t = sh2->mach;
+  if (t < -1 || (t == -1 && !(sh2->macl & 0x80000000)))
+  {
+    sh2->mach = 0xffffffff; // ?
+    sh2->macl = 0x80000000;
+  }
+  else if (t > 0 || (t == 0 && (sh2->macl & 0x80000000)))
+  {
+    sh2->mach = 0x7fffffff;
+    sh2->macl = 0xffffffff;
+  }
+}
 
 #define DELAYED_OP \
   delayed_op = 2
@@ -546,7 +602,7 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
   int op, delayed_op = 0, test_irq = 0;
   int tcache_id = 0, blkid = 0;
   int cycles = 0;
-  u32 tmp, tmp2, tmp3, tmp4;
+  u32 tmp, tmp2, tmp3, tmp4, sr;
 
   // validate PC
   tmp = sh2->pc >> 29;
@@ -771,8 +827,27 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         rcache_free_tmp(tmp);
         goto end_op;
       case 0x0f: // MAC.L   @Rm+,@Rn+  0000nnnnmmmm1111
-        // TODO
-        break;
+        emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 2);
+        tmp3 = rcache_get_reg(SHR_SR, RC_GR_READ);
+        tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
+        /* MS 16 MAC bits unused if saturated */
+        emith_tst_r_imm(tmp3, S);
+        EMITH_SJMP_START(DCOND_EQ);
+        emith_clear_msb_c(DCOND_NE, tmp4, tmp4, 16);
+        EMITH_SJMP_END(DCOND_EQ);
+        tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW); // might evict SR
+        emith_mula_s64(tmp3, tmp4, tmp, tmp2);
+        rcache_free_tmp(tmp);
+        rcache_free_tmp(tmp2);
+        rcache_clean();
+        tmp3 = rcache_get_reg(SHR_SR, RC_GR_READ);
+        emith_tst_r_imm(tmp3, S);
+        EMITH_SJMP_START(DCOND_EQ);
+        emith_call_cond(DCOND_NE, sh2_macl_sat_fixup);
+        EMITH_SJMP_END(DCOND_EQ);
+        rcache_invalidate();
+        cycles += 3;
+        goto end_op;
       }
       goto default_;
 
@@ -869,7 +944,7 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         tmp  = rcache_get_reg(GET_Rn(), RC_GR_RMW);
         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
         emith_lsr(tmp, tmp, 16);
-        emith_or_r_r_r_lsl(tmp, tmp, tmp2, 16);
+        emith_or_r_r_lsl(tmp, tmp2, 16);
         goto end_op;
       case 0x0e: // MULU.W Rm,Rn        0010nnnnmmmm1110
       case 0x0f: // MULS.W Rm,Rn        0010nnnnmmmm1111
@@ -935,8 +1010,37 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         }
         goto end_op;
       case 0x04: // DIV1    Rm,Rn       0011nnnnmmmm0100
-        // TODO
-        break;
+        // Q1 = carry(Rn = (Rn << 1) | T)
+        // if Q ^ M
+        //   Q2 = carry(Rn += Rm)
+        // else
+        //   Q2 = carry(Rn -= Rm)
+        // Q = M ^ Q1 ^ Q2
+        // T = (Q == M) = !(Q ^ M) = !(Q1 ^ Q2)
+        tmp2 = rcache_get_reg(GET_Rn(), RC_GR_RMW);
+        tmp3 = rcache_get_reg(GET_Rm(), RC_GR_READ);
+        sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
+        emith_set_carry(sr);
+        emith_adcf_r_r(tmp2, tmp2);
+        emith_carry_to_t(sr, 0);            // keep Q1 in T for now
+        tmp4 = rcache_get_tmp();
+        emith_and_r_r_imm(tmp4, sr, M);
+        emith_eor_r_r_lsr(sr, tmp4, M_SHIFT - Q_SHIFT); // Q ^= M
+        rcache_free_tmp(tmp4);
+        // add or sub, invert T if carry to get Q1 ^ Q2
+        // in: (Q ^ M) passed in Q, Q1 in T
+        emith_sh2_div1_step(tmp2, tmp3, sr);
+       emith_bic_r_imm(sr, Q);
+       emith_tst_r_imm(sr, M);
+       EMITH_SJMP_START(DCOND_EQ);
+       emith_or_r_imm_c(DCOND_NE, sr, Q);  // Q = M
+       EMITH_SJMP_END(DCOND_EQ);
+       emith_tst_r_imm(sr, T);
+       EMITH_SJMP_START(DCOND_EQ);
+       emith_eor_r_imm_c(DCOND_NE, sr, Q); // Q = M ^ Q1 ^ Q2
+       EMITH_SJMP_END(DCOND_EQ);
+       emith_eor_r_imm(sr, T);             // T = !(Q1 ^ Q2)
+        goto end_op;
       case 0x05: // DMULU.L Rm,Rn       0011nnnnmmmm0101
         tmp  = rcache_get_reg(GET_Rn(), RC_GR_READ);
         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
@@ -1248,7 +1352,6 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         }
         if (tmp2 == SHR_SR) {
           emith_write_sr(tmp);
-          emit_move_r_imm32(SHR_PC, pc);
           test_irq = 1;
         } else {
           tmp2 = rcache_get_reg(tmp2, RC_GR_WRITE);
@@ -1257,7 +1360,24 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         goto end_op;
       case 0x0f:
         // MAC @Rm+,@Rn+  0100nnnnmmmm1111
-        break; // TODO
+        emit_indirect_read_double(&tmp, &tmp2, GET_Rn(), GET_Rm(), 1);
+        emith_sext(tmp, tmp, 16);
+        emith_sext(tmp2, tmp2, 16);
+        tmp3 = rcache_get_reg(SHR_MACL, RC_GR_RMW);
+        tmp4 = rcache_get_reg(SHR_MACH, RC_GR_RMW);
+        emith_mula_s64(tmp3, tmp4, tmp, tmp2);
+        rcache_free_tmp(tmp);
+        rcache_free_tmp(tmp2);
+        rcache_clean();
+        // XXX: MACH should be untouched when S is set?
+        tmp3 = rcache_get_reg(SHR_SR, RC_GR_READ);
+        emith_tst_r_imm(tmp3, S);
+        EMITH_SJMP_START(DCOND_EQ);
+        emith_call_cond(DCOND_NE, sh2_macw_sat_fixup);
+        EMITH_SJMP_END(DCOND_EQ);
+        rcache_invalidate();
+        cycles += 2;
+        goto end_op;
       }
       goto default_;
 
@@ -1315,9 +1435,9 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
             tmp3 = rcache_get_tmp();
           tmp4 = rcache_get_tmp();
           emith_lsr(tmp3, tmp, 16);
-          emith_or_r_r_r_lsl(tmp3, tmp3, tmp, 24);
+          emith_or_r_r_lsl(tmp3, tmp, 24);
           emith_and_r_r_imm(tmp4, tmp, 0xff00);
-          emith_or_r_r_r_lsl(tmp3, tmp3, tmp4, 8);
+          emith_or_r_r_lsl(tmp3, tmp4, 8);
           emith_rol(tmp2, tmp3, 16);
           rcache_free_tmp(tmp4);
           if (tmp == tmp2)
@@ -1429,8 +1549,14 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
     /////////////////////////////////////////////
     case 0x09:
       // MOV.W @(disp,PC),Rn  1001nnnndddddddd
-      // TODO
-      goto default_;
+      rcache_clean();
+      tmp = rcache_get_tmp_arg(0);
+      emith_move_r_imm(tmp, pc + (op & 0xff) * 2 + 2);
+      tmp  = emit_memhandler_read(1);
+      tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
+      emith_sext(tmp2, tmp, 16);
+      rcache_free_tmp(tmp);
+      goto end_op;
 
     /////////////////////////////////////////////
     case 0x0a:
@@ -1557,8 +1683,14 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
     /////////////////////////////////////////////
     case 0x0d:
       // MOV.L @(disp,PC),Rn  1101nnnndddddddd
-      // TODO
-      goto default_;
+      rcache_clean();
+      tmp = rcache_get_tmp_arg(0);
+      emith_move_r_imm(tmp, (pc + (op & 0xff) * 4 + 2) & ~3);
+      tmp  = emit_memhandler_read(2);
+      tmp2 = rcache_get_reg(GET_Rn(), RC_GR_WRITE);
+      emith_move_r_r(tmp2, tmp);
+      rcache_free_tmp(tmp);
+      goto end_op;
 
     /////////////////////////////////////////////
     case 0x0e:
@@ -1569,11 +1701,15 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
 
     default:
     default_:
+      elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
+        sh2->is_slave ? 's' : 'm', op, pc - 2);
+#ifdef DRC_DEBUG_INTERP
       emit_move_r_imm32(SHR_PC, pc - 2);
       rcache_flush();
       emith_pass_arg_r(0, CONTEXT_REG);
       emith_pass_arg_imm(1, op);
       emith_call(sh2_do_op);
+#endif
       break;
     }
 
@@ -1582,10 +1718,12 @@ end_op:
       emit_move_r_r(SHR_PC, SHR_PPC);
 
     if (test_irq && delayed_op != 2) {
+      if (!delayed_op)
+        emit_move_r_imm32(SHR_PC, pc);
       rcache_flush();
       emith_pass_arg_r(0, CONTEXT_REG);
       emith_call(sh2_test_irq);
-      break;
+      goto end_block_btf;
     }
     if (delayed_op == 1)
       break;
index 8e84f7e..7beead3 100644 (file)
 #define LOG(x) do { if (VERBOSE) logerror x; } while (0)\r
 \r
 //int sh2_icount;\r
-SH2 *sh2;\r
+//SH2 *sh2;\r
 \r
 #if 0\r
 INLINE UINT8 RB(offs_t A)\r
index 57b7d9c..9fdbe66 100644 (file)
@@ -33,7 +33,7 @@ typedef unsigned char  UINT8;
 
 #include "sh2.c"
 
-#ifndef DRC_TMP
+#ifndef DRC_SH2
 
 void sh2_execute(SH2 *sh2_, int cycles)
 {
@@ -48,6 +48,7 @@ void sh2_execute(SH2 *sh2_, int cycles)
        {
                UINT32 opcode;
 
+               /* FIXME: Darxide doesn't like this */
                if (sh2->test_irq && !sh2->delay && sh2->pending_level > ((sh2->sr >> 4) & 0x0f))
                {
                        if (sh2->pending_irl > sh2->pending_int_irq)
@@ -102,7 +103,7 @@ void sh2_execute(SH2 *sh2_, int cycles)
        sh2->cycles_done += cycles - sh2->icount;
 }
 
-#else // DRC_TMP
+#else // DRC_SH2
 
 #ifdef __i386__
 #define REGPARM(x) __attribute__((regparm(x)))
@@ -110,7 +111,7 @@ void sh2_execute(SH2 *sh2_, int cycles)
 #define REGPARM(x)
 #endif
 
-// tmp
+// drc debug
 void REGPARM(2) sh2_do_op(SH2 *sh2_, int opcode)
 {
        sh2 = sh2_;
index cd07bef..d8d82ed 100644 (file)
@@ -4,6 +4,8 @@
 
 #define I 0xf0
 
+SH2 *sh2; // active sh2
+
 int sh2_init(SH2 *sh2, int is_slave)
 {
        int ret = 0;
index 264bb4e..8e9f3b0 100644 (file)
@@ -11,20 +11,20 @@ typedef struct
        unsigned int    gbr, vbr;       // 50\r
        unsigned int    mach, macl;     // 58\r
 \r
-       // interpreter stuff\r
-       int             icount;         // 60 cycles left in current timeslice\r
-       unsigned int    ea;\r
-       unsigned int    delay;\r
-       unsigned int    test_irq;\r
-\r
        // common\r
-       const void      *read8_map;     // 70\r
+       const void      *read8_map;     // 60\r
        const void      *read16_map;\r
        const void      **write8_tab;\r
        const void      **write16_tab;\r
 \r
        // drc stuff\r
-       //void  **pc_hashtab;           // 80\r
+       int             drc_tmp;        // 70\r
+\r
+       // interpreter stuff\r
+       int             icount;         // cycles left in current timeslice\r
+       unsigned int    ea;\r
+       unsigned int    delay;\r
+       unsigned int    test_irq;\r
 \r
        int     pending_level;          // MAX(pending_irl, pending_int_irq)\r
        int     pending_irl;\r
@@ -37,7 +37,7 @@ typedef struct
        unsigned int    cycles_done;\r
 } SH2;\r
 \r
-extern SH2 *sh2; // active sh2\r
+extern SH2 *sh2; // active sh2. XXX: consider removing\r
 \r
 int  sh2_init(SH2 *sh2, int is_slave);\r
 void sh2_finish(SH2 *sh2);\r
diff --git a/platform/common/common.mak b/platform/common/common.mak
new file mode 100644 (file)
index 0000000..edc8aae
--- /dev/null
@@ -0,0 +1,78 @@
+# === CPU cores ===
+# --- M68k ---
+ifeq "$(use_musashi)" "1"
+DEFINES += EMU_M68K
+OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o
+#OBJS += cpu/musashi/m68kdasm.o
+endif
+ifeq "$(use_cyclone)" "1"
+DEFINES += EMU_C68K
+OBJS += pico/m68kif_cyclone.o cpu/Cyclone/proj/Cyclone.o cpu/Cyclone/tools/idle.o
+endif
+ifeq "$(use_fame)" "1"
+DEFINES += EMU_F68K
+OBJS += cpu/fame/famec.o
+endif
+
+# --- Z80 ---
+ifeq "$(use_mz80)" "1"
+DEFINES += _USE_MZ80
+OBJS += cpu/mz80/mz80.o
+endif
+#
+ifeq "$(use_drz80)" "1"
+DEFINES += _USE_DRZ80
+OBJS += cpu/DrZ80/drz80.o
+endif
+#
+ifeq "$(use_cz80)" "1"
+DEFINES += _USE_CZ80
+OBJS += cpu/cz80/cz80.o
+endif
+
+# --- SH2 ---
+OBJS += cpu/sh2/sh2.o
+OBJS += cpu/drc/cmn.o
+#
+ifeq "$(use_sh2drc)" "1"
+DEFINES += DRC_SH2
+OBJS += cpu/sh2/compiler.o
+OBJS += cpu/sh2/stub_$(ARCH).o
+ifdef drc_debug
+DEFINES += DRC_DEBUG=$(drc_debug)
+OBJS += cpu/sh2/mame/sh2dasm.o
+OBJS += platform/linux/host_dasm.o
+LDFLAGS += -lbfd -lopcodes -liberty
+endif
+ifeq "$(drc_debug_interp)" "1"
+DEFINES += DRC_DEBUG_INTERP
+use_sh2mame = 1
+endif
+endif
+#
+ifeq "$(use_sh2mame)" "1"
+OBJS += cpu/sh2/mame/sh2pico.o
+endif
+
+
+# random deps
+pico/carthw/svp/compiler.o : ../../cpu/drc/emit_$(ARCH).c
+cpu/sh2/compiler.o : ../../cpu/drc/emit_$(ARCH).c
+cpu/sh2/mame/sh2pico.o : ../../cpu/sh2/mame/sh2.c
+pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h
+pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h
+
+../../cpu/musashi/m68kops.c :
+       @make -C ../../cpu/musashi
+
+../../cpu/mz80/mz80.asm :
+       @make -C ../../cpu/mz80/
+
+cpu/fame/famec.o : ../../cpu/fame/famec.c ../../cpu/fame/famec_opcodes.h
+       @echo ">>>" $<
+       $(CC) $(CFLAGS) -Wno-unused -c $< -o $@
+
+../../cpu/Cyclone/proj/Cyclone.s:
+       @echo building Cyclone...
+       @make -C ../../cpu/Cyclone/proj CONFIG_FILE=config_pico.h
+
index 6f8eb9a..11270a3 100644 (file)
@@ -45,20 +45,6 @@ clean_prof:
 mkdirs:
        mkdir -p $(DIRS)
 
-# some deps
-pico/carthw/svp/compiler.o : ../../pico/carthw/svp/ssp16.o ../../cpu/drc/emit_arm.c
-cpu/sh2/compiler.o : ../../cpu/drc/emit_arm.c
-pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h
-pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h
-
-# build Cyclone
-../../cpu/Cyclone/proj/Cyclone.s:
-       @echo building Cyclone...
-       @make -C ../../cpu/Cyclone/proj CONFIG_FILE=config_pico.h
-
-../../cpu/musashi/m68kops.c :
-       @make -C ../../cpu/musashi
-
 # build helix libs
 ../common/helix/$(CROSS)helix-mp3.a:
        make -C ../common/helix clean all
index 934be24..cdfea37 100644 (file)
@@ -1,8 +1,12 @@
-export CROSS = arm-linux-\r
+CROSS ?= arm-linux-\r
 \r
 # settings\r
-#mz80 = 1\r
-#debug_cyclone = 1\r
+use_cyclone = 1\r
+#use_musashi = 1\r
+use_drz80 = 1\r
+use_sh2drc = 1\r
+#use_sh2mame = 1\r
+\r
 asm_memory = 1\r
 asm_render = 1\r
 asm_ym2612 = 1\r
@@ -11,8 +15,6 @@ asm_cdpico = 1
 asm_cdmemory = 1\r
 amalgamate = 0\r
 #profile = 1\r
-#use_musashi = 1\r
-use_sh2drc = 1\r
 #drc_debug = 3\r
 \r
 -include Makefile.local\r
@@ -25,10 +27,9 @@ ifeq "$(use_musashi)" "1"
 # due to CPU stop flag acces\r
 asm_cdpico = 0\r
 asm_cdmemory = 0\r
-else\r
-use_cyclone = 1\r
 endif\r
 \r
+ARCH = arm\r
 DEFINES += ARM __GP2X__ IN_GP2X IN_EVDEV # BENCHMARK\r
 CFLAGS += -Wall -Winline -I../.. -I.\r
 ifeq ($(DEBUG),)\r
@@ -94,42 +95,6 @@ OBJS += unzip/unzip.o unzip/unzip_stream.o
 # zlib\r
 OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \\r
        zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o\r
-# debug\r
-ifeq "$(debug_cyclone)" "1"\r
-OBJS += pico/DebugCPU.o cpu/musashi/m68kdasm.o\r
-endif\r
-# CPU cores\r
-ifeq "$(use_musashi)" "1"\r
-DEFINES += EMU_M68K\r
-OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o\r
-endif\r
-ifeq "$(use_cyclone)" "1"\r
-DEFINES += EMU_C68K\r
-OBJS += pico/m68kif_cyclone.o cpu/Cyclone/proj/Cyclone.o cpu/Cyclone/tools/idle.o\r
-endif\r
-ifeq "$(mz80)" "1"\r
-DEFINES += _USE_MZ80\r
-OBJS += cpu/mz80/mz80.o\r
-else\r
-DEFINES += _USE_DRZ80\r
-OBJS += cpu/DrZ80/drz80.o\r
-endif\r
-OBJS += cpu/sh2/sh2.o\r
-ifeq "$(use_sh2drc)" "1"\r
-DEFINES += DRC_SH2 DRC_TMP\r
-OBJS += cpu/sh2/mame/sh2pico.o\r
-OBJS += cpu/sh2/compiler.o\r
-OBJS += cpu/sh2/stub_arm.o\r
-ifdef drc_debug\r
-DEFINES += DRC_DEBUG=$(drc_debug)\r
-OBJS += cpu/sh2/mame/sh2dasm.o\r
-OBJS += platform/linux/host_dasm.o\r
-LDFLAGS += -lbfd -lopcodes -liberty\r
-endif\r
-else\r
-OBJS += cpu/sh2/mame/sh2pico.o\r
-endif\r
-OBJS += cpu/drc/cmn.o\r
 \r
 CFLAGS += $(addprefix -D,$(DEFINES))\r
 \r
@@ -144,6 +109,7 @@ DIRS = platform platform/gp2x platform/linux platform/common pico pico/cd pico/p
 \r
 all: mkdirs PicoDrive\r
 \r
+include ../common/common.mak\r
 include ../common/common_arm.mak\r
 include ../common/revision.mak\r
 \r
index 3638286..6c28e41 100644 (file)
@@ -1,9 +1,12 @@
 # settings
 use_musashi = 1
 #use_fame = 1
-#use_mz80 = 1
+use_cz80 = 1
 use_sh2drc = 1
+#use_sh2mame = 1
+
 #drc_debug = 3
+#drc_debug_interp = 1
 #profile = 1
 #fake_in_gp2x = 1
 
@@ -70,47 +73,6 @@ OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \
        zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o zlib/uncompr.o
 # unzip
 OBJS += unzip/unzip.o unzip/unzip_stream.o
-# CPU cores
-ifeq "$(use_musashi)" "1"
-DEFINES += EMU_M68K
-OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o
-#OBJS += cpu/musashi/m68kdasm.o
-endif
-ifeq "$(use_fame)" "1"
-DEFINES += EMU_F68K
-OBJS += cpu/fame/famec.o
-endif
-# z80
-ifeq "$(use_mz80)" "1"
-DEFINES += _USE_MZ80
-OBJS += cpu/mz80/mz80.o
-else
-DEFINES += _USE_CZ80
-OBJS += cpu/cz80/cz80.o
-endif
-# sh2
-OBJS += cpu/sh2/sh2.o
-ifeq "$(use_sh2drc)" "1"
-DEFINES += DRC_SH2 DRC_TMP
-OBJS += cpu/sh2/mame/sh2pico.o
-OBJS += cpu/sh2/compiler.o
-OBJS += cpu/sh2/stub_$(ARCH).o
-ifdef drc_debug
-DEFINES += DRC_DEBUG=$(drc_debug)
-OBJS += cpu/sh2/mame/sh2dasm.o
-OBJS += host_dasm.o
-LDFLAGS += -lbfd -lopcodes -liberty
-endif
-else
-OBJS += cpu/sh2/mame/sh2pico.o
-endif
-OBJS += cpu/drc/cmn.o
-# misc
-ifeq "$(use_fame)" "1"
-ifeq "$(use_musashi)" "1"
-OBJS += pico/debugCPU.o
-endif
-endif
 
 CFLAGS += $(addprefix -D,$(DEFINES))
 
@@ -119,10 +81,13 @@ vpath %.s = ../..
 vpath %.S = ../..
 vpath %.asm = ../..
 
-DIRS = platform platform/gp2x platform/common pico pico/cd pico/pico pico/sound pico/carthw/svp \
+DIRS = platform/linux platform/gp2x platform/common pico pico/cd pico/pico pico/sound pico/carthw/svp \
        pico/32x zlib unzip cpu cpu/musashi cpu/fame cpu/mz80 cpu/cz80 cpu/sh2/mame cpu/drc
 
 all: mkdirs PicoDrive
+
+include ../common/common.mak
+
 clean: tidy
        @$(RM) PicoDrive
 tidy:
@@ -139,22 +104,6 @@ mkdirs:
 
 include ../common/revision.mak
 
-pico/carthw/svp/compiler.o : ../../cpu/drc/emit_arm.c
-cpu/sh2/compiler.o : ../../cpu/drc/emit_x86.c
-cpu/sh2/mame/sh2pico.o : ../../cpu/sh2/mame/sh2.c
-pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h
-pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h
-
-../../cpu/musashi/m68kops.c :
-       @make -C ../../cpu/musashi
-
-cpu/mz80/mz80.o : ../../cpu/mz80/mz80.asm
-       @echo $@
-       @nasm -f elf $< -o $@
-
-../../cpu/mz80/mz80.asm :
-       @make -C ../../cpu/mz80/
-
 .c.o:
        @echo ">>>" $<
        $(CC) $(CFLAGS) -c $< -o $@
@@ -165,8 +114,3 @@ cpu/mz80/mz80.o : ../../cpu/mz80/mz80.asm
        @echo ">>>" $<
        nasm -f elf $< -o $@
 
-
-cpu/fame/famec.o : ../../cpu/fame/famec.c ../../cpu/fame/famec_opcodes.h
-       @echo ">>>" $<
-       $(CC) $(CFLAGS) -Wno-unused -c $< -o $@
-