mirror of https://github.com/xemu-project/xemu.git
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:
parent
73651cce62
commit
ab471ade02
|
@ -1060,7 +1060,6 @@ void call_pal (CPUState *env, int palcode)
|
||||||
{
|
{
|
||||||
target_long ret;
|
target_long ret;
|
||||||
|
|
||||||
qemu_log("%s: palcode %02x\n", __func__, palcode);
|
|
||||||
switch (palcode) {
|
switch (palcode) {
|
||||||
case 0x83:
|
case 0x83:
|
||||||
/* CALLSYS */
|
/* CALLSYS */
|
||||||
|
@ -1078,14 +1077,14 @@ void call_pal (CPUState *env, int palcode)
|
||||||
break;
|
break;
|
||||||
case 0x9E:
|
case 0x9E:
|
||||||
/* RDUNIQUE */
|
/* RDUNIQUE */
|
||||||
env->ir[IR_V0] = env->unique;
|
|
||||||
qemu_log("RDUNIQUE: " TARGET_FMT_lx "\n", env->unique);
|
qemu_log("RDUNIQUE: " TARGET_FMT_lx "\n", env->unique);
|
||||||
break;
|
/* Handled in the translator for usermode. */
|
||||||
|
abort();
|
||||||
case 0x9F:
|
case 0x9F:
|
||||||
/* WRUNIQUE */
|
/* WRUNIQUE */
|
||||||
env->unique = env->ir[IR_A0];
|
qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
|
||||||
qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->unique);
|
/* Handled in the translator for usermode. */
|
||||||
break;
|
abort();
|
||||||
default:
|
default:
|
||||||
qemu_log("%s: unhandled palcode %02x\n",
|
qemu_log("%s: unhandled palcode %02x\n",
|
||||||
__func__, palcode);
|
__func__, palcode);
|
||||||
|
|
|
@ -57,6 +57,9 @@ static TCGv cpu_ir[31];
|
||||||
static TCGv cpu_fir[31];
|
static TCGv cpu_fir[31];
|
||||||
static TCGv cpu_pc;
|
static TCGv cpu_pc;
|
||||||
static TCGv cpu_lock;
|
static TCGv cpu_lock;
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
static TCGv cpu_uniq;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* register names */
|
/* register names */
|
||||||
static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
|
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,
|
cpu_lock = tcg_global_mem_new_i64(TCG_AREG0,
|
||||||
offsetof(CPUState, lock), "lock");
|
offsetof(CPUState, lock), "lock");
|
||||||
|
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0,
|
||||||
|
offsetof(CPUState, unique), "uniq");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* register helpers */
|
/* register helpers */
|
||||||
#define GEN_HELPER 2
|
#define GEN_HELPER 2
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
@ -751,23 +759,34 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
/* CALL_PAL */
|
/* 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) {
|
if (palcode >= 0x80 && palcode < 0xC0) {
|
||||||
/* Unprivileged PAL call */
|
/* Unprivileged PAL call */
|
||||||
gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
|
gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
|
||||||
#if !defined (CONFIG_USER_ONLY)
|
ret = 3;
|
||||||
} else if (palcode < 0x40) {
|
break;
|
||||||
|
}
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
if (palcode < 0x40) {
|
||||||
/* Privileged PAL code */
|
/* Privileged PAL code */
|
||||||
if (ctx->mem_idx & 1)
|
if (ctx->mem_idx & 1)
|
||||||
goto invalid_opc;
|
goto invalid_opc;
|
||||||
else
|
gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
|
||||||
gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
|
ret = 3;
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
/* Invalid PAL call */
|
|
||||||
goto invalid_opc;
|
|
||||||
}
|
}
|
||||||
ret = 3;
|
#endif
|
||||||
break;
|
/* Invalid PAL call */
|
||||||
|
goto invalid_opc;
|
||||||
case 0x01:
|
case 0x01:
|
||||||
/* OPC01 */
|
/* OPC01 */
|
||||||
goto invalid_opc;
|
goto invalid_opc;
|
||||||
|
|
Loading…
Reference in New Issue