All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Sandiford <rdsandiford@googlemail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] Honour current_tc for MIPS M{T,F}{HI,LO}
Date: Sun, 25 May 2008 10:43:35 +0100	[thread overview]
Message-ID: <87skw667nc.fsf@firetop.home> (raw)

I noticed while working on something else that the MIPS muldiv code
is careful to store in {HI,LO}[current_tc] but that the M{F,T}{HI,LO}
code always uses {HI,LO}[0].  I realise we don't really support MT yet,
but I thought I might as well have a stab at "fixing" it.

Following the current use of "current_tc_gprs", the patch introduces
a new TCG global, "current_tc_hi", to point at the current thread
context's HI array.  This is good for accessing LO as well,
and could be used for ACX in future.

HI and LO accesses are now more complicated than they were
when the gen_{load,store}_{HI,LO} accessor functions were removed,
so I've added them back.  I also added an accumulator register
parameter, ready for any future DSP support.

This might well not seem like the right approach, or it might
interfere with a longer-term plan.  If so, I apologise; please
feel free to ignore. ;)

Richard


Index: qemu/target-mips/cpu.h
===================================================================
--- qemu.orig/target-mips/cpu.h	2008-05-25 09:54:30.000000000 +0100
+++ qemu/target-mips/cpu.h	2008-05-25 09:56:19.000000000 +0100
@@ -159,6 +159,7 @@ struct CPUMIPSState {
     CPUMIPSFPUContext *fpu;
     uint32_t current_tc;
     target_ulong *current_tc_gprs;
+    target_ulong *current_tc_hi;
 
     uint32_t SEGBITS;
     target_ulong SEGMask;
Index: qemu/target-mips/translate.c
===================================================================
--- qemu.orig/target-mips/translate.c	2008-05-25 09:54:30.000000000 +0100
+++ qemu/target-mips/translate.c	2008-05-25 09:57:00.000000000 +0100
@@ -524,7 +524,7 @@ enum {
 };
 
 /* global register indices */
-static TCGv cpu_env, current_tc_gprs, cpu_T[2];
+static TCGv cpu_env, current_tc_gprs, current_tc_hi, cpu_T[2];
 
 /* The code generator doesn't like lots of temporaries, so maintain our own
    cache for reuse within a function.  */
@@ -633,6 +633,33 @@ static inline void gen_store_gpr (TCGv t
         tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
 }
 
+/* Moves to/from HI and LO registers.  */
+static inline void gen_load_LO (TCGv t, int reg)
+{
+    tcg_gen_ld_tl(t, current_tc_hi,
+                  offsetof(CPUState, LO)
+                  - offsetof(CPUState, HI)
+                  + sizeof(target_ulong) * reg);
+}
+
+static inline void gen_store_LO (TCGv t, int reg)
+{
+    tcg_gen_st_tl(t, current_tc_hi,
+                  offsetof(CPUState, LO)
+                  - offsetof(CPUState, HI)
+                  + sizeof(target_ulong) * reg);
+}
+
+static inline void gen_load_HI (TCGv t, int reg)
+{
+    tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
+}
+
+static inline void gen_store_HI (TCGv t, int reg)
+{
+    tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
+}
+
 /* Moves to/from shadow registers. */
 static inline void gen_load_srsgpr (TCGv t, int reg)
 {
@@ -1917,23 +1944,23 @@ static void gen_HILO (DisasContext *ctx,
     }
     switch (opc) {
     case OPC_MFHI:
-        tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[0]));
+        gen_load_HI(cpu_T[0], 0);
         gen_store_gpr(cpu_T[0], reg);
         opn = "mfhi";
         break;
     case OPC_MFLO:
-        tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[0]));
+        gen_load_LO(cpu_T[0], 0);
         gen_store_gpr(cpu_T[0], reg);
         opn = "mflo";
         break;
     case OPC_MTHI:
         gen_load_gpr(cpu_T[0], reg);
-        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[0]));
+        gen_store_HI(cpu_T[0], 0);
         opn = "mthi";
         break;
     case OPC_MTLO:
         gen_load_gpr(cpu_T[0], reg);
-        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[0]));
+        gen_store_LO(cpu_T[0], 0);
         opn = "mtlo";
         break;
     default:
