diff mbox

[3/6] target-ppc: Extend FPU state for newer POWER CPUs

Message ID 1348629141-8719-4-git-send-email-david@gibson.dropbear.id.au
State New
Headers show

Commit Message

David Gibson Sept. 26, 2012, 3:12 a.m. UTC
This patch adds some extra FPU state to CPUPPCState.  Specifically, fpscr
is extended to 64 bits, since some recent CPUs now have more status bits
than fit inside 64 bits, and we add the 32 VSR registers present on CPUs
with VSX (these extend the standard FP regs, which together with the
Altivec/VMX registers form a 64 x 128bit register file for VSX).

We don't actually support the instructions using these extra registers in
TCG yet, but we still a place to store the state so we can sync it with
KVM and savevm/loadvm it.  This patch updates the savevm code to not
fail on the extended state, but also does not actually save it - that's
a project for another patch.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/cpu.h       |    4 +++-
 target-ppc/machine.c   |    8 ++++++--
 target-ppc/translate.c |    2 +-
 3 files changed, 10 insertions(+), 4 deletions(-)

Comments

Aurelien Jarno Sept. 26, 2012, 6:36 a.m. UTC | #1
On Wed, Sep 26, 2012 at 01:12:18PM +1000, David Gibson wrote:
> This patch adds some extra FPU state to CPUPPCState.  Specifically, fpscr
> is extended to 64 bits, since some recent CPUs now have more status bits
> than fit inside 64 bits, and we add the 32 VSR registers present on CPUs
> with VSX (these extend the standard FP regs, which together with the
> Altivec/VMX registers form a 64 x 128bit register file for VSX).
> 
> We don't actually support the instructions using these extra registers in
> TCG yet, but we still a place to store the state so we can sync it with
> KVM and savevm/loadvm it.  This patch updates the savevm code to not
> fail on the extended state, but also does not actually save it - that's
> a project for another patch.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  target-ppc/cpu.h       |    4 +++-
>  target-ppc/machine.c   |    8 ++++++--
>  target-ppc/translate.c |    2 +-
>  3 files changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index faf4404..846778f 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -963,7 +963,7 @@ struct CPUPPCState {
>      /* floating point registers */
>      float64 fpr[32];
>      /* floating point status and control register */
> -    uint32_t fpscr;
> +    uint64_t fpscr;

This will break the TCG code, as fpscr is mapped as an i32 in TCG. Also
if it is 64-bit only on PPC64 machines, it might be a good idea to
change it to target_ulong instead, and use _tl in the TCG code.

>      /* Next instruction pointer */
>      target_ulong nip;
> @@ -1014,6 +1014,8 @@ struct CPUPPCState {
>      /* Altivec registers */
>      ppc_avr_t avr[32];
>      uint32_t vscr;
> +    /* VSX registers */
> +    uint64_t vsr[32];
>      /* SPE registers */
>      uint64_t spe_acc;
>      uint32_t spe_fscr;
> diff --git a/target-ppc/machine.c b/target-ppc/machine.c
> index 21ce757..5e7bc00 100644
> --- a/target-ppc/machine.c
> +++ b/target-ppc/machine.c
> @@ -6,6 +6,7 @@ void cpu_save(QEMUFile *f, void *opaque)
>  {
>      CPUPPCState *env = (CPUPPCState *)opaque;
>      unsigned int i, j;
> +    uint32_t fpscr;
>  
>      for (i = 0; i < 32; i++)
>          qemu_put_betls(f, &env->gpr[i]);
> @@ -30,7 +31,8 @@ void cpu_save(QEMUFile *f, void *opaque)
>          u.d = env->fpr[i];
>          qemu_put_be64(f, u.l);
>      }
> -    qemu_put_be32s(f, &env->fpscr);
> +    fpscr = env->fpscr;
> +    qemu_put_be32s(f, &fpscr);
>      qemu_put_sbe32s(f, &env->access_type);
>  #if defined(TARGET_PPC64)
>      qemu_put_betls(f, &env->asr);
> @@ -90,6 +92,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
>      CPUPPCState *env = (CPUPPCState *)opaque;
>      unsigned int i, j;
>      target_ulong sdr1;
> +    uint32_t fpscr;
>  
>      for (i = 0; i < 32; i++)
>          qemu_get_betls(f, &env->gpr[i]);
> @@ -114,7 +117,8 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
>          u.l = qemu_get_be64(f);
>          env->fpr[i] = u.d;
>      }
> -    qemu_get_be32s(f, &env->fpscr);
> +    qemu_get_be32s(f, &fpscr);
> +    env->fpscr = fpscr;
>      qemu_get_sbe32s(f, &env->access_type);
>  #if defined(TARGET_PPC64)
>      qemu_get_betls(f, &env->asr);
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index ac915cc..c8122b7 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -9463,7 +9463,7 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
>          if ((i & (RFPL - 1)) == (RFPL - 1))
>              cpu_fprintf(f, "\n");
>      }
> -    cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
> +    cpu_fprintf(f, "FPSCR %08" PRIx64 "\n", env->fpscr);
>  #if !defined(CONFIG_USER_ONLY)
>      cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
>                     "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
> -- 
> 1.7.10.4
> 
> 
>
David Gibson Sept. 27, 2012, 12:03 a.m. UTC | #2
On Wed, Sep 26, 2012 at 08:36:45AM +0200, Aurelien Jarno wrote:
> On Wed, Sep 26, 2012 at 01:12:18PM +1000, David Gibson wrote:
> > This patch adds some extra FPU state to CPUPPCState.  Specifically, fpscr
> > is extended to 64 bits, since some recent CPUs now have more status bits
> > than fit inside 64 bits, and we add the 32 VSR registers present on CPUs
> > with VSX (these extend the standard FP regs, which together with the
> > Altivec/VMX registers form a 64 x 128bit register file for VSX).
> > 
> > We don't actually support the instructions using these extra registers in
> > TCG yet, but we still a place to store the state so we can sync it with
> > KVM and savevm/loadvm it.  This patch updates the savevm code to not
> > fail on the extended state, but also does not actually save it - that's
> > a project for another patch.
> > 
> > Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> > ---
> >  target-ppc/cpu.h       |    4 +++-
> >  target-ppc/machine.c   |    8 ++++++--
> >  target-ppc/translate.c |    2 +-
> >  3 files changed, 10 insertions(+), 4 deletions(-)
> > 
> > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> > index faf4404..846778f 100644
> > --- a/target-ppc/cpu.h
> > +++ b/target-ppc/cpu.h
> > @@ -963,7 +963,7 @@ struct CPUPPCState {
> >      /* floating point registers */
> >      float64 fpr[32];
> >      /* floating point status and control register */
> > -    uint32_t fpscr;
> > +    uint64_t fpscr;
> 
> This will break the TCG code, as fpscr is mapped as an i32 in TCG. Also
> if it is 64-bit only on PPC64 machines, it might be a good idea to
> change it to target_ulong instead, and use _tl in the TCG code.

Ah, good point, thanks for catching that.  Both changes made for the
next version.
diff mbox

Patch

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index faf4404..846778f 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -963,7 +963,7 @@  struct CPUPPCState {
     /* floating point registers */
     float64 fpr[32];
     /* floating point status and control register */
-    uint32_t fpscr;
+    uint64_t fpscr;
 
     /* Next instruction pointer */
     target_ulong nip;
@@ -1014,6 +1014,8 @@  struct CPUPPCState {
     /* Altivec registers */
     ppc_avr_t avr[32];
     uint32_t vscr;
+    /* VSX registers */
+    uint64_t vsr[32];
     /* SPE registers */
     uint64_t spe_acc;
     uint32_t spe_fscr;
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 21ce757..5e7bc00 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -6,6 +6,7 @@  void cpu_save(QEMUFile *f, void *opaque)
 {
     CPUPPCState *env = (CPUPPCState *)opaque;
     unsigned int i, j;
+    uint32_t fpscr;
 
     for (i = 0; i < 32; i++)
         qemu_put_betls(f, &env->gpr[i]);
@@ -30,7 +31,8 @@  void cpu_save(QEMUFile *f, void *opaque)
         u.d = env->fpr[i];
         qemu_put_be64(f, u.l);
     }
-    qemu_put_be32s(f, &env->fpscr);
+    fpscr = env->fpscr;
+    qemu_put_be32s(f, &fpscr);
     qemu_put_sbe32s(f, &env->access_type);
 #if defined(TARGET_PPC64)
     qemu_put_betls(f, &env->asr);
@@ -90,6 +92,7 @@  int cpu_load(QEMUFile *f, void *opaque, int version_id)
     CPUPPCState *env = (CPUPPCState *)opaque;
     unsigned int i, j;
     target_ulong sdr1;
+    uint32_t fpscr;
 
     for (i = 0; i < 32; i++)
         qemu_get_betls(f, &env->gpr[i]);
@@ -114,7 +117,8 @@  int cpu_load(QEMUFile *f, void *opaque, int version_id)
         u.l = qemu_get_be64(f);
         env->fpr[i] = u.d;
     }
-    qemu_get_be32s(f, &env->fpscr);
+    qemu_get_be32s(f, &fpscr);
+    env->fpscr = fpscr;
     qemu_get_sbe32s(f, &env->access_type);
 #if defined(TARGET_PPC64)
     qemu_get_betls(f, &env->asr);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ac915cc..c8122b7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9463,7 +9463,7 @@  void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
         if ((i & (RFPL - 1)) == (RFPL - 1))
             cpu_fprintf(f, "\n");
     }
-    cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
+    cpu_fprintf(f, "FPSCR %08" PRIx64 "\n", env->fpscr);
 #if !defined(CONFIG_USER_ONLY)
     cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
                    "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",