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>
This commit is contained in:
Richard Henderson 2009-12-11 09:38:23 -08:00 committed by Aurelien Jarno
parent 73651cce62
commit ab471ade02
2 changed files with 34 additions and 16 deletions

View File

@ -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);

View File

@ -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;