diff options
author | Maciej W. Rozycki <macro@codesourcery.com> | 2014-11-19 17:29:00 +0000 |
---|---|---|
committer | Leon Alrae <leon.alrae@imgtec.com> | 2014-12-16 12:45:20 +0000 |
commit | c48245f0c62405f27266fcf08722d8c290520418 (patch) | |
tree | 4d08bee9257ebc937b5bc0a18935a4f9e064ba25 /target-mips/cpu.h | |
parent | d9224450208e0de62323b64ace91f98bc31d6e2c (diff) | |
download | qemu-c48245f0c62405f27266fcf08722d8c290520418.tar.gz qemu-c48245f0c62405f27266fcf08722d8c290520418.tar.bz2 qemu-c48245f0c62405f27266fcf08722d8c290520418.zip |
target-mips: Correct 32-bit address space wrapping
Make sure the address space is unconditionally wrapped on 32-bit
processors, that is ones that do not implement at least the MIPS III
ISA.
Also make MIPS16 SAVE and RESTORE instructions use address calculation
rather than plain arithmetic operations for stack pointer manipulation
so that their semantics for stack accesses follows the architecture
specification. That in particular applies to user software run on
64-bit processors with the CP0.Status.UX bit clear where the address
space is wrapped to 32 bits.
Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Diffstat (limited to 'target-mips/cpu.h')
-rw-r--r-- | target-mips/cpu.h | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/target-mips/cpu.h b/target-mips/cpu.h index e59cb4c6dc..f8cf143198 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -838,10 +838,12 @@ static inline void compute_hflags(CPUMIPSState *env) env->hflags |= MIPS_HFLAG_64; } - if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && - !(env->CP0_Status & (1 << CP0St_UX))) { + if (!(env->insn_flags & ISA_MIPS3)) { env->hflags |= MIPS_HFLAG_AWRAP; - } else if (env->insn_flags & ISA_MIPS32R6) { + } else if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && + !(env->CP0_Status & (1 << CP0St_UX))) { + env->hflags |= MIPS_HFLAG_AWRAP; + } else if (env->insn_flags & ISA_MIPS64R6) { /* Address wrapping for Supervisor and Kernel is specified in R6 */ if ((((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) && !(env->CP0_Status & (1 << CP0St_SX))) || |