From patchwork Tue Dec 8 16:06:27 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Froyd X-Patchwork-Id: 40676 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C4302B6F10 for ; Wed, 9 Dec 2009 08:57:53 +1100 (EST) Received: from localhost ([127.0.0.1]:60606 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NI845-0007dJ-AP for incoming@patchwork.ozlabs.org; Tue, 08 Dec 2009 16:57:49 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NI83S-0007Zu-OD for qemu-devel@nongnu.org; Tue, 08 Dec 2009 16:57:10 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NI83O-0007T4-Jy for qemu-devel@nongnu.org; Tue, 08 Dec 2009 16:57:10 -0500 Received: from [199.232.76.173] (port=45284 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NI83O-0007SX-8A for qemu-devel@nongnu.org; Tue, 08 Dec 2009 16:57:06 -0500 Received: from mx20.gnu.org ([199.232.41.8]:4543) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1NI83N-0007DS-Qy for qemu-devel@nongnu.org; Tue, 08 Dec 2009 16:57:05 -0500 Received: from mail.codesourcery.com ([38.113.113.100]) by mx20.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NI83M-000168-I7 for qemu-devel@nongnu.org; Tue, 08 Dec 2009 16:57:05 -0500 Received: (qmail 32154 invoked from network); 8 Dec 2009 16:06:36 -0000 Received: from unknown (HELO localhost) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 8 Dec 2009 16:06:36 -0000 From: Nathan Froyd To: qemu-devel@nongnu.org Date: Tue, 8 Dec 2009 08:06:27 -0800 Message-Id: <1260288392-20804-7-git-send-email-froydnj@codesourcery.com> X-Mailer: git-send-email 1.6.3.2 In-Reply-To: <1260288392-20804-1-git-send-email-froydnj@codesourcery.com> References: <1260288392-20804-1-git-send-email-froydnj@codesourcery.com> X-detected-operating-system: by mx20.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Subject: [Qemu-devel] [PATCH 06/11] target-mips: split out delay slot handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Move delay slot handling to common code whose invocation can be controlled from gen_intermediate_code_internal. Signed-off-by: Nathan Froyd --- 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 b38b97f..36bfdeb 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -7532,6 +7532,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 */ @@ -7542,7 +7592,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; @@ -7557,7 +7607,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); @@ -7648,7 +7698,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); @@ -7937,7 +7988,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); @@ -8056,11 +8108,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: @@ -8121,7 +8175,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: @@ -8226,51 +8281,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 @@ -8284,6 +8294,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); @@ -8343,9 +8355,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.