Skip to contentSkip to conversation

target-ppc: add support for reading/writing spefscr

PATCH In review Nathan Froyd 2 participants 2 messages Dec 14, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 target-ppc: add support for reading/writing spefscr

As well as reading/writing the CPU's idea of what spefscr is, this patch also adds support for reading/writing it in user mode.

---
 target-ppc/translate.c      |    4 ++++
 target-ppc/translate_init.c |   21 +++++++++++++++------
 2 files changed, 19 insertions(+), 6 deletions(-)
target-ppc/translate.c +4 -0
index e2d6f42..82f1b9c 100644
@@ -69,6 +69,7 @@ static TCGv cpu_lr;
 static TCGv cpu_xer;
 static TCGv cpu_reserve;
 static TCGv_i32 cpu_fpscr;
+static TCGv_i32 cpu_spefscr;
 static TCGv_i32 cpu_access_type;
 
 #include "gen-icount.h"
@@ -152,6 +153,9 @@ void ppc_translate_init(void)
     cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
                                        offsetof(CPUState, fpscr), "fpscr");
 
+    cpu_spefscr = tcg_global_mem_new_i32(TCG_AREG0,
+                                         offsetof(CPUState, spe_fscr), "spefscr");
+
     cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
                                              offsetof(CPUState, access_type), "access_type");
 
target-ppc/translate_init.c +15 -6
index 0ce81ed..60838aa 100644
@@ -434,6 +434,17 @@ static void spr_write_pir (void *opaque, int sprn, int gprn)
 }
 #endif
 
+/* SPE specific registers */
+static void spr_read_spefscr (void *opaque, int gprn, int sprn)
+{
+    tcg_gen_mov_tl(cpu_gpr[gprn], cpu_spefscr);
+}
+
+static void spr_write_spefscr (void *opaque, int sprn, int gprn)
+{
+    tcg_gen_mov_tl(cpu_spefscr, cpu_gpr[gprn]);
+}
+
 #if !defined(CONFIG_USER_ONLY)
 /* Callback used to write the exception vector base */
 static void spr_write_excp_prefix (void *opaque, int sprn, int gprn)
@@ -3995,10 +4006,9 @@ static void init_proc_e200 (CPUPPCState *env)
     /* Time base */
     gen_tbl(env);
     gen_spr_BookE(env, 0x000000070000FFFFULL);
-    /* XXX : not implemented */
     spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_spefscr, &spr_write_spefscr,
+                 &spr_read_spefscr, &spr_write_spefscr,
                  0x00000000);
     /* Memory management */
     gen_spr_BookE_FSL(env, 0x0000005D);
@@ -4165,10 +4175,9 @@ static void init_proc_e500 (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_pir,
                  0x00000000);
-    /* XXX : not implemented */
     spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_spefscr, &spr_write_spefscr,
+                 &spr_read_spefscr, &spr_write_spefscr,
                  0x00000000);
     /* Memory management */
 #if !defined(CONFIG_USER_ONLY)
Signature · 1 line
1.6.0.5
#1 lore raw
Quoted 4 lines · Nathan Froyd

As well as reading/writing the CPU's idea of what spefscr is, this patch also adds support for reading/writing it in user mode.

I am not sure it is worth mapping fpescr as a TCG register given that except load/store it will be only used in op_helper.c. Moreover I am sure that sooner or later we will need an helper to write it, as a write may change rounding mode or trigger an exception.

I think it is better to use tcg_gen_ld_tl/tcg_gen_st_tl as it is already done for other SPE registers.

Quoted 81 lines
---
 target-ppc/translate.c      |    4 ++++
 target-ppc/translate_init.c |   21 +++++++++++++++------
 2 files changed, 19 insertions(+), 6 deletions(-)
target-ppc/translate.c +4 -0
index e2d6f42..82f1b9c 100644
@@ -69,6 +69,7 @@ static TCGv cpu_lr;
 static TCGv cpu_xer;
 static TCGv cpu_reserve;
 static TCGv_i32 cpu_fpscr;
+static TCGv_i32 cpu_spefscr;
 static TCGv_i32 cpu_access_type;
 
 #include "gen-icount.h"
@@ -152,6 +153,9 @@ void ppc_translate_init(void)
     cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
                                        offsetof(CPUState, fpscr), "fpscr");
 
+    cpu_spefscr = tcg_global_mem_new_i32(TCG_AREG0,
+                                         offsetof(CPUState, spe_fscr), "spefscr");
+
     cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
                                              offsetof(CPUState, access_type), "access_type");
 
target-ppc/translate_init.c +15 -6
index 0ce81ed..60838aa 100644
@@ -434,6 +434,17 @@ static void spr_write_pir (void *opaque, int sprn, int gprn)
 }
 #endif
 
+/* SPE specific registers */
+static void spr_read_spefscr (void *opaque, int gprn, int sprn)
+{
+    tcg_gen_mov_tl(cpu_gpr[gprn], cpu_spefscr);
+}
+
+static void spr_write_spefscr (void *opaque, int sprn, int gprn)
+{
+    tcg_gen_mov_tl(cpu_spefscr, cpu_gpr[gprn]);
+}
+
 #if !defined(CONFIG_USER_ONLY)
 /* Callback used to write the exception vector base */
 static void spr_write_excp_prefix (void *opaque, int sprn, int gprn)
@@ -3995,10 +4006,9 @@ static void init_proc_e200 (CPUPPCState *env)
     /* Time base */
     gen_tbl(env);
     gen_spr_BookE(env, 0x000000070000FFFFULL);
-    /* XXX : not implemented */
     spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_spefscr, &spr_write_spefscr,
+                 &spr_read_spefscr, &spr_write_spefscr,
                  0x00000000);
     /* Memory management */
     gen_spr_BookE_FSL(env, 0x0000005D);
@@ -4165,10 +4175,9 @@ static void init_proc_e500 (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_pir,
                  0x00000000);
-    /* XXX : not implemented */
     spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_spefscr, &spr_write_spefscr,
+                 &spr_read_spefscr, &spr_write_spefscr,
                  0x00000000);
     /* Memory management */
 #if !defined(CONFIG_USER_ONLY)
Signature · 1 line
1.6.0.5
Signature · 4 lines
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   [email protected]         | [email protected]
   `-    people.debian.org/~aurel32 | www.aurel32.net