diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2020-02-08 12:58:01 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-02-13 14:14:54 +0000 |
commit | 4f9584ed4bba8a57a3cb2fa48a682725005d530a (patch) | |
tree | 3f726e63b54c96e7de87f76732b3f2165a2a6298 /target | |
parent | d8564ee4e5bce87ec1fdf23656df9367eb1bc571 (diff) | |
download | qemu-4f9584ed4bba8a57a3cb2fa48a682725005d530a.zip qemu-4f9584ed4bba8a57a3cb2fa48a682725005d530a.tar.gz qemu-4f9584ed4bba8a57a3cb2fa48a682725005d530a.tar.bz2 |
target/arm: Split out aarch32_cpsr_valid_mask
Split this helper out of msr_mask in translate.c. At the same time,
transform the negative reductive logic to positive accumulative logic.
It will be usable along the exception paths.
While touching msr_mask, fix up formatting.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20200208125816.14954-6-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/internals.h | 21 | ||||
-rw-r--r-- | target/arm/translate.c | 40 |
2 files changed, 38 insertions, 23 deletions
diff --git a/target/arm/internals.h b/target/arm/internals.h index 6be8b2d..4d4896f 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1061,6 +1061,27 @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx) } } +static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features, + const ARMISARegisters *id) +{ + uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV | CPSR_J; + + if ((features >> ARM_FEATURE_V4T) & 1) { + valid |= CPSR_T; + } + if ((features >> ARM_FEATURE_V5) & 1) { + valid |= CPSR_Q; /* V5TE in reality*/ + } + if ((features >> ARM_FEATURE_V6) & 1) { + valid |= CPSR_E | CPSR_GE; + } + if ((features >> ARM_FEATURE_THUMB2) & 1) { + valid |= CPSR_IT; + } + + return valid; +} + /* * Parameters of a given virtual address, as extracted from the * translation control register (TCR) for a given regime. diff --git a/target/arm/translate.c b/target/arm/translate.c index d58c328..20f89ac 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -2734,39 +2734,33 @@ static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y) /* Return the mask of PSR bits set by a MSR instruction. */ static uint32_t msr_mask(DisasContext *s, int flags, int spsr) { - uint32_t mask; + uint32_t mask = 0; - mask = 0; - if (flags & (1 << 0)) + if (flags & (1 << 0)) { mask |= 0xff; - if (flags & (1 << 1)) - mask |= 0xff00; - if (flags & (1 << 2)) - mask |= 0xff0000; - if (flags & (1 << 3)) - mask |= 0xff000000; - - /* Mask out undefined bits. */ - mask &= ~CPSR_RESERVED; - if (!arm_dc_feature(s, ARM_FEATURE_V4T)) { - mask &= ~CPSR_T; } - if (!arm_dc_feature(s, ARM_FEATURE_V5)) { - mask &= ~CPSR_Q; /* V5TE in reality*/ + if (flags & (1 << 1)) { + mask |= 0xff00; } - if (!arm_dc_feature(s, ARM_FEATURE_V6)) { - mask &= ~(CPSR_E | CPSR_GE); + if (flags & (1 << 2)) { + mask |= 0xff0000; } - if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) { - mask &= ~CPSR_IT; + if (flags & (1 << 3)) { + mask |= 0xff000000; } - /* Mask out execution state and reserved bits. */ + + /* Mask out undefined and reserved bits. */ + mask &= aarch32_cpsr_valid_mask(s->features, s->isar); + + /* Mask out execution state. */ if (!spsr) { - mask &= ~(CPSR_EXEC | CPSR_RESERVED); + mask &= ~CPSR_EXEC; } + /* Mask out privileged bits. */ - if (IS_USER(s)) + if (IS_USER(s)) { mask &= CPSR_USER; + } return mask; } |