Skip to content

Commit

Permalink
target-sh4: rework exceptions handling
Browse files Browse the repository at this point in the history
Since commit fd4bab1 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 <aurelien@aurel32.net>
  • Loading branch information
aurel32 committed Sep 21, 2012
1 parent ed22e6f commit 1012740
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 30 deletions.
14 changes: 7 additions & 7 deletions 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)
Expand Down
30 changes: 13 additions & 17 deletions target-sh4/op_helper.c
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
18 changes: 12 additions & 6 deletions target-sh4/translate.c
Expand Up @@ -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; \
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
}
Expand Down

0 comments on commit 1012740

Please sign in to comment.