qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Nathan Froyd <froydnj@codesourcery.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 07/11] target-mips: split out delay slot handling
Date: Mon, 23 Nov 2009 12:50:05 -0800	[thread overview]
Message-ID: <1259009409-2755-8-git-send-email-froydnj@codesourcery.com> (raw)
In-Reply-To: <1259009409-2755-1-git-send-email-froydnj@codesourcery.com>

Move delay slot handling to common code whose invocation can be
controlled from gen_intermediate_code_internal.

Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
---
 target-mips/translate.c |  134 +++++++++++++++++++++++++++-------------------
 1 files changed, 79 insertions(+), 55 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index fece3c1..e7aee33 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -7548,6 +7548,56 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
                fregnames[fs], fregnames[ft]);
 }
 
+static void handle_delay_slot (CPUState *env, DisasContext *ctx,
+                               int insn_bytes)
+{
+    if (ctx->hflags & MIPS_HFLAG_BMASK) {
+        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
+        /* Branches completion */
+        ctx->hflags &= ~MIPS_HFLAG_BMASK;
+        ctx->bstate = BS_BRANCH;
+        save_cpu_state(ctx, 0);
+        /* FIXME: Need to clear can_do_io.  */
+        switch (hflags) {
+        case MIPS_HFLAG_B:
+            /* unconditional branch */
+            MIPS_DEBUG("unconditional branch");
+            gen_goto_tb(ctx, 0, ctx->btarget);
+            break;
+        case MIPS_HFLAG_BL:
+            /* blikely taken case */
+            MIPS_DEBUG("blikely branch taken");
+            gen_goto_tb(ctx, 0, ctx->btarget);
+            break;
+        case MIPS_HFLAG_BC:
+            /* Conditional branch */
+            MIPS_DEBUG("conditional branch");
+            {
+                int l1 = gen_new_label();
+
+                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
+                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
+                gen_set_label(l1);
+                gen_goto_tb(ctx, 0, ctx->btarget);
+            }
+            break;
+        case MIPS_HFLAG_BR:
+            /* unconditional branch to register */
+            MIPS_DEBUG("branch to register");
+            tcg_gen_mov_tl(cpu_PC, btarget);
+            if (ctx->singlestep_enabled) {
+                save_cpu_state(ctx, 0);
+                gen_helper_0i(raise_exception, EXCP_DEBUG);
+            }
+            tcg_gen_exit_tb(0);
+            break;
+        default:
+            MIPS_DEBUG("unknown branch");
+            break;
+        }
+    }
+}
+
 /* ISA extensions (ASEs) */
 /* MIPS16 extension to MIPS32 */
 /* SmartMIPS extension to MIPS32 */
@@ -7558,7 +7608,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
 
 #endif
 
-static void decode_opc (CPUState *env, DisasContext *ctx)
+static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
 {
     int32_t offset;
     int rs, rt, rd, sa;
@@ -7573,7 +7623,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
     }
 
     /* Handle blikely not taken case */
-    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
+    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
         int l1 = gen_new_label();
 
         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
@@ -7664,7 +7714,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
             break;
         case OPC_JR ... OPC_JALR:
             gen_compute_branch(ctx, op1, 4, rs, rd, sa);
-            return;
+            *is_branch = 1;
+            break;
         case OPC_TGE ... OPC_TEQ: /* Traps */
         case OPC_TNE:
             gen_trap(ctx, op1, rs, rt, -1);
@@ -7953,7 +8004,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
         case OPC_BLTZAL ... OPC_BGEZALL:
             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
-            return;
+            *is_branch = 1;
+            break;
         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
         case OPC_TNEI:
             gen_trap(ctx, op1, rs, -1, imm);
@@ -8072,11 +8124,13 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
     case OPC_J ... OPC_JAL: /* Jump */
          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
          gen_compute_branch(ctx, op, 4, rs, rt, offset);
-         return;
+         *is_branch = 1;
+         break;
     case OPC_BEQ ... OPC_BGTZ: /* Branch */
     case OPC_BEQL ... OPC_BGTZL:
          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
-         return;
+         *is_branch = 1;
+         break;
     case OPC_LB ... OPC_LWR: /* Load and stores */
     case OPC_SB ... OPC_SW:
     case OPC_SWR:
@@ -8137,7 +8191,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
             case OPC_BC1:
                 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
                                     (rt >> 2) & 0x7, imm << 2);
-                return;
+                *is_branch = 1;
+                break;
             case OPC_S_FMT:
             case OPC_D_FMT:
             case OPC_W_FMT:
@@ -8242,51 +8297,6 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
         generate_exception(ctx, EXCP_RI);
         break;
     }
