qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Sparc32: Mask writes to the WIM register


From: Luis Pureza
Subject: Re: [Qemu-devel] Sparc32: Mask writes to the WIM register
Date: Wed, 20 Aug 2008 21:06:44 +0100

On Wed, Aug 20, 2008 at 4:30 PM, Blue Swirl <address@hidden> wrote:
> On 8/20/08, Luis Pureza <address@hidden> wrote:
>> OK, the following patch works for me:
>>
>>  ---
>>   target-sparc/translate.c |    7 +++++++
>>   1 files changed, 7 insertions(+), 0 deletions(-)
>>
>>  diff --git a/target-sparc/translate.c b/target-sparc/translate.c
>>  index 8286d36..02e497f 100644
>>
>> --- a/target-sparc/translate.c
>>  +++ b/target-sparc/translate.c
>>
>> @@ -73,6 +73,7 @@ typedef struct DisasContext {
>>      struct TranslationBlock *tb;
>>      uint32_t features;
>>      int extra_cpu_cycles;
>>  +    uint32_t wim_mask;
>>   } DisasContext;
>>
>>   // This function uses non-native bit order
>>  @@ -3485,6 +3486,7 @@ static void disas_sparc_insn(DisasContext * dc)
>>
>>                              }
>>   #else
>>                              tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
>>
>> +                            tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
>>  dc->wim_mask);
>>
>>                              tcg_gen_st_i32(cpu_tmp32, cpu_env,
>>                                             offsetof(CPUSPARCState, wim));
>>
>>  #endif
>>  @@ -4848,6 +4850,11 @@ static inline void
>>  gen_intermediate_code_internal(TranslationBlock * tb,
>>   #ifdef TARGET_SPARC64
>>      dc->address_mask_32bit = env->pstate & PS_AM;
>>   #endif
>>  +    if (env->nwindows == 32) {
>>  +        dc->wim_mask = 0xFFFFFFFF;
>>  +    } else {
>>  +        dc->wim_mask = (1 << env->nwindows) - 1;
>>  +    }
>>      gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
>>
>>      cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
>
> Thanks. But now every translation would be slowed down by a tiny
> amount because the wim mask is calculated, even if it will never be
> used. More optimally, the mask should be calculated as needed and only
> nwindows should be copied to dc.
>
> A more complex solution would be to avoid most of the copying
> entirely, so that env would have a pointer to sparc_def_t structure
> and dc could copy only this "def" pointer. Then instead of
> dc->features and dc->nwindows, dc->def->features and dc->def->nwindows
> would be used. This would be more useful in the future, if I add code
> to select the ASI helper at translation time.

Complex please. One of those "integration problems" I had was
precisely related to different ASI mappings.

The following patch tries to do what you said. I guess more stuff
could be removed from CPUSPARCState now that it has a pointer to a
sparc_def_t. But I leave that to your judgment. The only thing I
removed was "features".

Note that the wrwim fix is also included.

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 2574690..f9fa609 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -187,6 +187,23 @@ typedef struct trap_state {
 } trap_state;
 #endif

+typedef struct sparc_def_t sparc_def_t;
+
+struct sparc_def_t {
+    const char *name;
+    target_ulong iu_version;
+    uint32_t fpu_version;
+    uint32_t mmu_version;
+    uint32_t mmu_bm;
+    uint32_t mmu_ctpr_mask;
+    uint32_t mmu_cxr_mask;
+    uint32_t mmu_sfsr_mask;
+    uint32_t mmu_trcr_mask;
+    uint32_t features;
+    uint32_t nwindows;
+    uint32_t maxtl;
+};
+
 typedef struct CPUSPARCState {
     target_ulong gregs[8]; /* general registers */
     target_ulong *regwptr; /* pointer to current register window */
@@ -275,7 +292,7 @@ typedef struct CPUSPARCState {
     uint64_t hpstate, htstate[MAXTL_MAX], hintp, htba, hver, hstick_cmpr, ssr;
     void *hstick; // UA 2005
 #endif
-    uint32_t features;
+    sparc_def_t *def;
 } CPUSPARCState;

 #define CPU_FEATURE_FLOAT    (1 << 0)
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 811de01..09b30e3 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -34,23 +34,6 @@
 //#define DEBUG_FEATURES
 //#define DEBUG_PCALL

-typedef struct sparc_def_t sparc_def_t;
-
-struct sparc_def_t {
-    const char *name;
-    target_ulong iu_version;
-    uint32_t fpu_version;
-    uint32_t mmu_version;
-    uint32_t mmu_bm;
-    uint32_t mmu_ctpr_mask;
-    uint32_t mmu_cxr_mask;
-    uint32_t mmu_sfsr_mask;
-    uint32_t mmu_trcr_mask;
-    uint32_t features;
-    uint32_t nwindows;
-    uint32_t maxtl;
-};
-
 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);

 /* Sparc MMU emulation */
@@ -936,7 +919,8 @@ static int cpu_sparc_register(CPUSPARCState *env,
const char *cpu_model)
     if (cpu_sparc_find_by_name(def, cpu_model) < 0)
         return -1;

-    env->features = def->features;
+    env->def = malloc(sizeof(*def));
+    memcpy(env->def, def, sizeof(*def));
     env->cpu_model_str = cpu_model;
     env->version = def->iu_version;
     env->fsr = def->fpu_version;
@@ -960,6 +944,7 @@ static int cpu_sparc_register(CPUSPARCState *env,
const char *cpu_model)

 static void cpu_sparc_close(CPUSPARCState *env)
 {
+    free(env->def);
     free(env);
 }

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 6315218..1796cff 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -59,7 +59,7 @@ typedef struct DisasContext {
     int fpu_enabled;
     int address_mask_32bit;
     struct TranslationBlock *tb;
-    uint32_t features;
+    sparc_def_t *def;
 } DisasContext;

 // This function uses non-native bit order
@@ -1905,10 +1905,10 @@ static inline TCGv get_src2(unsigned int insn, TCGv def)
 }

 #define CHECK_IU_FEATURE(dc, FEATURE)                      \
