diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2019-02-15 10:00:56 +0000 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2019-02-18 11:00:44 +1100 |
commit | 9b5b74da0a07a89ef71c7f7da0b36560a3bac521 (patch) | |
tree | 6c7164a8b4bdd3b69c2ed60fa85a816b08e51f7d /target | |
parent | 6175f5a058eb077fb4dd94c79e8ef961bb4dba69 (diff) | |
download | qemu-9b5b74da0a07a89ef71c7f7da0b36560a3bac521.zip qemu-9b5b74da0a07a89ef71c7f7da0b36560a3bac521.tar.gz qemu-9b5b74da0a07a89ef71c7f7da0b36560a3bac521.tar.bz2 |
target/ppc: Split out VSCR_SAT to a vector field
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>
Diffstat (limited to 'target')
-rw-r--r-- | target/ppc/cpu.h | 4 | ||||
-rw-r--r-- | 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 1c883fa..325ebbe 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 1d8a4b5..6ad596a 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) |