32x: drc: enable and fix static reg alloc, carry flag tweaks
authornotaz <notasas@gmail.com>
Mon, 7 Dec 2009 15:30:52 +0000 (15:30 +0000)
committernotaz <notasas@gmail.com>
Mon, 7 Dec 2009 15:30:52 +0000 (15:30 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@838 be3aeb3a-fb24-0410-a615-afba39da0efa

cpu/drc/emit_arm.c
cpu/drc/emit_x86.c
cpu/sh2/compiler.c

index f651dd5..5195483 100644 (file)
@@ -3,7 +3,7 @@
 // (c) Copyright 2008-2009, Grazvydas "notaz" Ignotas
 // Free for non-commercial use.
 
-#define CONTEXT_REG 7
+#define CONTEXT_REG 11
 
 // XXX: tcache_ptr type for SVP and SH2 compilers differs..
 #define EMIT_PTR(ptr, x) \
 #define EOP_XXM(cond,p,u,s,w,l,rn,list) \
        EMIT(((cond)<<28) | (1<<27) | ((p)<<24) | ((u)<<23) | ((s)<<22) | ((w)<<21) | ((l)<<20) | ((rn)<<16) | (list))
 
-#define EOP_STMFD(rb,list) EOP_XXM(A_COND_AL,1,0,0,1,0,rb,list)
-#define EOP_LDMFD(rb,list) EOP_XXM(A_COND_AL,0,1,0,1,1,rb,list)
+#define EOP_STMIA(rb,list) EOP_XXM(A_COND_AL,0,1,0,0,0,rb,list)
+#define EOP_LDMIA(rb,list) EOP_XXM(A_COND_AL,0,1,0,0,1,rb,list)
+
+#define EOP_STMFD_SP(list) EOP_XXM(A_COND_AL,1,0,0,1,0,13,list)
+#define EOP_LDMFD_SP(list) EOP_XXM(A_COND_AL,0,1,0,1,1,13,list)
 
 /* branches */
 #define EOP_C_BX(cond,rm) \
@@ -357,6 +360,9 @@ static int emith_xbranch(int cond, void *target, int is_call)
 #define emith_sub_r_r(d, s) \
        EOP_SUB_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0)
 
+#define emith_adc_r_r(d, s) \
+       EOP_ADC_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0)
+
 #define emith_and_r_r(d, s) \
        EOP_AND_REG(A_COND_AL,0,d,d,s,A_AM1_LSL,0)
 
@@ -521,25 +527,26 @@ static int emith_xbranch(int cond, void *target, int is_call)
 #define emith_ctx_read(r, offs) \
        EOP_LDR_IMM(r, CONTEXT_REG, offs)
 
-#define emith_ctx_read_multiple(r, offs, count, tmpr) do { \
-       int v_, r_ = r, c_ = count; \
-       for (v_ = 0; c_; c_--, r_++) \
-               v_ |= 1 << r_; \
-       EOP_ADD_IMM(tmpr,CONTEXT_REG,30/2,(offs)>>2); \
-       EOP_LDMFD(tmpr,v_); \
-} while(0)
-
 #define emith_ctx_write(r, offs) \
        EOP_STR_IMM(r, CONTEXT_REG, offs)
 
-#define emith_ctx_write_multiple(r, offs, count, tmpr) do { \
-       int v_, r_ = r, c_ = count; \
-       for (v_ = 0; c_; c_--, r_++) \
-               v_ |= 1 << r_; \
-       EOP_ADD_IMM(tmpr,CONTEXT_REG,30/2,(offs)>>2); \
-       EOP_STMFD(tmpr,v_); \
+#define emith_ctx_do_multiple(op, r, offs, count, tmpr) do { \
+       int v_, r_ = r, c_ = count, b_ = CONTEXT_REG;        \
+       for (v_ = 0; c_; c_--, r_++)                         \
+               v_ |= 1 << r_;                               \
+       if ((offs) != 0) {                                   \
+               EOP_ADD_IMM(tmpr,CONTEXT_REG,30/2,(offs)>>2);\
+               b_ = tmpr;                                   \
+       }                                                    \
+       op(b_,v_);                                           \
 } while(0)
 