@@ -1961,9 +1988,6 @@ static void gen_muldiv (DisasContext *ct
                 TCGv r_tmp1 = new_tmp();
                 TCGv r_tmp2 = new_tmp();
                 TCGv r_tmp3 = new_tmp();
-                TCGv r_tc_off = new_tmp();
-                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
-                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
 
                 tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
                 tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
@@ -1971,16 +1995,11 @@ static void gen_muldiv (DisasContext *ct
                 tcg_gen_rem_i32(r_tmp1, r_tmp1, r_tmp2);
                 tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
                 tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
+                gen_store_LO(cpu_T[0], 0);
+                gen_store_HI(cpu_T[1], 0);
                 dead_tmp(r_tmp1);
                 dead_tmp(r_tmp2);
                 dead_tmp(r_tmp3);
-                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
-                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
-                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
-                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
-                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
-                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
-                dead_tmp(r_tc_off);
             }
             gen_set_label(l1);
         }
@@ -1995,9 +2014,6 @@ static void gen_muldiv (DisasContext *ct
                 TCGv r_tmp1 = new_tmp();
                 TCGv r_tmp2 = new_tmp();
                 TCGv r_tmp3 = new_tmp();
-                TCGv r_tc_off = new_tmp();
-                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
-                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
 
                 tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
                 tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
@@ -2005,16 +2021,11 @@ static void gen_muldiv (DisasContext *ct
                 tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
                 tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
                 tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
+                gen_store_LO(cpu_T[0], 0);
+                gen_store_HI(cpu_T[1], 0);
                 dead_tmp(r_tmp1);
                 dead_tmp(r_tmp2);
                 dead_tmp(r_tmp3);
-                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
-                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
-                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
-                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
-                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
-                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
-                dead_tmp(r_tc_off);
             }
             gen_set_label(l1);
         }
@@ -2035,9 +2046,6 @@ static void gen_muldiv (DisasContext *ct
 
             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
             {
-                TCGv r_tc_off = new_tmp();
-                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
-                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
                 int l2 = gen_new_label();
                 int l3 = gen_new_label();
 
@@ -2051,13 +2059,8 @@ static void gen_muldiv (DisasContext *ct
                 tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]);
                 gen_set_label(l3);
 
-                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
-                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
-                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
-                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
-                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
-                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
-                dead_tmp(r_tc_off);
+                gen_store_LO(cpu_T[0], 0);
+                gen_store_HI(cpu_T[1], 0);
             }
             gen_set_label(l1);
         }
@@ -2071,19 +2074,11 @@ static void gen_muldiv (DisasContext *ct
             {
                 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
                 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
-                TCGv r_tc_off = new_tmp();
-                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
-                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
 
                 tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
                 tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
-                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
-                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
-                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
-                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
-                tcg_gen_st_tl(r_tmp1, r_ptr, offsetof(CPUState, LO));
-                tcg_gen_st_tl(r_tmp2, r_ptr, offsetof(CPUState, HI));
-                dead_tmp(r_tc_off);
+                gen_store_LO(r_tmp1, 0);
+                gen_store_HI(r_tmp2, 0);
             }
             gen_set_label(l1);
         }
@@ -8432,6 +8427,10 @@ static void mips_tcg_init(void)
                                          TCG_AREG0,
                                          offsetof(CPUState, current_tc_gprs),
                                          "current_tc_gprs");
+    current_tc_hi = tcg_global_mem_new(TCG_TYPE_PTR,
+                                       TCG_AREG0,
+                                       offsetof(CPUState, current_tc_hi),
+                                       "current_tc_hi");
 #if TARGET_LONG_BITS > HOST_LONG_BITS
     cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
                                   TCG_AREG0, offsetof(CPUState, t0), "T0");
Index: qemu/target-mips/translate_init.c
===================================================================
--- qemu.orig/target-mips/translate_init.c	2008-05-25 09:54:30.000000000 +0100
+++ qemu/target-mips/translate_init.c	2008-05-25 09:56:19.000000000 +0100
@@ -547,6 +547,7 @@ static int cpu_mips_register (CPUMIPSSta
     env->CP0_SRSCtl = def->CP0_SRSCtl;
     env->current_tc = 0;
     env->current_tc_gprs = &env->gpr[env->current_tc][0];
+    env->current_tc_hi = &env->HI[env->current_tc][0];
     env->SEGBITS = def->SEGBITS;
     env->SEGMask = (target_ulong)((1ULL << def->SEGBITS) - 1);
 #if defined(TARGET_MIPS64)

                 reply	other threads:[~2008-05-25  9:43 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87skw667nc.fsf@firetop.home \
    --to=rdsandiford@googlemail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.