qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Aurelien Jarno <aurelien@aurel32.net>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [5111] SH4: convert branch/jump instructions to TCG
Date: Fri, 29 Aug 2008 22:32:32 +0000	[thread overview]
Message-ID: <E1KZCW8-0003Rv-Ta@cvs.savannah.gnu.org> (raw)

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	other threads:[~2008-08-29 22:32 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1KZCW8-0003Rv-Ta@cvs.savannah.gnu.org \
    --to=aurelien@aurel32.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).