+#define emith_ctx_read_multiple(r, offs, count, tmpr) \
+       emith_ctx_do_multiple(EOP_LDMIA, r, offs, count, tmpr)
+
+#define emith_ctx_write_multiple(r, offs, count, tmpr) \
+       emith_ctx_do_multiple(EOP_STMIA, r, offs, count, tmpr)
+
 #define emith_clear_msb_c(cond, d, s, count) { \
        u32 t; \
        if ((count) <= 8) { \
@@ -566,19 +573,6 @@ static int emith_xbranch(int cond, void *target, int is_call)
        EOP_MOV_REG_ASR(d,d,32 - (bits)); \
 }
 
-// _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 */ \
-
-// put bit0 of r0 to carry (for subtraction, inverted on ARM)
-#define emith_set_carry_sub(r0) { \
-       int t = rcache_get_tmp(); \
-       EOP_EOR_IMM(t,r0,0,1); /* invert */ \
-       EOP_MOV_REG(A_COND_AL,1,t,t,A_AM1_LSR,1); /* shift out to carry */ \
-       rcache_free_tmp(t); \
-}
-
 #define host_arg2reg(rd, arg) \
        rd = arg
 
@@ -606,10 +600,10 @@ static int emith_xbranch(int cond, void *target, int is_call)
 
 /* SH2 drc specific */
 #define emith_sh2_drc_entry() \
-       EOP_STMFD(13,A_R7M|A_R14M)
+       EOP_STMFD_SP(A_R4M|A_R5M|A_R6M|A_R7M|A_R8M|A_R9M|A_R10M|A_R11M|A_R14M)
 
 #define emith_sh2_drc_exit() \
-       EOP_LDMFD(13,A_R7M|A_R15M)
+       EOP_LDMFD_SP(A_R4M|A_R5M|A_R6M|A_R7M|A_R8M|A_R9M|A_R10M|A_R11M|A_R15M)
 
 #define emith_sh2_test_t() { \
        int r = rcache_get_reg(SHR_SR, RC_GR_READ); \
@@ -654,6 +648,18 @@ static int emith_xbranch(int cond, void *target, int is_call)
        } \
 }
 
+#define emith_tpop_carry(sr, is_sub) {  \
+       if (is_sub)                     \
+               emith_eor_r_imm(sr, 1); \
+       emith_lsrf(sr, sr, 1);          \
+}
+
+#define emith_tpush_carry(sr, is_sub) { \
+       emith_adc_r_r(sr, sr);          \
+       if (is_sub)                     \
+               emith_eor_r_imm(sr, 1); \
+}
+
 /*
  * if Q
  *   t = carry(Rn += Rm)
index 7f314f0..8f28612 100644 (file)
@@ -1,7 +1,9 @@
 /*
+ * note:
+ *  temp registers must be eax-edx due to use of SETcc.
  * 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.
+ *  these are here because the compiler was designed
+ *  for ARM as it's primary target.
  */
 #include <stdarg.h>
 
@@ -298,21 +300,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 
 #define emith_setc(r) { \
        EMIT_OP(0x0f); \
-       EMIT(0x92, u8); \
-       EMIT_MODRM(3, 0, r); /* SETC r */ \
+       EMIT_OP_MODRM(0x92, 3, 0, r); /* SETC r */ \
 }
 
-// put bit0 of r0 to carry
-#define emith_set_carry(r0) { \
-       emith_tst_r_imm(r0, 1); /* clears C */ \
-       EMITH_SJMP_START(DCOND_EQ); \
-       EMIT_OP(0xf9); /* STC */ \
-       EMITH_SJMP_END(DCOND_EQ); \
-}
-
-// put bit0 of r0 to carry (for subtraction)
-#define emith_set_carry_sub emith_set_carry
-
 // XXX: stupid mess
 #define emith_mul_(op, dlo, dhi, s1, s2) { \
        int rmr; \
@@ -389,7 +379,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 
 #define emith_ctx_read_multiple(r, offs, cnt, tmpr) do { \
        int r_ = r, offs_ = offs, cnt_ = cnt;     \
