aboutsummaryrefslogtreecommitdiff
path: root/target-mips/op_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-mips/op_helper.c')
-rw-r--r--target-mips/op_helper.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 01315ef0dc..185ae40270 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -17,16 +17,70 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
-#include "exec.h"
+#include "cpu.h"
+#include "dyngen-exec.h"
#include "host-utils.h"
#include "helper.h"
+#if !defined(CONFIG_USER_ONLY)
+#include "softmmu_exec.h"
+#endif /* !defined(CONFIG_USER_ONLY) */
+
#ifndef CONFIG_USER_ONLY
static inline void cpu_mips_tlb_flush (CPUState *env, int flush_global);
#endif
+static inline void compute_hflags(CPUState *env)
+{
+ env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
+ MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
+ MIPS_HFLAG_UX);
+ if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
+ !(env->CP0_Status & (1 << CP0St_ERL)) &&
+ !(env->hflags & MIPS_HFLAG_DM)) {
+ env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
+ }
+#if defined(TARGET_MIPS64)
+ if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
+ (env->CP0_Status & (1 << CP0St_PX)) ||
+ (env->CP0_Status & (1 << CP0St_UX))) {
+ env->hflags |= MIPS_HFLAG_64;
+ }
+ if (env->CP0_Status & (1 << CP0St_UX)) {
+ env->hflags |= MIPS_HFLAG_UX;
+ }
+#endif
+ if ((env->CP0_Status & (1 << CP0St_CU0)) ||
+ !(env->hflags & MIPS_HFLAG_KSU)) {
+ env->hflags |= MIPS_HFLAG_CP0;
+ }
+ if (env->CP0_Status & (1 << CP0St_CU1)) {
+ env->hflags |= MIPS_HFLAG_FPU;
+ }
+ if (env->CP0_Status & (1 << CP0St_FR)) {
+ env->hflags |= MIPS_HFLAG_F64;
+ }
+ if (env->insn_flags & ISA_MIPS32R2) {
+ if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
+ env->hflags |= MIPS_HFLAG_COP1X;
+ }
+ } else if (env->insn_flags & ISA_MIPS32) {
+ if (env->hflags & MIPS_HFLAG_64) {
+ env->hflags |= MIPS_HFLAG_COP1X;
+ }
+ } else if (env->insn_flags & ISA_MIPS4) {
+ /* All supported MIPS IV CPUs use the XX (CU3) to enable
+ and disable the MIPS IV extensions to the MIPS III ISA.
+ Some other MIPS IV CPUs ignore the bit, so the check here
+ would be too restrictive for them. */
+ if (env->CP0_Status & (1 << CP0St_CU3)) {
+ env->hflags |= MIPS_HFLAG_COP1X;
+ }
+ }
+}
+
/*****************************************************************************/
/* Exceptions processing helpers */