mirror of https://gitee.com/openkylin/qemu.git
MIPS patches 2015-09-18
Changes: * fixes for rdhwr, tlbwr, mtc0, recip.fmt, rsqrt.fmt and daui instructions * removal of MIPS_DEBUG code * use tcg_gen_extrh_i64_i32() * improve random tlb index generation in cpu_mips_get_random() * exception handling improvements to correctly restore icount -----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJV+/JQAAoJEFIRjjwLKdprNboH/3w5bd/PpHqG7HW8kZpf/Vhb DQwvbMDC20PulIieYl3+FQTu/G4X1Vio1MNmbb40g9E/ddoqnYnTfpZry8Fa6beZ ZgSdVZt0F0T9XS1BcAyQdpzdi9fefwWZrJUaHMvTTL68Qc8Y4R+4CAuSmsi0JsFZ euKQlEQCxFzB+hUSZoBYmo/gFVzJUkWXbl5qr82uWW7nlycv7uSe/bopTZvT30ad EbJvqs8Eok8FRIZP+Qr5wDejjOYpXTNaOocPV1rcXT9Ffb5ozeq6Qp2uXQJEjbJb kNX9IIEUVH4rE6w80xOVVDVXTypHYvRYWnLvsys/sF0tuVFWwDYRn2n37xU0bew= =VsAJ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/lalrae/tags/mips-20150918' into staging MIPS patches 2015-09-18 Changes: * fixes for rdhwr, tlbwr, mtc0, recip.fmt, rsqrt.fmt and daui instructions * removal of MIPS_DEBUG code * use tcg_gen_extrh_i64_i32() * improve random tlb index generation in cpu_mips_get_random() * exception handling improvements to correctly restore icount # gpg: Signature made Fri 18 Sep 2015 12:15:28 BST using RSA key ID 0B29DA6B # gpg: Good signature from "Leon Alrae <leon.alrae@imgtec.com>" * remotes/lalrae/tags/mips-20150918: target-mips: improve exception handling target-mips: correct MTC0 instruction on MIPS64 target-mips: add missing restriction in DAUI instruction target-mips: fix corner case in TLBWR causing QEMU to hang pic32: use LCG algorithm for generated random index of TLBWR instruction target-mips: get rid of MIPS_DEBUG_SIGN_EXTENSIONS target-mips: get rid of MIPS_DEBUG target-mips: Fix RDHWR on CP0.Count target-mips: remove wrong checks for recip.fmt and rsqrt.fmt target-mips: Use tcg_gen_extrh_i64_i32 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3bf1f5ec6a
|
@ -30,13 +30,21 @@
|
|||
/* XXX: do not use a global */
|
||||
uint32_t cpu_mips_get_random (CPUMIPSState *env)
|
||||
{
|
||||
static uint32_t lfsr = 1;
|
||||
static uint32_t seed = 1;
|
||||
static uint32_t prev_idx = 0;
|
||||
uint32_t idx;
|
||||
uint32_t nb_rand_tlb = env->tlb->nb_tlb - env->CP0_Wired;
|
||||
|
||||
if (nb_rand_tlb == 1) {
|
||||
return env->tlb->nb_tlb - 1;
|
||||
}
|
||||
|
||||
/* Don't return same value twice, so get another value */
|
||||
do {
|
||||
lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u);
|
||||
idx = lfsr % (env->tlb->nb_tlb - env->CP0_Wired) + env->CP0_Wired;
|
||||
/* Use a simple algorithm of Linear Congruential Generator
|
||||
* from ISO/IEC 9899 standard. */
|
||||
seed = 1103515245 * seed + 12345;
|
||||
idx = (seed >> 16) % nb_rand_tlb + env->CP0_Wired;
|
||||
} while (idx == prev_idx);
|
||||
prev_idx = idx;
|
||||
return idx;
|
||||
|
|
|
@ -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__) */
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -2184,10 +2210,15 @@ target_ulong helper_rdhwr_synci_step(CPUMIPSState *env)
|
|||
target_ulong helper_rdhwr_cc(CPUMIPSState *env)
|
||||
{
|
||||
if ((env->hflags & MIPS_HFLAG_CP0) ||
|
||||
(env->CP0_HWREna & (1 << 2)))
|
||||
(env->CP0_HWREna & (1 << 2))) {
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
return env->CP0_Count;
|
||||
else
|
||||
helper_raise_exception(env, EXCP_RI);
|
||||
#else
|
||||
return (int32_t)cpu_mips_get_count(env);
|
||||
#endif
|
||||
} else {
|
||||
do_raise_exception(env, EXCP_RI, GETPC());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2198,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;
|
||||
}
|
||||
|
@ -2235,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)
|
||||
|
@ -2296,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 */
|
||||
|
@ -2333,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;
|
||||
|
@ -2376,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:
|
||||
|
@ -2388,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
Loading…
Reference in New Issue