-    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
+    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))     \
         goto illegal_insn;
 #define CHECK_FPU_FEATURE(dc, FEATURE)                     \
-    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
+    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))       \
         goto nfpu_insn;

 /* before an instruction, dc->pc must be static */
@@ -3451,6 +3451,9 @@ static void disas_sparc_insn(DisasContext * dc)
                             }
 #else
                             tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
+                            if (dc->def->nwindows != 32) {
+                                tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
(1 << dc->def->nwindows) - 1);
+                            }
                             tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                            offsetof(CPUSPARCState, wim));
 #endif
@@ -4141,7 +4144,7 @@ static void disas_sparc_insn(DisasContext * dc)
                     goto jmp_insn;
 #endif
                 case 0x3b: /* flush */
-                    if (!((dc)->features & CPU_FEATURE_FLUSH))
+                    if (!((dc)->def->features & CPU_FEATURE_FLUSH))
                         goto unimp_flush;
                     tcg_gen_helper_0_1(helper_flush, cpu_dst);
                     break;
@@ -4742,11 +4745,11 @@ static inline void
gen_intermediate_code_internal(TranslationBlock * tb,
     last_pc = dc->pc;
     dc->npc = (target_ulong) tb->cs_base;
     dc->mem_idx = cpu_mmu_index(env);
-    dc->features = env->features;
-    if ((dc->features & CPU_FEATURE_FLOAT)) {
+    dc->def = env->def;
+    if ((dc->def->features & CPU_FEATURE_FLOAT)) {
         dc->fpu_enabled = cpu_fpu_enabled(env);
 #if defined(CONFIG_USER_ONLY)
-        dc->features |= CPU_FEATURE_FLOAT128;
+        dc->def->features |= CPU_FEATURE_FLOAT128;
 #endif
     } else
         dc->fpu_enabled = 0;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]