target-mips: improve exception handling

This patch improves exception handling in MIPS.
Instructions generate several types of exceptions.
When exception is generated, it breaks the execution of the current
translation block. Implementation of the exceptions handling does not
correctly restore icount for the instruction which caused the exception.
In most cases icount will be decreased by the value equal to the size of
TB. This patch passes pointer to the translation block internals to the
exception handler. It allows correct restoring of the icount value.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
[leon.alrae@imgtec.com: avoid retranslation in linux-user SC, break lines
 which are over 80 chars, remove v3 changelog from the commit message]
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
This commit is contained in:
Pavel Dovgaluk 2015-07-10 12:57:08 +03:00 committed by Leon Alrae
parent d54a299b83
commit 9c708c7f9f
5 changed files with 427 additions and 379 deletions

View File

@ -1049,4 +1049,28 @@ static inline void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val)
}
#endif
static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
uint32_t exception,
int error_code,
uintptr_t pc)
{
CPUState *cs = CPU(mips_env_get_cpu(env));
if (exception < EXCP_SC) {
qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n",
__func__, exception, error_code);
}
cs->exception_index = exception;
env->error_code = error_code;
cpu_loop_exit_restore(cs, pc);
}
static inline void QEMU_NORETURN do_raise_exception(CPUMIPSState *env,
uint32_t exception,
uintptr_t pc)
{
do_raise_exception_err(env, exception, 0, pc);
}
#endif /* !defined (__MIPS_CPU_H__) */

View File

@ -1,5 +1,6 @@
DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int)
DEF_HELPER_2(raise_exception, noreturn, env, i32)
DEF_HELPER_1(raise_exception_debug, noreturn, env)
DEF_HELPER_1(do_semihosting, void, env)

View File