-    if (ctx->hflags & MIPS_HFLAG_BMASK) {
-        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
-        /* Branches completion */
-        ctx->hflags &= ~MIPS_HFLAG_BMASK;
-        ctx->bstate = BS_BRANCH;
-        save_cpu_state(ctx, 0);
-        /* FIXME: Need to clear can_do_io.  */
-        switch (hflags) {
-        case MIPS_HFLAG_B:
-            /* unconditional branch */
-            MIPS_DEBUG("unconditional branch");
-            gen_goto_tb(ctx, 0, ctx->btarget);
-            break;
-        case MIPS_HFLAG_BL:
-            /* blikely taken case */
-            MIPS_DEBUG("blikely branch taken");
-            gen_goto_tb(ctx, 0, ctx->btarget);
-            break;
-        case MIPS_HFLAG_BC:
-            /* Conditional branch */
-            MIPS_DEBUG("conditional branch");
-            {
-                int l1 = gen_new_label();
-
-                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
-                gen_goto_tb(ctx, 1, ctx->pc + 4);
-                gen_set_label(l1);
-                gen_goto_tb(ctx, 0, ctx->btarget);
-            }
-            break;
-        case MIPS_HFLAG_BR:
-            /* unconditional branch to register */
-            MIPS_DEBUG("branch to register");
-            tcg_gen_mov_tl(cpu_PC, btarget);
-            if (ctx->singlestep_enabled) {
-                save_cpu_state(ctx, 0);
-                gen_helper_0i(raise_exception, EXCP_DEBUG);
-            }
-            tcg_gen_exit_tb(0);
-            break;
-        default:
-            MIPS_DEBUG("unknown branch");
-            break;
-        }
-    }
 }
 
 static inline void
@@ -8300,6 +8310,8 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
     int j, lj = -1;
     int num_insns;
     int max_insns;
+    int insn_bytes;
+    int is_branch;
 
     if (search_pc)
         qemu_log("search pc %d\n", search_pc);
@@ -8360,9 +8372,21 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
-        ctx.opcode = ldl_code(ctx.pc);
-        decode_opc(env, &ctx);
-        ctx.pc += 4;
+
+        is_branch = 0;
+        if (ctx.isa_mode == 0) {
+            ctx.opcode = ldl_code(ctx.pc);
+            insn_bytes = 4;
+            decode_opc(env, &ctx, &is_branch);
+        } else {
+            generate_exception(&ctx, EXCP_RI);
+            break;
+        }
+        if (!is_branch) {
+            handle_delay_slot(env, &ctx, insn_bytes);
+        }
+        ctx.pc += insn_bytes;
+
         num_insns++;
 
         /* Execute a branch and its delay slot as a single instruction.
-- 
1.6.3.2

  parent reply	other threads:[~2009-11-23 20:57 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-23 20:49 [Qemu-devel] [PATCH 00/11] target-mips: add mips16 support Nathan Froyd
2009-11-23 20:49 ` [Qemu-devel] [PATCH 01/11] target-mips: add ISAMode bits for mips16 execution Nathan Froyd
2009-11-28 10:17   ` Aurelien Jarno
2009-11-30 17:45     ` Aurelien Jarno
2009-11-23 20:50 ` [Qemu-devel] [PATCH 02/11] target-mips: add new HFLAGs for JALX and 16/32-bit delay slots Nathan Froyd
2009-11-23 20:50 ` [Qemu-devel] [PATCH 03/11] target-mips: change interrupt bits to be mips16-aware Nathan Froyd
2009-11-28 10:17   ` Aurelien Jarno
2009-11-23 20:50 ` [Qemu-devel] [PATCH 04/11] target-mips: move ROTR and ROTRV inside gen_shift_{imm, } Nathan Froyd
2009-11-23 20:50 ` [Qemu-devel] [PATCH 05/11] target-mips: make gen_compute_branch 16/32-bit-aware Nathan Froyd
2009-11-23 20:50 ` [Qemu-devel] [PATCH 06/11] target-mips: add gen_base_offset_addr Nathan Froyd
2009-11-28 10:17   ` Aurelien Jarno
2009-11-23 20:50 ` Nathan Froyd [this message]
2009-11-23 20:50 ` [Qemu-devel] [PATCH 08/11] target-mips: add enums for MIPS16 opcodes Nathan Froyd
2009-11-23 20:50 ` [Qemu-devel] [PATCH 09/11] target-mips: add mips16 instruction decoding Nathan Froyd
2009-11-28 10:17   ` Aurelien Jarno
2009-11-23 20:50 ` [Qemu-devel] [PATCH 10/11] gdbstub: add MIPS16 support Nathan Froyd
2009-11-23 20:50 ` [Qemu-devel] [PATCH 11/11] target-mips: add copyright notice for mips16 work Nathan Froyd
2009-11-28 10:17 ` [Qemu-devel] [PATCH 00/11] target-mips: add mips16 support Aurelien Jarno

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=1259009409-2755-8-git-send-email-froydnj@codesourcery.com \
    --to=froydnj@codesourcery.com \
    --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).