[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH][MIPS] hflags computation cleanup
From: |
Aurelien Jarno |
Subject: |
[Qemu-devel] [PATCH][MIPS] hflags computation cleanup |
Date: |
Tue, 25 Sep 2007 17:45:31 +0200 |
User-agent: |
Mutt/1.5.13 (2006-08-11) |
Hi all,
Currently hflags is computed at three different places of the code,
with a few minor differences.
The patch below adds a compute_hflags() function which does the same
job. I am not sure the code is faster, but at least that makes the code
more maintainable.
It also fixes two small bugs:
- The current code assume that writting CP0 Status only allow a
transition from kernel to userland. This is wrong in some rare cases
when CP0 is accessible as a user.
- When leaving debug mode, MIPS_HFLAG_DM should be cleared, not set.
Bye,
Aurelien
Index: target-mips/exec.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/exec.h,v
retrieving revision 1.32
diff -u -d -p -r1.32 exec.h
--- target-mips/exec.h 16 Sep 2007 21:08:03 -0000 1.32
+++ target-mips/exec.h 25 Sep 2007 15:40:11 -0000
@@ -95,6 +95,7 @@ void do_mfc0_count(void);
void do_mtc0_entryhi(uint32_t in);
void do_mtc0_status_debug(uint32_t old, uint32_t val);
void do_mtc0_status_irqraise_debug(void);
+void compute_hflags(CPUState *env);
void dump_fpu(CPUState *env);
void fpu_dump_state(CPUState *env, FILE *f,
int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
Index: target-mips/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/helper.c,v
retrieving revision 1.50
diff -u -d -p -r1.50 helper.c
--- target-mips/helper.c 25 Sep 2007 14:49:46 -0000 1.50
+++ target-mips/helper.c 25 Sep 2007 15:40:11 -0000
@@ -368,10 +368,8 @@ void do_interrupt (CPUState *env)
env->CP0_DEPC = env->PC[env->current_tc];
}
enter_debug_mode:
- env->hflags |= MIPS_HFLAG_DM;
- env->hflags |= MIPS_HFLAG_64;
+ env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
env->hflags &= ~MIPS_HFLAG_UM;
- env->hflags |= MIPS_HFLAG_CP0;
/* EJTAG probe trap enable is not implemented... */
if (!(env->CP0_Status & (1 << CP0St_EXL)))
env->CP0_Cause &= ~(1 << CP0Ca_BD);
@@ -396,9 +394,8 @@ void do_interrupt (CPUState *env)
env->CP0_ErrorEPC = env->PC[env->current_tc];
}
env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
- env->hflags |= MIPS_HFLAG_64;
+ env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
env->hflags &= ~MIPS_HFLAG_UM;
- env->hflags |= MIPS_HFLAG_CP0;
if (!(env->CP0_Status & (1 << CP0St_EXL)))
env->CP0_Cause &= ~(1 << CP0Ca_BD);
env->PC[env->current_tc] = (int32_t)0xBFC00000;
@@ -499,9 +496,8 @@ void do_interrupt (CPUState *env)
env->CP0_Cause &= ~(1 << CP0Ca_BD);
}
env->CP0_Status |= (1 << CP0St_EXL);
- env->hflags |= MIPS_HFLAG_64;
+ env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
env->hflags &= ~MIPS_HFLAG_UM;
- env->hflags |= MIPS_HFLAG_CP0;
}
env->hflags &= ~MIPS_HFLAG_BMASK;
if (env->CP0_Status & (1 << CP0St_BEV)) {
Index: target-mips/op.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op.c,v
retrieving revision 1.73
diff -u -d -p -r1.73 op.c
--- target-mips/op.c 25 Sep 2007 14:49:47 -0000 1.73
+++ target-mips/op.c 25 Sep 2007 15:40:11 -0000
@@ -1841,30 +1841,8 @@ void op_mtc0_status (void)
val = T0 & mask;
old = env->CP0_Status;
- if (!(val & (1 << CP0St_EXL)) &&
- !(val & (1 << CP0St_ERL)) &&
- !(env->hflags & MIPS_HFLAG_DM) &&
- (val & (1 << CP0St_UM)))
- env->hflags |= MIPS_HFLAG_UM;
-#ifdef TARGET_MIPS64
- if ((env->hflags & MIPS_HFLAG_UM) &&
- !(val & (1 << CP0St_PX)) &&
- !(val & (1 << CP0St_UX)))
- env->hflags &= ~MIPS_HFLAG_64;
-#endif
- if ((val & (1 << CP0St_CU0)) || !(env->hflags & MIPS_HFLAG_UM))
- env->hflags |= MIPS_HFLAG_CP0;
- else
- env->hflags &= ~MIPS_HFLAG_CP0;
- if (val & (1 << CP0St_CU1))
- env->hflags |= MIPS_HFLAG_FPU;
- else
- env->hflags &= ~MIPS_HFLAG_FPU;
- if (val & (1 << CP0St_FR))
- env->hflags |= MIPS_HFLAG_F64;
- else
- env->hflags &= ~MIPS_HFLAG_F64;
env->CP0_Status = (env->CP0_Status & ~mask) | val;
+ CALL_FROM_TB1(compute_hflags, env);
if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB2(do_mtc0_status_debug, old, val);
CALL_FROM_TB1(cpu_mips_update_irq, env);
@@ -3002,21 +2980,7 @@ void op_eret (void)
env->PC[env->current_tc] = env->CP0_EPC;
env->CP0_Status &= ~(1 << CP0St_EXL);
}
- if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
- !(env->CP0_Status & (1 << CP0St_ERL)) &&
- !(env->hflags & MIPS_HFLAG_DM) &&
- (env->CP0_Status & (1 << CP0St_UM)))
- env->hflags |= MIPS_HFLAG_UM;
-#ifdef TARGET_MIPS64
- if ((env->hflags & MIPS_HFLAG_UM) &&
- !(env->CP0_Status & (1 << CP0St_PX)) &&
- !(env->CP0_Status & (1 << CP0St_UX)))
- env->hflags &= ~MIPS_HFLAG_64;
-#endif
- if ((env->CP0_Status & (1 << CP0St_CU0)) || !(env->hflags & MIPS_HFLAG_UM))
- env->hflags |= MIPS_HFLAG_CP0;
- else
- env->hflags &= ~MIPS_HFLAG_CP0;
+ CALL_FROM_TB1(compute_hflags, env);
if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB0(debug_post_eret);
env->CP0_LLAddr = 1;
@@ -3028,22 +2992,8 @@ void op_deret (void)
if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB0(debug_pre_eret);
env->PC[env->current_tc] = env->CP0_DEPC;
- env->hflags |= MIPS_HFLAG_DM;
- if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
- !(env->CP0_Status & (1 << CP0St_ERL)) &&
- !(env->hflags & MIPS_HFLAG_DM) &&
- (env->CP0_Status & (1 << CP0St_UM)))
- env->hflags |= MIPS_HFLAG_UM;
-#ifdef TARGET_MIPS64
- if ((env->hflags & MIPS_HFLAG_UM) &&
- !(env->CP0_Status & (1 << CP0St_PX)) &&
- !(env->CP0_Status & (1 << CP0St_UX)))
- env->hflags &= ~MIPS_HFLAG_64;
-#endif
- if ((env->CP0_Status & (1 << CP0St_CU0)) || !(env->hflags & MIPS_HFLAG_UM))
- env->hflags |= MIPS_HFLAG_CP0;
- else
- env->hflags &= ~MIPS_HFLAG_CP0;
+ env->hflags &= MIPS_HFLAG_DM;
+ CALL_FROM_TB1(compute_hflags, env);
if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB0(debug_post_eret);
env->CP0_LLAddr = 1;
Index: target-mips/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op_helper.c,v
retrieving revision 1.59
diff -u -d -p -r1.59 op_helper.c
--- target-mips/op_helper.c 17 Sep 2007 08:09:53 -0000 1.59
+++ target-mips/op_helper.c 25 Sep 2007 15:40:12 -0000
@@ -313,6 +313,29 @@ void do_mtc0_status_irqraise_debug(void)
fprintf(logfile, "Raise pending IRQs\n");
}
+void compute_hflags(CPUState *env)
+{
+ env->hflags &= ~(MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | MIPS_HFLAG_F64 |
+ MIPS_HFLAG_FPU | MIPS_HFLAG_UM);
+ if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
+ !(env->CP0_Status & (1 << CP0St_ERL)) &&
+ !(env->hflags & MIPS_HFLAG_DM) &&
+ (env->CP0_Status & (1 << CP0St_UM)))
+ env->hflags |= MIPS_HFLAG_UM;
+#ifdef TARGET_MIPS64
+ if (!(env->hflags & MIPS_HFLAG_UM) ||
+ (env->CP0_Status & (1 << CP0St_PX)) ||
+ (env->CP0_Status & (1 << CP0St_UX)))
+ env->hflags |= MIPS_HFLAG_64;
+#endif
+ if ((env->CP0_Status & (1 << CP0St_CU0)) || !(env->hflags & MIPS_HFLAG_UM))
+ 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;
+}
+
void fpu_handle_exception(void)
{
#ifdef CONFIG_SOFTFLOAT
--
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73
: :' : Debian developer | Electrical Engineer
`. `' address@hidden | address@hidden
`- people.debian.org/~aurel32 | www.aurel32.net
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH][MIPS] hflags computation cleanup,
Aurelien Jarno <=