@ -1352,7 +1352,7 @@ void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong elm, uint32_t cd)
/* check exception */
if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)
& GET_FP_CAUSE(env->active_tc.msacsr)) {
helper_raise_exception(env, EXCP_MSAFPE);
do_raise_exception(env, EXCP_MSAFPE, GETPC());
}
break;
}
@ -1505,14 +1505,14 @@ static inline void clear_msacsr_cause(CPUMIPSState *env)
SET_FP_CAUSE(env->active_tc.msacsr, 0);
}
static inline void check_msacsr_cause(CPUMIPSState *env)
static inline void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
{
if ((GET_FP_CAUSE(env->active_tc.msacsr) &
(GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)) == 0) {
UPDATE_FP_FLAGS(env->active_tc.msacsr,
GET_FP_CAUSE(env->active_tc.msacsr));
} else {
helper_raise_exception(env, EXCP_MSAFPE);
do_raise_exception(env, EXCP_MSAFPE, retaddr);
}
}
@ -1851,7 +1851,8 @@ static inline int32 float64_to_q32(float64 a, float_status *status)
} while (0)
static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -1873,13 +1874,14 @@ static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -1903,13 +1905,14 @@ static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -1931,13 +1934,14 @@ static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -1959,13 +1963,14 @@ static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -1987,13 +1992,14 @@ static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -2015,13 +2021,14 @@ static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -2043,13 +2050,14 @@ static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -2071,13 +2079,14 @@ static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -2099,13 +2108,14 @@ static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet)
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -2127,13 +2137,15 @@ static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
wr_t *pwt, uint32_t df, int quiet) {
wr_t *pwt, uint32_t df, int quiet,
uintptr_t retaddr)
{
wr_t wx, *pwx = &wx;
uint32_t i;
@ -2154,7 +2166,7 @@ static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, retaddr);
msa_move_v(pwd, pwx);
}
@ -2165,7 +2177,7 @@ void helper_msa_fcaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_af(env, pwd, pws, pwt, df, 1);
compare_af(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fcun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2174,7 +2186,7 @@ void helper_msa_fcun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_un(env, pwd, pws, pwt, df, 1);
compare_un(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fceq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2183,7 +2195,7 @@ void helper_msa_fceq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_eq(env, pwd, pws, pwt, df, 1);
compare_eq(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fcueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2192,7 +2204,7 @@ void helper_msa_fcueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_ueq(env, pwd, pws, pwt, df, 1);
compare_ueq(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fclt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2201,7 +2213,7 @@ void helper_msa_fclt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_lt(env, pwd, pws, pwt, df, 1);
compare_lt(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fcult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2210,7 +2222,7 @@ void helper_msa_fcult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_ult(env, pwd, pws, pwt, df, 1);
compare_ult(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fcle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2219,7 +2231,7 @@ void helper_msa_fcle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_le(env, pwd, pws, pwt, df, 1);
compare_le(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fcule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2228,7 +2240,7 @@ void helper_msa_fcule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_ule(env, pwd, pws, pwt, df, 1);
compare_ule(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fsaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2237,7 +2249,7 @@ void helper_msa_fsaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_af(env, pwd, pws, pwt, df, 0);
compare_af(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fsun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2246,7 +2258,7 @@ void helper_msa_fsun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_un(env, pwd, pws, pwt, df, 0);
compare_un(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fseq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2255,7 +2267,7 @@ void helper_msa_fseq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_eq(env, pwd, pws, pwt, df, 0);
compare_eq(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fsueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2264,7 +2276,7 @@ void helper_msa_fsueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_ueq(env, pwd, pws, pwt, df, 0);
compare_ueq(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fslt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2273,7 +2285,7 @@ void helper_msa_fslt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_lt(env, pwd, pws, pwt, df, 0);
compare_lt(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fsult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2282,7 +2294,7 @@ void helper_msa_fsult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_ult(env, pwd, pws, pwt, df, 0);
compare_ult(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fsle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2291,7 +2303,7 @@ void helper_msa_fsle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_le(env, pwd, pws, pwt, df, 0);
compare_le(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fsule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2300,7 +2312,7 @@ void helper_msa_fsule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_ule(env, pwd, pws, pwt, df, 0);
compare_ule(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fcor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2309,7 +2321,7 @@ void helper_msa_fcor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_or(env, pwd, pws, pwt, df, 1);
compare_or(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fcune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2318,7 +2330,7 @@ void helper_msa_fcune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_une(env, pwd, pws, pwt, df, 1);
compare_une(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fcne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2327,7 +2339,7 @@ void helper_msa_fcne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_ne(env, pwd, pws, pwt, df, 1);
compare_ne(env, pwd, pws, pwt, df, 1, GETPC());
}
void helper_msa_fsor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2336,7 +2348,7 @@ void helper_msa_fsor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_or(env, pwd, pws, pwt, df, 0);
compare_or(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fsune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2345,7 +2357,7 @@ void helper_msa_fsune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_une(env, pwd, pws, pwt, df, 0);
compare_une(env, pwd, pws, pwt, df, 0, GETPC());
}
void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
@ -2354,7 +2366,7 @@ void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
compare_ne(env, pwd, pws, pwt, df, 0);
compare_ne(env, pwd, pws, pwt, df, 0, GETPC());
}
#define float16_is_zero(ARG) 0
@ -2404,7 +2416,7 @@ void helper_msa_fadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2434,7 +2446,7 @@ void helper_msa_fsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2464,7 +2476,7 @@ void helper_msa_fmul_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2495,7 +2507,7 @@ void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2542,7 +2554,7 @@ void helper_msa_fmadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2577,7 +2589,7 @@ void helper_msa_fmsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2614,7 +2626,7 @@ void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2666,7 +2678,7 @@ void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2712,7 +2724,7 @@ void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2791,7 +2803,7 @@ void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2822,7 +2834,7 @@ void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2865,7 +2877,7 @@ void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2896,7 +2908,7 @@ void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2958,7 +2970,7 @@ void helper_msa_ftrunc_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -2988,7 +3000,7 @@ void helper_msa_ftrunc_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3018,7 +3030,7 @@ void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3067,7 +3079,7 @@ void helper_msa_frsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3097,7 +3109,7 @@ void helper_msa_frcp_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3127,7 +3139,7 @@ void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3181,7 +3193,7 @@ void helper_msa_flog2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3216,7 +3228,7 @@ void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3250,7 +3262,7 @@ void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3331,7 +3343,7 @@ void helper_msa_ftint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3361,7 +3373,7 @@ void helper_msa_ftint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3397,7 +3409,7 @@ void helper_msa_ffint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}
@ -3427,7 +3439,7 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
assert(0);
}
check_msacsr_cause(env);
check_msacsr_cause(env, GETPC());
msa_move_v(pwd, pwx);
}

View File

@ -30,35 +30,6 @@ static inline void cpu_mips_tlb_flush (CPUMIPSState *env, int flush_global);
/*****************************************************************************/
/* Exceptions processing helpers */
static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
uint32_t exception,
int error_code,
uintptr_t pc)
{
CPUState *cs = CPU(mips_env_get_cpu(env));
if (exception < EXCP_SC) {
qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n",
__func__, exception, error_code);
}
cs->exception_index = exception;
env->error_code = error_code;
if (pc) {
/* now we have a real cpu fault */
cpu_restore_state(cs, pc);
}
cpu_loop_exit(cs);
}
static inline void QEMU_NORETURN do_raise_exception(CPUMIPSState *env,
uint32_t exception,
uintptr_t pc)
{
do_raise_exception_err(env, exception, 0, pc);
}
void helper_raise_exception_err(CPUMIPSState *env, uint32_t exception,
int error_code)
{
@ -66,6 +37,16 @@ void helper_raise_exception_err(CPUMIPSState *env, uint32_t exception,
}
void helper_raise_exception(CPUMIPSState *env, uint32_t exception)
{
do_raise_exception(env, exception, GETPC());
}
void helper_raise_exception_debug(CPUMIPSState *env)
{
do_raise_exception(env, EXCP_DEBUG, 0);
}
static void raise_exception(CPUMIPSState *env, uint32_t exception)
{
do_raise_exception(env, exception, 0);
}
@ -73,21 +54,21 @@ void helper_raise_exception(CPUMIPSState *env, uint32_t exception)
#if defined(CONFIG_USER_ONLY)
#define HELPER_LD(name, insn, type) \
static inline type do_##name(CPUMIPSState *env, target_ulong addr, \
int mem_idx) \
int mem_idx, uintptr_t retaddr) \
{ \
return (type) cpu_##insn##_data(env, addr); \
return (type) cpu_##insn##_data_ra(env, addr, retaddr); \
}
#else
#define HELPER_LD(name, insn, type) \
static inline type do_##name(CPUMIPSState *env, target_ulong addr, \
int mem_idx) \
int mem_idx, uintptr_t retaddr) \
{ \
switch (mem_idx) \
{ \
case 0: return (type) cpu_##insn##_kernel(env, addr); break; \
case 1: return (type) cpu_##insn##_super(env, addr); break; \
case 0: return (type) cpu_##insn##_kernel_ra(env, addr, retaddr); \
case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr); \
default: \
case 2: return (type) cpu_##insn##_user(env, addr); break; \
case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr); \
} \
}
#endif
@ -100,21 +81,21 @@ HELPER_LD(ld, ldq, int64_t)
#if defined(CONFIG_USER_ONLY)
#define HELPER_ST(name, insn, type) \
static inline void do_##name(CPUMIPSState *env, target_ulong addr, \
type val, int mem_idx) \
type val, int mem_idx, uintptr_t retaddr) \
{ \
cpu_##insn##_data(env, addr, val); \
cpu_##insn##_data_ra(env, addr, val, retaddr); \
}
#else
#define HELPER_ST(name, insn, type) \
static inline void do_##name(CPUMIPSState *env, target_ulong addr, \
type val, int mem_idx) \
type val, int mem_idx, uintptr_t retaddr) \
{ \
switch (mem_idx) \
{ \
case 0: cpu_##insn##_kernel(env, addr, val); break; \
case 1: cpu_##insn##_super(env, addr, val); break; \
case 0: cpu_##insn##_kernel_ra(env, addr, val, retaddr); break; \
case 1: cpu_##insn##_super_ra(env, addr, val, retaddr); break; \
default: \
case 2: cpu_##insn##_user(env, addr, val); break; \
case 2: cpu_##insn##_user_ra(env, addr, val, retaddr); break; \
} \
}
#endif
@ -293,14 +274,15 @@ target_ulong helper_bitswap(target_ulong rt)
static inline hwaddr do_translate_address(CPUMIPSState *env,
target_ulong address,
int rw)
int rw, uintptr_t retaddr)
{
hwaddr lladdr;
CPUState *cs = CPU(mips_env_get_cpu(env));
lladdr = cpu_mips_translate_address(env, address, rw);
if (lladdr == -1LL) {
cpu_loop_exit(CPU(mips_env_get_cpu(env)));
cpu_loop_exit_restore(cs, retaddr);
} else {
return lladdr;
}
@ -311,10 +293,10 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx) \
{ \
if (arg & almask) { \
env->CP0_BadVAddr = arg; \
helper_raise_exception(env, EXCP_AdEL); \
do_raise_exception(env, EXCP_AdEL, GETPC()); \
} \
env->lladdr = do_translate_address(env, arg, 0); \
env->llval = do_##insn(env, arg, mem_idx); \
env->lladdr = do_translate_address(env, arg, 0, GETPC()); \
env->llval = do_##insn(env, arg, mem_idx, GETPC()); \
return env->llval; \
}
HELPER_LD_ATOMIC(ll, lw, 0x3)
@ -331,12 +313,12 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1, \
\
if (arg2 & almask) { \
env->CP0_BadVAddr = arg2; \
helper_raise_exception(env, EXCP_AdES); \
do_raise_exception(env, EXCP_AdES, GETPC()); \
} \
if (do_translate_address(env, arg2, 1) == env->lladdr) { \
tmp = do_##ld_insn(env, arg2, mem_idx); \
if (do_translate_address(env, arg2, 1, GETPC()) == env->lladdr) { \
tmp = do_##ld_insn(env, arg2, mem_idx, GETPC()); \
if (tmp == env->llval) { \
do_##st_insn(env, arg2, arg1, mem_idx); \
do_##st_insn(env, arg2, arg1, mem_idx, GETPC()); \
return 1; \
} \
} \
@ -360,31 +342,43 @@ HELPER_ST_ATOMIC(scd, ld, sd, 0x7)
void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
int mem_idx)
{
do_sb(env, arg2, (uint8_t)(arg1 >> 24), mem_idx);
do_sb(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC());
if (GET_LMASK(arg2) <= 2)
do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16), mem_idx);
if (GET_LMASK(arg2) <= 2) {
do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16), mem_idx,
GETPC());
}
if (GET_LMASK(arg2) <= 1)
do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8), mem_idx);
if (GET_LMASK(arg2) <= 1) {
do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8), mem_idx,
GETPC());
}
if (GET_LMASK(arg2) == 0)
do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)arg1, mem_idx);
if (GET_LMASK(arg2) == 0) {
do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)arg1, mem_idx,
GETPC());
}
}
void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
int mem_idx)
{
do_sb(env, arg2, (uint8_t)arg1, mem_idx);
do_sb(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
if (GET_LMASK(arg2) >= 1)
do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
if (GET_LMASK(arg2) >= 1) {
do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx,
GETPC());
}
if (GET_LMASK(arg2) >= 2)
do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
if (GET_LMASK(arg2) >= 2) {
do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx,
GETPC());
}
if (GET_LMASK(arg2) == 3)
do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
if (GET_LMASK(arg2) == 3) {
do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx,
GETPC());
}
}
#if defined(TARGET_MIPS64)
@ -400,55 +394,83 @@ void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
int mem_idx)
{
do_sb(env, arg2, (uint8_t)(arg1 >> 56), mem_idx);
do_sb(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC());
if (GET_LMASK64(arg2) <= 6)
do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48), mem_idx);
if (GET_LMASK64(arg2) <= 6) {
do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) <= 5)
do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40), mem_idx);
if (GET_LMASK64(arg2) <= 5) {
do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) <= 4)
do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32), mem_idx);
if (GET_LMASK64(arg2) <= 4) {
do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) <= 3)
do_sb(env, GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24), mem_idx);
if (GET_LMASK64(arg2) <= 3) {
do_sb(env, GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) <= 2)
do_sb(env, GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16), mem_idx);
if (GET_LMASK64(arg2) <= 2) {
do_sb(env, GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) <= 1)
do_sb(env, GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8), mem_idx);
if (GET_LMASK64(arg2) <= 1) {
do_sb(env, GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) <= 0)
do_sb(env, GET_OFFSET(arg2, 7), (uint8_t)arg1, mem_idx);
if (GET_LMASK64(arg2) <= 0) {
do_sb(env, GET_OFFSET(arg2, 7), (uint8_t)arg1, mem_idx,
GETPC());
}
}
void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
int mem_idx)
{
do_sb(env, arg2, (uint8_t)arg1, mem_idx);
do_sb(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
if (GET_LMASK64(arg2) >= 1)
do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
if (GET_LMASK64(arg2) >= 1) {
do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) >= 2)
do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
if (GET_LMASK64(arg2) >= 2) {
do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) >= 3)
do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
if (GET_LMASK64(arg2) >= 3) {
do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) >= 4)
do_sb(env, GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32), mem_idx);
if (GET_LMASK64(arg2) >= 4) {
do_sb(env, GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) >= 5)
do_sb(env, GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40), mem_idx);
if (GET_LMASK64(arg2) >= 5) {
do_sb(env, GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) >= 6)
do_sb(env, GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48), mem_idx);
if (GET_LMASK64(arg2) >= 6) {
do_sb(env, GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48), mem_idx,
GETPC());
}
if (GET_LMASK64(arg2) == 7)
do_sb(env, GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56), mem_idx);
if (GET_LMASK64(arg2) == 7) {
do_sb(env, GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56), mem_idx,
GETPC());
}
}
#endif /* TARGET_MIPS64 */
@ -465,13 +487,14 @@ void helper_lwm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
for (i = 0; i < base_reglist; i++) {
env->active_tc.gpr[multiple_regs[i]] =
(target_long)do_lw(env, addr, mem_idx);
(target_long)do_lw(env, addr, mem_idx, GETPC());
addr += 4;
}
}
if (do_r31) {
env->active_tc.gpr[31] = (target_long)do_lw(env, addr, mem_idx);
env->active_tc.gpr[31] = (target_long)do_lw(env, addr, mem_idx,
GETPC());
}
}
@ -485,13 +508,14 @@ void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
target_ulong i;
for (i = 0; i < base_reglist; i++) {
do_sw(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx);
do_sw(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx,
GETPC());
addr += 4;
}
}
if (do_r31) {
do_sw(env, addr, env->active_tc.gpr[31], mem_idx);
do_sw(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
}
}
@ -506,13 +530,14 @@ void helper_ldm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
target_ulong i;
for (i = 0; i < base_reglist; i++) {
env->active_tc.gpr[multiple_regs[i]] = do_ld(env, addr, mem_idx);
env->active_tc.gpr[multiple_regs[i]] = do_ld(env, addr, mem_idx,
GETPC());
addr += 8;
}
}
if (do_r31) {
env->active_tc.gpr[31] = do_ld(env, addr, mem_idx);
env->active_tc.gpr[31] = do_ld(env, addr, mem_idx, GETPC());
}
}
@ -526,13 +551,14 @@ void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
target_ulong i;
for (i = 0; i < base_reglist; i++) {
do_sd(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx);
do_sd(env, addr, env->active_tc.gpr[multiple_regs[i]], mem_idx,
GETPC());
addr += 8;
}
}
if (do_r31) {
do_sd(env, addr, env->active_tc.gpr[31], mem_idx);
do_sd(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
}
}
#endif
@ -1792,13 +1818,13 @@ target_ulong helper_yield(CPUMIPSState *env, target_ulong arg)
env->active_tc.CP0_TCStatus & (1 << CP0TCSt_DT)) {
env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
helper_raise_exception(env, EXCP_THREAD);
do_raise_exception(env, EXCP_THREAD, GETPC());
}
}
} else if (arg1 == 0) {
if (0 /* TODO: TC underflow */) {
env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
helper_raise_exception(env, EXCP_THREAD);
do_raise_exception(env, EXCP_THREAD, GETPC());
} else {
// TODO: Deallocate TC
}
@ -1806,7 +1832,7 @@ target_ulong helper_yield(CPUMIPSState *env, target_ulong arg)
/* Yield qualifier inputs not implemented. */
env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
helper_raise_exception(env, EXCP_THREAD);
do_raise_exception(env, EXCP_THREAD, GETPC());
}
return env->CP0_YQMask;
}
@ -2165,7 +2191,7 @@ target_ulong helper_rdhwr_cpunum(CPUMIPSState *env)
(env->CP0_HWREna & (1 << 0)))
return env->CP0_EBase & 0x3ff;
else
helper_raise_exception(env, EXCP_RI);
do_raise_exception(env, EXCP_RI, GETPC());
return 0;
}
@ -2176,7 +2202,7 @@ target_ulong helper_rdhwr_synci_step(CPUMIPSState *env)
(env->CP0_HWREna & (1 << 1)))
return env->SYNCI_Step;
else
helper_raise_exception(env, EXCP_RI);
do_raise_exception(env, EXCP_RI, GETPC());
return 0;
}
@ -2191,7 +2217,7 @@ target_ulong helper_rdhwr_cc(CPUMIPSState *env)
return (int32_t)cpu_mips_get_count(env);
#endif
} else {
helper_raise_exception(env, EXCP_RI);
do_raise_exception(env, EXCP_RI, GETPC());
}
return 0;
@ -2203,7 +2229,7 @@ target_ulong helper_rdhwr_ccres(CPUMIPSState *env)
(env->CP0_HWREna & (1 << 3)))
return env->CCRes;
else
helper_raise_exception(env, EXCP_RI);
do_raise_exception(env, EXCP_RI, GETPC());
return 0;
}
@ -2240,7 +2266,9 @@ void helper_wait(CPUMIPSState *env)
cs->halted = 1;
cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE);
helper_raise_exception(env, EXCP_HLT);
/* Last instruction in the block, PC was updated before
- no need to recover PC and icount */
raise_exception(env, EXCP_HLT);
}
#if !defined(CONFIG_USER_ONLY)
@ -2301,9 +2329,9 @@ void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
}
if (is_exec) {
helper_raise_exception(env, EXCP_IBE);
raise_exception(env, EXCP_IBE);
} else {
helper_raise_exception(env, EXCP_DBE);
raise_exception(env, EXCP_DBE);
}
}
#endif /* !CONFIG_USER_ONLY */
@ -2338,7 +2366,7 @@ target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
arg1 = (int32_t)
((env->CP0_Status & (1 << CP0St_FR)) >> CP0St_FR);
} else {
helper_raise_exception(env, EXCP_RI);
do_raise_exception(env, EXCP_RI, GETPC());
}
}
break;
@ -2381,7 +2409,7 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
env->CP0_Status &= ~(1 << CP0St_FR);
compute_hflags(env);
} else {
helper_raise_exception(env, EXCP_RI);
do_raise_exception(env, EXCP_RI, GETPC());
}
break;
case 4:
@ -2393,7 +2421,7 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
env->CP0_Status |= (1 << CP0St_FR);
compute_hflags(env);
} else {
helper_raise_exception(env, EXCP_RI);
do_raise_exception(env, EXCP_RI, GETPC());
}
break;
case 5:

File diff suppressed because it is too large Load Diff