qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [5111] SH4: convert branch/jump instructions to TCG


From: Aurelien Jarno
Subject: [Qemu-devel] [5111] SH4: convert branch/jump instructions to TCG
Date: Fri, 29 Aug 2008 22:32:32 +0000

Revision: 5111
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5111
Author:   aurel32
Date:     2008-08-29 22:32:32 +0000 (Fri, 29 Aug 2008)

Log Message:
-----------
SH4: convert branch/jump instructions to TCG

(Shin-ichiro KAWASAKI)

Modified Paths:
--------------
    trunk/target-sh4/op.c
    trunk/target-sh4/translate.c

Modified: trunk/target-sh4/op.c
===================================================================
--- trunk/target-sh4/op.c       2008-08-29 21:03:31 UTC (rev 5110)
+++ trunk/target-sh4/op.c       2008-08-29 22:32:32 UTC (rev 5111)
@@ -37,70 +37,6 @@
        clr_t();
 }
 
-void OPPROTO op_bf_s(void)
-{
-    env->delayed_pc = PARAM1;
-    if (!(env->sr & SR_T)) {
-        env->flags |= DELAY_SLOT_TRUE;
-    }
-    RETURN();
-}
-
-void OPPROTO op_bt_s(void)
-{
-    env->delayed_pc = PARAM1;
-    if (env->sr & SR_T) {
-        env->flags |= DELAY_SLOT_TRUE;
-    }
-    RETURN();
-}
-
-void OPPROTO op_store_flags(void)
-{
-    env->flags &= DELAY_SLOT_TRUE;
-    env->flags |= PARAM1;
-    RETURN();
-}
-
-void OPPROTO op_bra(void)
-{
-    env->delayed_pc = PARAM1;
-    RETURN();
-}
-
-void OPPROTO op_braf_T0(void)
-{
-    env->delayed_pc = PARAM1 + T0;
-    RETURN();
-}
-
-void OPPROTO op_bsr(void)
-{
-    env->pr = PARAM1;
-    env->delayed_pc = PARAM2;
-    RETURN();
-}
-
-void OPPROTO op_bsrf_T0(void)
-{
-    env->pr = PARAM1;
-    env->delayed_pc = PARAM1 + T0;
-    RETURN();
-}
-
-void OPPROTO op_jsr_T0(void)
-{
-    env->pr = PARAM1;
-    env->delayed_pc = T0;
-    RETURN();
-}
-
-void OPPROTO op_rts(void)
-{
-    env->delayed_pc = env->pr;
-    RETURN();
-}
-
 void OPPROTO op_ldtlb(void)
 {
     helper_ldtlb();
@@ -119,13 +55,6 @@
     RETURN();
 }
 
-void OPPROTO op_rte(void)
-{
-    env->sr = env->ssr;
-    env->delayed_pc = env->spc;
-    RETURN();
-}
-
 void OPPROTO op_addc_T0_T1(void)
 {
     helper_addc_T0_T1();
@@ -257,12 +186,6 @@
     RETURN();
 }
 
-void OPPROTO op_jmp_T0(void)
-{
-    env->delayed_pc = T0;
-    RETURN();
-}
-
 void OPPROTO op_ldcl_rMplus_rN_bank(void)
 {
     env->gregs[PARAM2] = env->gregs[PARAM1];
@@ -568,28 +491,6 @@
     RETURN();
 }
 
-void OPPROTO op_jT(void)
-{
-    if (env->sr & SR_T)
-       GOTO_LABEL_PARAM(1);
-    RETURN();
-}
-
-void OPPROTO op_jdelayed(void)
-{
-    if (env->flags & DELAY_SLOT_TRUE) {
-        env->flags &= ~DELAY_SLOT_TRUE;
-        GOTO_LABEL_PARAM(1);
-    }
-    RETURN();
-}
-
-void OPPROTO op_movl_delayed_pc_PC(void)
-{
-    env->pc = env->delayed_pc;
-    RETURN();
-}
-
 void OPPROTO op_raise_illegal_instruction(void)
 {
     env->exception_index = 0x180;

Modified: trunk/target-sh4/translate.c
===================================================================
--- trunk/target-sh4/translate.c        2008-08-29 21:03:31 UTC (rev 5110)
+++ trunk/target-sh4/translate.c        2008-08-29 22:32:32 UTC (rev 5111)
@@ -62,8 +62,11 @@
 static TCGv cpu_gregs[24];
 static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
-static TCGv cpu_pr, cpu_fpscr, cpu_fpul;
+static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_flags;
 
+/* internal register indexes */
+static TCGv cpu_flags, cpu_delayed_pc;
+
 /* dyngen register indexes */
 static TCGv cpu_T[2];
 
@@ -120,6 +123,12 @@
     cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
                                   offsetof(CPUState, fpul), "FPUL");
 
+    cpu_flags = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+                                  offsetof(CPUState, flags), "_flags_");
+    cpu_delayed_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+                                       offsetof(CPUState, delayed_pc),
+                                       "_delayed_pc_");
+
     /* register helpers */
 #undef DEF_HELPER
 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
@@ -249,7 +258,7 @@
     if (ctx->delayed_pc == (uint32_t) - 1) {
        /* Target is not statically known, it comes necessarily from a
           delayed jump as immediate jump are conditinal jumps */
-       gen_op_movl_delayed_pc_PC();
+       tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
        if (ctx->singlestep_enabled)
            gen_op_debug();
        tcg_gen_exit_tb(0);
@@ -258,6 +267,16 @@
     }
 }
 
