From patchwork Sun Sep 16 23:11:57 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 184264 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 48CEB2C007E for ; Mon, 17 Sep 2012 09:46:21 +1000 (EST) Received: from localhost ([::1]:41148 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TDO1I-00030P-FA for incoming@patchwork.ozlabs.org; Sun, 16 Sep 2012 19:12:56 -0400 Received: from eggs.gnu.org ([208.118.235.92]:52693) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TDO0U-0000x6-QR for qemu-devel@nongnu.org; Sun, 16 Sep 2012 19:12:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TDO0S-0008Ay-3r for qemu-devel@nongnu.org; Sun, 16 Sep 2012 19:12:06 -0400 Received: from hall.aurel32.net ([88.191.126.93]:47764) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TDO0R-00089u-Qp for qemu-devel@nongnu.org; Sun, 16 Sep 2012 19:12:04 -0400 Received: from [2001:470:d4ed:0:ea11:32ff:fea1:831a] (helo=ohm.aurel32.net) by hall.aurel32.net with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1TDO0Q-0006U8-Hx; Mon, 17 Sep 2012 01:12:03 +0200 Received: from aurel32 by ohm.aurel32.net with local (Exim 4.80) (envelope-from ) id 1TDO0P-0003nT-Vd; Mon, 17 Sep 2012 01:12:01 +0200 From: Aurelien Jarno To: qemu-devel@nongnu.org Date: Mon, 17 Sep 2012 01:11:57 +0200 Message-Id: <1347837120-14422-9-git-send-email-aurelien@aurel32.net> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1347837120-14422-1-git-send-email-aurelien@aurel32.net> References: <1347837120-14422-1-git-send-email-aurelien@aurel32.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 88.191.126.93 Cc: Aurelien Jarno Subject: [Qemu-devel] [PATCH 08/11] target-sh4: rework exceptions handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Since commit fd4bab102 PC is restored in case of exception through code retranslation. While it is clearly the thing to do in case it is not not known if an helper is going to trigger an exception or not (e.g. for load/store, FPU, etc.), it just make things slower when the exception is already known at translation time. Partially revert this commit and save PC in the TCG code. Set bstate to BS_BRANCH to not generate TCG exit code. Micro-optimize the sleep helper. Make all the exception helpers to call raise_exception and mark it as noreturn. Signed-off-by: Aurelien Jarno --- target-sh4/helper.h | 14 +++++++------- target-sh4/op_helper.c | 30 +++++++++++++----------------- target-sh4/translate.c | 18 ++++++++++++------ 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/target-sh4/helper.h b/target-sh4/helper.h index a00b7dd..6c1a47d 100644 --- a/target-sh4/helper.h +++ b/target-sh4/helper.h @@ -1,13 +1,13 @@ #include "def-helper.h" DEF_HELPER_1(ldtlb, void, env) -DEF_HELPER_1(raise_illegal_instruction, void, env) -DEF_HELPER_1(raise_slot_illegal_instruction, void, env) -DEF_HELPER_1(raise_fpu_disable, void, env) -DEF_HELPER_1(raise_slot_fpu_disable, void, env) -DEF_HELPER_1(debug, void, env) -DEF_HELPER_2(sleep, void, env, i32) -DEF_HELPER_2(trapa, void, env, i32) +DEF_HELPER_1(raise_illegal_instruction, noreturn, env) +DEF_HELPER_1(raise_slot_illegal_instruction, noreturn, env) +DEF_HELPER_1(raise_fpu_disable, noreturn, env) +DEF_HELPER_1(raise_slot_fpu_disable, noreturn, env) +DEF_HELPER_1(debug, noreturn, env) +DEF_HELPER_1(sleep, noreturn, env) +DEF_HELPER_2(trapa, noreturn, env, i32) DEF_HELPER_3(movcal, void, env, i32, i32) DEF_HELPER_1(discard_movcal_backup, void, env) diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c index 4f1f754..60ec4cb 100644 --- a/target-sh4/op_helper.c +++ b/target-sh4/op_helper.c @@ -21,7 +21,8 @@ #include "cpu.h" #include "helper.h" -static void cpu_restore_state_from_retaddr(CPUSH4State *env, uintptr_t retaddr) +static inline void cpu_restore_state_from_retaddr(CPUSH4State *env, + uintptr_t retaddr) { TranslationBlock *tb; @@ -77,8 +78,8 @@ void helper_ldtlb(CPUSH4State *env) #endif } -static inline void raise_exception(CPUSH4State *env, int index, - uintptr_t retaddr) +static inline void QEMU_NORETURN raise_exception(CPUSH4State *env, int index, + uintptr_t retaddr) { env->exception_index = index; cpu_restore_state_from_retaddr(env, retaddr); @@ -87,43 +88,40 @@ static inline void raise_exception(CPUSH4State *env, int index, void helper_raise_illegal_instruction(CPUSH4State *env) { - raise_exception(env, 0x180, GETPC()); + raise_exception(env, 0x180, 0); } void helper_raise_slot_illegal_instruction(CPUSH4State *env) { - raise_exception(env, 0x1a0, GETPC()); + raise_exception(env, 0x1a0, 0); } void helper_raise_fpu_disable(CPUSH4State *env) { - raise_exception(env, 0x800, GETPC()); + raise_exception(env, 0x800, 0); } void helper_raise_slot_fpu_disable(CPUSH4State *env) { - raise_exception(env, 0x820, GETPC()); + raise_exception(env, 0x820, 0); } void helper_debug(CPUSH4State *env) { - env->exception_index = EXCP_DEBUG; - cpu_loop_exit(env); + raise_exception(env, EXCP_DEBUG, 0); } -void helper_sleep(CPUSH4State *env, uint32_t next_pc) +void helper_sleep(CPUSH4State *env) { env->halted = 1; env->in_sleep = 1; - env->exception_index = EXCP_HLT; - env->pc = next_pc; - cpu_loop_exit(env); + raise_exception(env, EXCP_HLT, 0); } void helper_trapa(CPUSH4State *env, uint32_t tra) { env->tra = tra << 2; - raise_exception(env, 0x160, GETPC()); + raise_exception(env, 0x160, 0); } void helper_movcal(CPUSH4State *env, uint32_t address, uint32_t value) @@ -385,9 +383,7 @@ static void update_fpscr(CPUSH4State *env, uintptr_t retaddr) cause = (env->fpscr & FPSCR_CAUSE_MASK) >> FPSCR_CAUSE_SHIFT; enable = (env->fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT; if (cause & enable) { - cpu_restore_state_from_retaddr(env, retaddr); - env->exception_index = 0x120; - cpu_loop_exit(env); + raise_exception(env, 0x120, retaddr); } } } diff --git a/target-sh4/translate.c b/target-sh4/translate.c index cdc4e3b..6305db8 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -427,30 +427,33 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg) #define CHECK_NOT_DELAY_SLOT \ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \ { \ + tcg_gen_movi_i32(cpu_pc, ctx->pc); \ gen_helper_raise_slot_illegal_instruction(cpu_env); \ - ctx->bstate = BS_EXCP; \ + ctx->bstate = BS_BRANCH; \ return; \ } #define CHECK_PRIVILEGED \ if (IS_USER(ctx)) { \ + tcg_gen_movi_i32(cpu_pc, ctx->pc); \ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \ gen_helper_raise_slot_illegal_instruction(cpu_env); \ } else { \ gen_helper_raise_illegal_instruction(cpu_env); \ } \ - ctx->bstate = BS_EXCP; \ + ctx->bstate = BS_BRANCH; \ return; \ } #define CHECK_FPU_ENABLED \ if (ctx->flags & SR_FD) { \ + tcg_gen_movi_i32(cpu_pc, ctx->pc); \ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \ gen_helper_raise_slot_fpu_disable(cpu_env); \ } else { \ gen_helper_raise_fpu_disable(cpu_env); \ } \ - ctx->bstate = BS_EXCP; \ + ctx->bstate = BS_BRANCH; \ return; \ } @@ -541,7 +544,8 @@ static void _decode_opc(DisasContext * ctx) return; case 0x001b: /* sleep */ CHECK_PRIVILEGED - gen_helper_sleep(cpu_env, tcg_const_i32(ctx->pc + 2)); + tcg_gen_movi_i32(cpu_pc, ctx->pc + 2); + gen_helper_sleep(cpu_env); return; } @@ -1411,6 +1415,7 @@ static void _decode_opc(DisasContext * ctx) { TCGv imm; CHECK_NOT_DELAY_SLOT + tcg_gen_movi_i32(cpu_pc, ctx->pc); imm = tcg_const_i32(B7_0); gen_helper_trapa(cpu_env, imm); tcg_temp_free(imm); @@ -1909,12 +1914,13 @@ static void _decode_opc(DisasContext * ctx) ctx->opcode, ctx->pc); fflush(stderr); #endif + tcg_gen_movi_i32(cpu_pc, ctx->pc); if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { gen_helper_raise_slot_illegal_instruction(cpu_env); } else { gen_helper_raise_illegal_instruction(cpu_env); } - ctx->bstate = BS_EXCP; + ctx->bstate = BS_BRANCH; } static void decode_opc(DisasContext * ctx) @@ -1992,7 +1998,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb, /* We have hit a breakpoint - make sure PC is up-to-date */ tcg_gen_movi_i32(cpu_pc, ctx.pc); gen_helper_debug(cpu_env); - ctx.bstate = BS_EXCP; + ctx.bstate = BS_BRANCH; break; } }