diff options
author | Richard Henderson <rth@twiddle.net> | 2009-12-11 09:38:23 -0800 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2009-12-13 21:36:16 +0100 |
commit | ab471ade02d6bd3f82473a0560d76dd20c91cbb5 (patch) | |
tree | a1d9bb22df72ed454264dbc0c2451e1ca214a458 | |
parent | 73651cce62738f7f8732028a7b84f3484511eede (diff) |
target-alpha: Implement RD/WRUNIQUE in the translator
When emulating user-mode only, there's no reason to exit
the translation block to effect a call_pal. We can generate
a move to/from the unique slot directly.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r-- | hw/alpha_palcode.c | 11 | ||||
-rw-r--r-- | target-alpha/translate.c | 39 |
2 files changed, 34 insertions, 16 deletions
diff --git a/hw/alpha_palcode.c b/hw/alpha_palcode.c index c48a2976b5..edec01815a 100644 --- a/hw/alpha_palcode.c +++ b/hw/alpha_palcode.c @@ -1060,7 +1060,6 @@ void call_pal (CPUState *env, int palcode) { target_long ret; - qemu_log("%s: palcode %02x\n", __func__, palcode); switch (palcode) { case 0x83: /* CALLSYS */ @@ -1078,14 +1077,14 @@ void call_pal (CPUState *env, int palcode) break; case 0x9E: /* RDUNIQUE */ - env->ir[IR_V0] = env->unique; qemu_log("RDUNIQUE: " TARGET_FMT_lx "\n", env->unique); - break; + /* Handled in the translator for usermode. */ + abort(); case 0x9F: /* WRUNIQUE */ - env->unique = env->ir[IR_A0]; - qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->unique); - break; + qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->ir[IR_A0]); + /* Handled in the translator for usermode. */ + abort(); default: qemu_log("%s: unhandled palcode %02x\n", __func__, palcode); diff --git a/target-alpha/translate.c b/target-alpha/translate.c index fbcedde3ea..5c08923bfc 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -57,6 +57,9 @@ static TCGv cpu_ir[31]; static TCGv cpu_fir[31]; static TCGv cpu_pc; static TCGv cpu_lock; +#ifdef CONFIG_USER_ONLY +static TCGv cpu_uniq; +#endif /* register names */ static char cpu_reg_names[10*4+21*5 + 10*5+21*6]; @@ -93,6 +96,11 @@ static void alpha_translate_init(void) cpu_lock = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, lock), "lock"); +#ifdef CONFIG_USER_ONLY + cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0, + offsetof(CPUState, unique), "uniq"); +#endif + /* register helpers */ #define GEN_HELPER 2 #include "helper.h" @@ -751,23 +759,34 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn) switch (opc) { case 0x00: /* CALL_PAL */ +#ifdef CONFIG_USER_ONLY + if (palcode == 0x9E) { + /* RDUNIQUE */ + tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_uniq); + break; + } else if (palcode == 0x9F) { + /* WRUNIQUE */ + tcg_gen_mov_i64(cpu_uniq, cpu_ir[IR_A0]); + break; + } +#endif if (palcode >= 0x80 && palcode < 0xC0) { /* Unprivileged PAL call */ gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0); -#if !defined (CONFIG_USER_ONLY) - } else if (palcode < 0x40) { + ret = 3; + break; + } +#ifndef CONFIG_USER_ONLY + if (palcode < 0x40) { /* Privileged PAL code */ if (ctx->mem_idx & 1) goto invalid_opc; - else - gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0); -#endif - } else { - /* Invalid PAL call */ - goto invalid_opc; + gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0); + ret = 3; } - ret = 3; - break; +#endif + /* Invalid PAL call */ + goto invalid_opc; case 0x01: /* OPC01 */ goto invalid_opc; |