-       for (; cnt > 0; r_++, offs_ += 4, cnt_--) \
+       for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \
                emith_ctx_read(r_, offs_);        \
 } while (0)
 
@@ -400,7 +390,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 
 #define emith_ctx_write_multiple(r, offs, cnt, tmpr) do { \
        int r_ = r, offs_ = offs, cnt_ = cnt;     \
-       for (; cnt > 0; r_++, offs_ += 4, cnt_--) \
+       for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \
                emith_ctx_write(r_, offs_);       \
 } while (0)
 
@@ -457,9 +447,13 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 #define emith_sh2_drc_entry() { \
        emith_push(xBX);        \
        emith_push(xBP);        \
+       emith_push(xSI);        \
+       emith_push(xDI);        \
 }
 
 #define emith_sh2_drc_exit() {  \
+       emith_pop(xDI);         \
+       emith_pop(xSI);         \
        emith_pop(xBP);         \
        emith_pop(xBX);         \
        EMIT_OP(0xc3); /* ret */\
@@ -467,8 +461,9 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 
 #define emith_sh2_test_t() { \
        int t = rcache_get_reg(SHR_SR, RC_GR_READ); \
-       EMIT_OP_MODRM(0xf6, 3, 0, t); \
-       EMIT(0x01, u8); /* test <reg>, byte 1 */ \
+       EMIT(0x66, u8); \
+       EMIT_OP_MODRM(0xf7, 3, 0, t); \
+       EMIT(0x01, u16); /* test <reg>, word 1 */ \
 }
 
 #define emith_sh2_dtbf_loop() { \
@@ -506,13 +501,11 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
        rcache_free_tmp(tmp_); \
 }
 
-#define emith_carry_to_t(srr, is_sub) { \
-       int tmp_ = rcache_get_tmp(); \
-       emith_setc(tmp_); \
-       emith_bic_r_imm(srr, 1); \
-       EMIT_OP_MODRM(0x08, 3, tmp_, srr); /* OR srrl, tmpl */ \
-       rcache_free_tmp(tmp_); \
-}
+#define emith_tpop_carry(sr, is_sub) \
+       emith_lsr(sr, sr, 1)
+
+#define emith_tpush_carry(sr, is_sub) \
+       emith_adc_r_r(sr, sr)
 
 /*
  * if Q
@@ -524,6 +517,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
 #define emith_sh2_div1_step(rn, rm, sr) {         \
        u8 *jmp0, *jmp1;                          \
        int tmp_ = rcache_get_tmp();              \
+       emith_eor_r_r(tmp_, tmp_);                \
        emith_tst_r_imm(sr, Q);  /* if (Q ^ M) */ \
        JMP8_POS(jmp0);          /* je do_sub */  \
        emith_add_r_r(rn, rm);                    \
@@ -532,7 +526,7 @@ enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
        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) */ \
+       EMIT_OP_MODRM(0x31, 3, tmp_, sr); /* T = Q1 ^ Q2 */ \
        rcache_free_tmp(tmp_);                    \
 }
 
