summaryrefslogtreecommitdiff
path: root/target-alpha
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 /target-alpha
parent73651cce62738f7f8732028a7b84f3484511eede (diff)
downloadqemu-ab471ade02d6bd3f82473a0560d76dd20c91cbb5.tar.gz
qemu-ab471ade02d6bd3f82473a0560d76dd20c91cbb5.tar.bz2
qemu-ab471ade02d6bd3f82473a0560d76dd20c91cbb5.zip
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>
Diffstat (limited to 'target-alpha')
-rw-r--r--target-alpha/translate.c39
1 files changed, 29 insertions, 10 deletions
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;