Patchwork [06/13] alpha: Implement RD/WRUNIQUE in the translator

login
register
mail settings
Submitter Richard Henderson
Date Dec. 11, 2009, 5:38 p.m.
Message ID <bc17653bf6a420096496ac776504567a38cb3cdd.1260580414.git.rth@twiddle.net>
Download mbox | patch
Permalink /patch/40939/
State New
Headers show

Comments

Richard Henderson - Dec. 11, 2009, 5:38 p.m.
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>
---
 hw/alpha_palcode.c       |   11 +++++------
 target-alpha/translate.c |   39 +++++++++++++++++++++++++++++----------
 2 files changed, 34 insertions(+), 16 deletions(-)

Patch

diff --git a/hw/alpha_palcode.c b/hw/alpha_palcode.c
index 44b2ca4..4cc37fe 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 0x80:
         /* BPT */
@@ -1093,14 +1092,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 ();
     case 0xAA:
         /* GENTRAP */
         qemu_log("GENTRAP: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index cabf75a..b53737a 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;