index 19fb1a9..fc48413 100644 (file)
@@ -84,11 +84,11 @@ typedef struct {
 #include "../drc/emit_arm.c"
 
 static const int reg_map_g2h[] = {
+   4,  5,  6,  7,
+   8, -1, -1, -1,
   -1, -1, -1, -1,
-  -1, -1, -1, -1,
-  -1, -1, -1, -1,
-  -1, -1, -1, -1,
-  -1, -1, -1, -1,
+  -1, -1, -1,  9,
+  -1, -1, -1, 10,
   -1, -1, -1, -1,
 };
 
@@ -105,11 +105,11 @@ static temp_reg_t reg_temp[] = {
 #include "../drc/emit_x86.c"
 
 static const int reg_map_g2h[] = {
+  xSI,-1, -1, -1,
   -1, -1, -1, -1,
   -1, -1, -1, -1,
   -1, -1, -1, -1,
-  -1, -1, -1, -1,
-  -1, -1, -1, -1,
+  -1, -1, -1, xDI,
   -1, -1, -1, -1,
 };
 
@@ -1051,9 +1051,9 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         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_tpop_carry(sr, 0);
         emith_adcf_r_r(tmp2, tmp2);
-        emith_carry_to_t(sr, 0);            // keep Q1 in T for now
+        emith_tpush_carry(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
@@ -1094,13 +1094,13 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         tmp2 = rcache_get_reg(GET_Rm(), RC_GR_READ);
         sr   = rcache_get_reg(SHR_SR, RC_GR_RMW);
         if (op & 4) { // adc
-          emith_set_carry(sr);
+          emith_tpop_carry(sr, 0);
           emith_adcf_r_r(tmp, tmp2);
-          emith_carry_to_t(sr, 0);
+          emith_tpush_carry(sr, 0);
         } else {
-          emith_set_carry_sub(sr);
+          emith_tpop_carry(sr, 1);
           emith_sbcf_r_r(tmp, tmp2);
-          emith_carry_to_t(sr, 1);
+          emith_tpush_carry(sr, 1);
         }
         goto end_op;
       case 0x0b: // SUBV    Rm,Rn       0011nnnnmmmm1011
@@ -1138,8 +1138,9 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         case 2: // SHAL Rn    0100nnnn00100000
           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
+          emith_tpop_carry(sr, 0); // dummy
           emith_lslf(tmp, tmp, 1);
-          emith_carry_to_t(sr, 0);
+          emith_tpush_carry(sr, 0);
           goto end_op;
         case 1: // DT Rn      0100nnnn00010000
           if (p32x_sh2_read16(pc, sh2) == 0x8bfd) { // BF #-2
@@ -1161,11 +1162,12 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         case 2: // SHAR Rn    0100nnnn00100001
           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
+          emith_tpop_carry(sr, 0); // dummy
           if (op & 0x20) {
             emith_asrf(tmp, tmp, 1);
           } else
             emith_lsrf(tmp, tmp, 1);
-          emith_carry_to_t(sr, 0);
+          emith_tpush_carry(sr, 0);
           goto end_op;
         case 1: // CMP/PZ Rn  0100nnnn00010001
           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
@@ -1220,22 +1222,23 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
         case 0x05: // ROTR   Rn          0100nnnn00000101
           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
+          emith_tpop_carry(sr, 0); // dummy
           if (op & 1) {
             emith_rorf(tmp, tmp, 1);
           } else
             emith_rolf(tmp, tmp, 1);
-          emith_carry_to_t(sr, 0);
+          emith_tpush_carry(sr, 0);
           goto end_op;
         case 0x24: // ROTCL  Rn          0100nnnn00100100
         case 0x25: // ROTCR  Rn          0100nnnn00100101
           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
           sr  = rcache_get_reg(SHR_SR, RC_GR_RMW);
-          emith_set_carry(sr);
+          emith_tpop_carry(sr, 0);
           if (op & 1) {
             emith_rorcf(tmp);
           } else
             emith_rolcf(tmp);
-          emith_carry_to_t(sr, 0);
+          emith_tpush_carry(sr, 0);
           goto end_op;
         case 0x15: // CMP/PL Rn          0100nnnn00010101
           tmp = rcache_get_reg(GET_Rn(), RC_GR_RMW);
@@ -1487,9 +1490,9 @@ static void *sh2_translate(SH2 *sh2, block_desc *other_block)
           break;
         case 0x0a: // NEGC   Rm,Rn        0110nnnnmmmm1010
           sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
-          emith_set_carry_sub(sr);
+          emith_tpop_carry(sr, 1);
           emith_negcf_r_r(tmp2, tmp);
-          emith_carry_to_t(sr, 1);
+          emith_tpush_carry(sr, 1);
           break;
         case 0x0b: // NEG    Rm,Rn        0110nnnnmmmm1011
           emith_neg_r_r(tmp2, tmp);
@@ -2019,6 +2022,9 @@ int sh2_drc_init(SH2 *sh2)
 
     tcache_ptr = tcache;
     sh2_generate_utils();
+#ifdef ARM
+    cache_flush_d_inval_i(tcache, tcache_ptr);
+#endif
 
     memset(block_counts, 0, sizeof(block_counts));
     tcache_bases[0] = tcache_ptrs[0] = tcache_ptr;