aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2009-12-11 09:38:23 -0800
committerAurelien Jarno <aurelien@aurel32.net>2009-12-13 21:36:16 +0100
commitab471ade02d6bd3f82473a0560d76dd20c91cbb5 (patch)
treea1d9bb22df72ed454264dbc0c2451e1ca214a458
parent73651cce62738f7f8732028a7b84f3484511eede (diff)
downloadqemu-ab471ade02d6bd3f82473a0560d76dd20c91cbb5.zip
qemu-ab471ade02d6bd3f82473a0560d76dd20c91cbb5.tar.gz
qemu-ab471ade02d6bd3f82473a0560d76dd20c91cbb5.tar.bz2
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.c11
-rw-r--r--target-alpha/translate.c39
2 files changed, 34 insertions, 16 deletions
diff --git a/hw/alpha_palcode.c b/hw/alpha_palcode.c
index c48a297..edec018 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 fbcedde..5c08923 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;