+static inline void gen_branch_slot(uint32_t delayed_pc, int t)
+{
+    int label = gen_new_label();
+    tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
+    tcg_gen_andi_i32(cpu_T[0], cpu_sr, SR_T);
+    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], t ? SR_T : 0, label);
+    tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
+    gen_set_label(label);
+}
+
 /* Immediate conditional jump (bt or bf) */
 static void gen_conditional_jump(DisasContext * ctx,
                                 target_ulong ift, target_ulong ifnott)
@@ -265,7 +284,8 @@
     int l1;
 
     l1 = gen_new_label();
-    gen_op_jT(l1);
+    tcg_gen_andi_i32(cpu_T[0], cpu_sr, SR_T);
+    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], SR_T, l1);
     gen_goto_tb(ctx, 0, ifnott);
     gen_set_label(l1);
     gen_goto_tb(ctx, 1, ift);
@@ -277,9 +297,11 @@
     int l1;
 
     l1 = gen_new_label();
-    gen_op_jdelayed(l1);
+    tcg_gen_andi_i32(cpu_T[0], cpu_flags, DELAY_SLOT_TRUE);
+    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], DELAY_SLOT_TRUE, l1);
     gen_goto_tb(ctx, 1, ctx->pc + 2);
     gen_set_label(l1);
+    tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
     gen_jump(ctx);
 }
 
@@ -317,6 +339,12 @@
     gen_set_label(label2);
 }
 
+static inline void gen_store_flags(uint32_t flags)
+{
+    tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
+    tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
+}
+
 #define B3_0 (ctx->opcode & 0xf)
 #define B6_4 ((ctx->opcode >> 4) & 0x7)
 #define B7_4 ((ctx->opcode >> 4) & 0xf)
@@ -353,7 +381,8 @@
        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
        return;
     case 0x000b:               /* rts */
-       CHECK_NOT_DELAY_SLOT gen_op_rts();
+       CHECK_NOT_DELAY_SLOT
+       tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
        ctx->flags |= DELAY_SLOT;
        ctx->delayed_pc = (uint32_t) - 1;
        return;
@@ -375,7 +404,9 @@
 #endif
        return;
     case 0x002b:               /* rte */
-       CHECK_NOT_DELAY_SLOT gen_op_rte();
+       CHECK_NOT_DELAY_SLOT
+       tcg_gen_mov_i32(cpu_sr, cpu_ssr);
+       tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
        ctx->flags |= DELAY_SLOT;
        ctx->delayed_pc = (uint32_t) - 1;
        return;
@@ -436,13 +467,15 @@
        return;
     case 0xa000:               /* bra disp */
        CHECK_NOT_DELAY_SLOT
-           gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
+       ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
+       tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
        ctx->flags |= DELAY_SLOT;
        return;
     case 0xb000:               /* bsr disp */
        CHECK_NOT_DELAY_SLOT
-           gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
-                      ctx->pc + 4 + B11_0s * 2);
+       tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
+       ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
+       tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
        ctx->flags |= DELAY_SLOT;
        return;
     }
@@ -930,7 +963,7 @@
        return;
     case 0x8f00:               /* bf/s label */
        CHECK_NOT_DELAY_SLOT
-           gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
+       gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
        return;
     case 0x8900:               /* bt label */
@@ -941,7 +974,7 @@
        return;
     case 0x8d00:               /* bt/s label */
        CHECK_NOT_DELAY_SLOT
-           gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
+       gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
        return;
     case 0x8800:               /* cmp/eq #imm,R0 */
@@ -1083,13 +1116,14 @@
     switch (ctx->opcode & 0xf0ff) {
     case 0x0023:               /* braf Rn */
        CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
-       gen_op_braf_T0(ctx->pc + 4);
+       tcg_gen_addi_i32(cpu_delayed_pc, cpu_T[0], ctx->pc + 4);
        ctx->flags |= DELAY_SLOT;
        ctx->delayed_pc = (uint32_t) - 1;
        return;
     case 0x0003:               /* bsrf Rn */
        CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
-       gen_op_bsrf_T0(ctx->pc + 4);
+       tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
+       tcg_gen_add_i32(cpu_delayed_pc, cpu_T[0], cpu_pr);
        ctx->flags |= DELAY_SLOT;
        ctx->delayed_pc = (uint32_t) - 1;
        return;
@@ -1107,13 +1141,14 @@
        return;
     case 0x402b:               /* jmp @Rn */
        CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
-       gen_op_jmp_T0();
+       tcg_gen_mov_i32(cpu_delayed_pc, cpu_T[0]);
        ctx->flags |= DELAY_SLOT;
        ctx->delayed_pc = (uint32_t) - 1;
        return;
     case 0x400b:               /* jsr @Rn */
        CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
-       gen_op_jsr_T0(ctx->pc + 4);
+       tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
+       tcg_gen_mov_i32(cpu_delayed_pc, cpu_T[0]);
        ctx->flags |= DELAY_SLOT;
        ctx->delayed_pc = (uint32_t) - 1;
        return;
@@ -1332,12 +1367,12 @@
 
     if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
         if (ctx->flags & DELAY_SLOT_CLEARME) {
-            gen_op_store_flags(0);
+            gen_store_flags(0);
         } else {
            /* go out of the delay slot */
            uint32_t new_flags = ctx->flags;
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
-           gen_op_store_flags(new_flags);
+           gen_store_flags(new_flags);
         }
         ctx->flags = 0;
         ctx->bstate = BS_BRANCH;
@@ -1351,7 +1386,7 @@
 
     /* go into a delay slot */
     if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
-        gen_op_store_flags(ctx->flags);
+        gen_store_flags(ctx->flags);
 }
 
 static inline void
@@ -1448,7 +1483,7 @@
             /* fall through */
         case BS_NONE:
             if (ctx.flags) {
-                gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
+                gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
            }
             gen_goto_tb(&ctx, 0, ctx.pc);
             break;






reply via email to

[Prev in Thread] Current Thread [Next in Thread]