[Qemu-devel] [PULL 41/43] target/ppc: Split out VSCR_SAT to a vector field

David Gibson posted 43 patches 5 years, 7 months ago
Maintainers: "Hervé Poussineau" <hpoussin@reactos.org>, "Michael S. Tsirkin" <mst@redhat.com>, "Cédric Le Goater" <clg@kaod.org>, Igor Mammedov <imammedo@redhat.com>, Gerd Hoffmann <kraxel@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Christian Borntraeger <borntraeger@de.ibm.com>, Dmitry Fleytman <dmitry.fleytman@gmail.com>, Paolo Bonzini <pbonzini@redhat.com>, Halil Pasic <pasic@linux.ibm.com>, Fam Zheng <fam@euphon.net>, David Gibson <david@gibson.dropbear.id.au>, Amit Shah <amit@kernel.org>, Collin Walling <walling@linux.ibm.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Richard Henderson <rth@twiddle.net>, David Hildenbrand <david@redhat.com>, Cornelia Huck <cohuck@redhat.com>
[Qemu-devel] [PULL 41/43] target/ppc: Split out VSCR_SAT to a vector field
Posted by David Gibson 5 years, 7 months ago
From: Richard Henderson <richard.henderson@linaro.org>

Change the representation of VSCR_SAT such that it is easy
to set from vector code.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Message-Id: <20190215100058.20015-16-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/cpu.h        |  4 +++-
 target/ppc/int_helper.c | 11 ++++++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 1c883fa836..325ebbeb98 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1052,10 +1052,12 @@ struct CPUPPCState {
     /* Special purpose registers */
     target_ulong spr[1024];
     ppc_spr_t spr_cb[1024];
-    /* Vector status and control register */
+    /* Vector status and control register, minus VSCR_SAT.  */
     uint32_t vscr;
     /* VSX registers (including FP and AVR) */
     ppc_vsr_t vsr[64] QEMU_ALIGNED(16);
+    /* Non-zero if and only if VSCR_SAT should be set.  */
+    ppc_vsr_t vscr_sat QEMU_ALIGNED(16);
     /* SPE registers */
     uint64_t spe_acc;
     uint32_t spe_fscr;
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 1d8a4b530b..6ad596a08b 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -459,18 +459,23 @@ void helper_lvsr(ppc_avr_t *r, target_ulong sh)
 
 void helper_mtvscr(CPUPPCState *env, uint32_t vscr)
 {
-    env->vscr = vscr;
+    env->vscr = vscr & ~(1u << VSCR_SAT);
+    /* Which bit we set is completely arbitrary, but clear the rest.  */
+    env->vscr_sat.u64[0] = vscr & (1u << VSCR_SAT);
+    env->vscr_sat.u64[1] = 0;
     set_flush_to_zero((vscr >> VSCR_NJ) & 1, &env->vec_status);
 }
 
 uint32_t helper_mfvscr(CPUPPCState *env)
 {
-    return env->vscr;
+    uint32_t sat = (env->vscr_sat.u64[0] | env->vscr_sat.u64[1]) != 0;
+    return env->vscr | (sat << VSCR_SAT);
 }
 
 static inline void set_vscr_sat(CPUPPCState *env)
 {
-    env->vscr |= 1 << VSCR_SAT;
+    /* The choice of non-zero value is arbitrary.  */
+    env->vscr_sat.u32[0] = 1;
 }
 
 void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-- 
2.20.1