提交 84afc4dd 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/lalrae/tags/mips-20141216' into staging

* remotes/lalrae/tags/mips-20141216: (30 commits)
  target-mips: remove excp_names[] from linux-user as it is unused
  disas/mips: disable unused mips16_to_32_reg_map[]
  disas/mips: remove unused mips_msa_control_names_numeric[32]
  target-mips: convert single case switch into if statement
  target-mips: Fix DisasContext's ulri member initialization
  target-mips: Use local float status pointer across MSA macros
  target-mips: Add missing calls to synchronise SoftFloat status
  linux-user: Use the 5KEf processor for 64-bit emulation
  target-mips: Also apply the CP0.Status mask to MTTC0
  target-mips: gdbstub: Clean up FPU register handling
  target-mips: Correct 32-bit address space wrapping
  target-mips: Tighten ISA level checks
  target-mips: Fix CP0.Config3.ISAOnExc write accesses
  target-mips: Output CP0.Config2-5 in the register dump
  target-mips: Fix the 64-bit case for microMIPS MOVE16 and MOVEP
  target-mips: Correct the writes to Status and Cause registers via gdbstub
  target-mips: Correct the handling of writes to CP0.Status for MIPSr6
  target-mips: Correct MIPS16/microMIPS branch size calculation
  target-mips: Restore the order of helpers
  target-mips: Remove unused `FLOAT_OP' macro
  ...
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -3511,6 +3511,7 @@ struct mips_cp0sel_name
const char * const name;
};
#if 0
/* The mips16 registers. */
static const unsigned int mips16_to_32_reg_map[] =
{
......@@ -3518,7 +3519,7 @@ static const unsigned int mips16_to_32_reg_map[] =
};
#define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]]
#endif
static const char * const mips_gpr_names_numeric[32] =
{
......@@ -3801,13 +3802,6 @@ static const char * const mips_hwr_names_mips3264r2[32] =
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
};
static const char * const mips_msa_control_names_numeric[32] = {
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
};
static const char * const mips_msa_control_names_mips3264r2[32] = {
"MSAIR", "MSACSR", "$2", "$3", "$4", "$5", "$6", "$7",
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
......
......@@ -3905,7 +3905,7 @@ int main(int argc, char **argv, char **envp)
#endif
#elif defined(TARGET_MIPS)
#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
cpu_model = "20Kc";
cpu_model = "5KEf";
#else
cpu_model = "24Kf";
#endif
......
......@@ -446,8 +446,8 @@ struct CPUMIPSState {
#define CP0C3_MT 2
#define CP0C3_SM 1
#define CP0C3_TL 0
uint32_t CP0_Config4;
uint32_t CP0_Config4_rw_bitmask;
int32_t CP0_Config4;
int32_t CP0_Config4_rw_bitmask;
#define CP0C4_M 31
#define CP0C4_IE 29
#define CP0C4_KScrExist 16
......@@ -456,8 +456,8 @@ struct CPUMIPSState {
#define CP0C4_FTLBWays 4
#define CP0C4_FTLBSets 0
#define CP0C4_MMUSizeExt 0
uint32_t CP0_Config5;
uint32_t CP0_Config5_rw_bitmask;
int32_t CP0_Config5;
int32_t CP0_Config5_rw_bitmask;
#define CP0C5_M 31
#define CP0C5_K 30
#define CP0C5_CV 29
......@@ -777,6 +777,18 @@ target_ulong exception_resume_pc (CPUMIPSState *env);
extern unsigned int ieee_rm[];
int ieee_ex_to_mips(int xcpt);
static inline void restore_rounding_mode(CPUMIPSState *env)
{
set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3],
&env->active_fpu.fp_status);
}
static inline void restore_flush_mode(CPUMIPSState *env)
{
set_flush_to_zero((env->active_fpu.fcr31 & (1 << 24)) != 0,
&env->active_fpu.fp_status);
}
static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
......@@ -831,16 +843,19 @@ static inline void compute_hflags(CPUMIPSState *env)
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))) {
if ((env->insn_flags & ISA_MIPS3) &&
(((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->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->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
!(env->CP0_Status & (1 << CP0St_UX))) {
env->hflags |= MIPS_HFLAG_AWRAP;
} else if (env->insn_flags & ISA_MIPS32R6) {
} 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))) ||
......@@ -904,4 +919,93 @@ static inline void compute_hflags(CPUMIPSState *env)
}
}
#ifndef CONFIG_USER_ONLY
/* Called for updates to CP0_Status. */
static inline void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc)
{
int32_t tcstatus, *tcst;
uint32_t v = cpu->CP0_Status;
uint32_t cu, mx, asid, ksu;
uint32_t mask = ((1 << CP0TCSt_TCU3)
| (1 << CP0TCSt_TCU2)
| (1 << CP0TCSt_TCU1)
| (1 << CP0TCSt_TCU0)
| (1 << CP0TCSt_TMX)
| (3 << CP0TCSt_TKSU)
| (0xff << CP0TCSt_TASID));
cu = (v >> CP0St_CU0) & 0xf;
mx = (v >> CP0St_MX) & 0x1;
ksu = (v >> CP0St_KSU) & 0x3;
asid = env->CP0_EntryHi & 0xff;
tcstatus = cu << CP0TCSt_TCU0;
tcstatus |= mx << CP0TCSt_TMX;
tcstatus |= ksu << CP0TCSt_TKSU;
tcstatus |= asid;
if (tc == cpu->current_tc) {
tcst = &cpu->active_tc.CP0_TCStatus;
} else {
tcst = &cpu->tcs[tc].CP0_TCStatus;
}
*tcst &= ~mask;
*tcst |= tcstatus;
compute_hflags(cpu);
}
static inline void cpu_mips_store_status(CPUMIPSState *env, target_ulong val)
{
uint32_t mask = env->CP0_Status_rw_bitmask;
if (env->insn_flags & ISA_MIPS32R6) {
bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3;
if (has_supervisor && extract32(val, CP0St_KSU, 2) == 0x3) {
mask &= ~(3 << CP0St_KSU);
}
mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val);
}
env->CP0_Status = (env->CP0_Status & ~mask) | (val & mask);
if (env->CP0_Config3 & (1 << CP0C3_MT)) {
sync_c0_status(env, env, env->current_tc);
} else {
compute_hflags(env);
}
}
static inline void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val)
{
uint32_t mask = 0x00C00300;
uint32_t old = env->CP0_Cause;
int i;
if (env->insn_flags & ISA_MIPS32R2) {
mask |= 1 << CP0Ca_DC;
}
if (env->insn_flags & ISA_MIPS32R6) {
mask &= ~((1 << CP0Ca_WP) & val);
}
env->CP0_Cause = (env->CP0_Cause & ~mask) | (val & mask);
if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
if (env->CP0_Cause & (1 << CP0Ca_DC)) {
cpu_mips_stop_count(env);
} else {
cpu_mips_start_count(env);
}
}
/* Set/reset software interrupts */
for (i = 0 ; i < 2 ; i++) {
if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i)));
}
}
}
#endif
#endif /* !defined (__MIPS_CPU_H__) */
......@@ -29,8 +29,13 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
if (n < 32) {
return gdb_get_regl(mem_buf, env->active_tc.gpr[n]);
}
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
if (n >= 38 && n < 70) {
if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 72) {
switch (n) {
case 70:
return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr31);
case 71:
return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0);
default:
if (env->CP0_Status & (1 << CP0St_FR)) {
return gdb_get_regl(mem_buf,
env->active_fpu.fpr[n - 38].d);
......@@ -39,12 +44,6 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]);
}
}
switch (n) {
case 70:
return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr31);
case 71:
return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0);
}
}
switch (n) {
case 32:
......@@ -64,8 +63,10 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
return gdb_get_regl(mem_buf, 0); /* fp */
case 89:
return gdb_get_regl(mem_buf, (int32_t)env->CP0_PRid);
}
if (n >= 73 && n <= 88) {
default:
if (n > 89) {
return 0;
}
/* 16 embedded regs. */
return gdb_get_regl(mem_buf, 0);
}
......@@ -73,10 +74,6 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
return 0;
}
#define RESTORE_ROUNDING_MODE \
set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], \
&env->active_fpu.fp_status)
int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
MIPSCPU *cpu = MIPS_CPU(cs);
......@@ -89,30 +86,33 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
env->active_tc.gpr[n] = tmp;
return sizeof(target_ulong);
}
if (env->CP0_Config1 & (1 << CP0C1_FP)
&& n >= 38 && n < 73) {
if (n < 70) {
if (env->CP0_Status & (1 << CP0St_FR)) {
env->active_fpu.fpr[n - 38].d = tmp;
} else {
env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
}
}
if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 72) {
switch (n) {
case 70:
env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
/* set rounding mode */
RESTORE_ROUNDING_MODE;
restore_rounding_mode(env);
/* set flush-to-zero mode */
restore_flush_mode(env);
break;
case 71:
env->active_fpu.fcr0 = tmp;
/* FIR is read-only. Ignore writes. */
break;
default:
if (env->CP0_Status & (1 << CP0St_FR)) {
env->active_fpu.fpr[n - 38].d = tmp;
} else {
env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
}
break;
}
return sizeof(target_ulong);
}
switch (n) {
case 32:
env->CP0_Status = tmp;
#ifndef CONFIG_USER_ONLY
cpu_mips_store_status(env, tmp);
#endif
break;
case 33:
env->active_tc.LO[0] = tmp;
......@@ -124,7 +124,9 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
env->CP0_BadVAddr = tmp;
break;
case 36:
env->CP0_Cause = tmp;
#ifndef CONFIG_USER_ONLY
cpu_mips_store_cause(env, tmp);
#endif
break;
case 37:
env->active_tc.PC = tmp & ~(target_ulong)1;
......
......@@ -390,7 +390,6 @@ hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address, int r
return physical;
}
}
#endif
static const char * const excp_names[EXCP_LAST + 1] = {
[EXCP_RESET] = "reset",
......@@ -431,6 +430,7 @@ static const char * const excp_names[EXCP_LAST + 1] = {
[EXCP_MSADIS] = "MSA disabled",
[EXCP_MSAFPE] = "MSA floating point",
};
#endif
target_ulong exception_resume_pc (CPUMIPSState *env)
{
......@@ -529,7 +529,10 @@ void mips_cpu_do_interrupt(CPUState *cs)
env->CP0_DEPC = exception_resume_pc(env);
env->hflags &= ~MIPS_HFLAG_BMASK;
enter_debug_mode:
env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
if (env->insn_flags & ISA_MIPS3) {
env->hflags |= MIPS_HFLAG_64;
}
env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_CP0;
env->hflags &= ~(MIPS_HFLAG_KSU);
/* EJTAG probe trap enable is not implemented... */
if (!(env->CP0_Status & (1 << CP0St_EXL)))
......@@ -550,7 +553,10 @@ void mips_cpu_do_interrupt(CPUState *cs)
env->CP0_ErrorEPC = exception_resume_pc(env);
env->hflags &= ~MIPS_HFLAG_BMASK;
env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
if (env->insn_flags & ISA_MIPS3) {
env->hflags |= MIPS_HFLAG_64;
}
env->hflags |= MIPS_HFLAG_CP0;
env->hflags &= ~(MIPS_HFLAG_KSU);
if (!(env->CP0_Status & (1 << CP0St_EXL)))
env->CP0_Cause &= ~(1U << CP0Ca_BD);
......@@ -728,7 +734,10 @@ void mips_cpu_do_interrupt(CPUState *cs)
env->CP0_Cause &= ~(1U << CP0Ca_BD);
}
env->CP0_Status |= (1 << CP0St_EXL);
env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0;
if (env->insn_flags & ISA_MIPS3) {
env->hflags |= MIPS_HFLAG_64;
}
env->hflags |= MIPS_HFLAG_CP0;
env->hflags &= ~(MIPS_HFLAG_KSU);
}
env->hflags &= ~MIPS_HFLAG_BMASK;
......
......@@ -137,6 +137,7 @@ DEF_HELPER_2(mtc0_ebase, void, env, tl)
DEF_HELPER_2(mttc0_ebase, void, env, tl)
DEF_HELPER_2(mtc0_config0, void, env, tl)
DEF_HELPER_2(mtc0_config2, void, env, tl)
DEF_HELPER_2(mtc0_config3, void, env, tl)
DEF_HELPER_2(mtc0_config4, void, env, tl)
DEF_HELPER_2(mtc0_config5, void, env, tl)
DEF_HELPER_2(mtc0_lladdr, void, env, tl)
......
......@@ -1782,15 +1782,14 @@ static inline int32 float64_to_q32(float64 a STATUS_PARAM)
#define MSA_FLOAT_COND(DEST, OP, ARG1, ARG2, BITS, QUIET) \
do { \
float_status *status = &env->active_tc.msa_fp_status; \
int c; \
int64_t cond; \
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
set_float_exception_flags(0, status); \
if (!QUIET) { \
cond = float ## BITS ## _ ## OP(ARG1, ARG2, \
&env->active_tc.msa_fp_status); \
cond = float ## BITS ## _ ## OP(ARG1, ARG2, status); \
} else { \
cond = float ## BITS ## _ ## OP ## _quiet(ARG1, ARG2, \
&env->active_tc.msa_fp_status); \
cond = float ## BITS ## _ ## OP ## _quiet(ARG1, ARG2, status); \
} \
DEST = cond ? M_MAX_UINT(BITS) : 0; \
c = update_msacsr(env, CLEAR_IS_INEXACT, 0); \
......@@ -2375,11 +2374,11 @@ void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
#define MSA_FLOAT_BINOP(DEST, OP, ARG1, ARG2, BITS) \
do { \
float_status *status = &env->active_tc.msa_fp_status; \
int c; \
\
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
DEST = float ## BITS ## _ ## OP(ARG1, ARG2, \
&env->active_tc.msa_fp_status); \
set_float_exception_flags(0, status); \
DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status); \
c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
\
if (get_enabled_exceptions(env, c)) { \
......@@ -2511,11 +2510,11 @@ void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
#define MSA_FLOAT_MULADD(DEST, ARG1, ARG2, ARG3, NEGATE, BITS) \
do { \
float_status *status = &env->active_tc.msa_fp_status; \
int c; \
\
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
DEST = float ## BITS ## _muladd(ARG2, ARG3, ARG1, NEGATE, \
&env->active_tc.msa_fp_status); \
set_float_exception_flags(0, status); \
DEST = float ## BITS ## _muladd(ARG2, ARG3, ARG1, NEGATE, status); \
c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
\
if (get_enabled_exceptions(env, c)) { \
......@@ -2630,10 +2629,11 @@ void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
#define MSA_FLOAT_UNOP(DEST, OP, ARG, BITS) \
do { \
float_status *status = &env->active_tc.msa_fp_status; \
int c; \
\
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
DEST = float ## BITS ## _ ## OP(ARG, &env->active_tc.msa_fp_status);\
set_float_exception_flags(0, status); \
DEST = float ## BITS ## _ ## OP(ARG, status); \
c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
\
if (get_enabled_exceptions(env, c)) { \
......@@ -2678,10 +2678,11 @@ void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
#define MSA_FLOAT_UNOP_XD(DEST, OP, ARG, BITS, XBITS) \
do { \
float_status *status = &env->active_tc.msa_fp_status; \
int c; \
\
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
DEST = float ## BITS ## _ ## OP(ARG, &env->active_tc.msa_fp_status);\
set_float_exception_flags(0, status); \
DEST = float ## BITS ## _ ## OP(ARG, status); \
c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0); \
\
if (get_enabled_exceptions(env, c)) { \
......@@ -2728,11 +2729,11 @@ void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
#define MSA_FLOAT_MAXOP(DEST, OP, ARG1, ARG2, BITS) \
do { \
float_status *status = &env->active_tc.msa_fp_status; \
int c; \
\
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
DEST = float ## BITS ## _ ## OP(ARG1, ARG2, \
&env->active_tc.msa_fp_status); \
set_float_exception_flags(0, status); \
DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status); \
c = update_msacsr(env, 0, 0); \
\
if (get_enabled_exceptions(env, c)) { \
......@@ -2924,10 +2925,11 @@ void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
#define MSA_FLOAT_UNOP0(DEST, OP, ARG, BITS) \
do { \
float_status *status = &env->active_tc.msa_fp_status; \
int c; \
\
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
DEST = float ## BITS ## _ ## OP(ARG, &env->active_tc.msa_fp_status);\
set_float_exception_flags(0, status); \
DEST = float ## BITS ## _ ## OP(ARG, status); \
c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0); \
\
if (get_enabled_exceptions(env, c)) { \
......@@ -3029,11 +3031,11 @@ void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
#define MSA_FLOAT_RECIPROCAL(DEST, ARG, BITS) \
do { \
float_status *status = &env->active_tc.msa_fp_status; \
int c; \
\
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, \
&env->active_tc.msa_fp_status); \
set_float_exception_flags(0, status); \
DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, status); \
c = update_msacsr(env, float ## BITS ## _is_infinity(ARG) || \
float ## BITS ## _is_quiet_nan(DEST) ? \
0 : RECIPROCAL_INEXACT, \
......@@ -3138,23 +3140,20 @@ void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
#define MSA_FLOAT_LOGB(DEST, ARG, BITS) \
do { \
float_status *status = &env->active_tc.msa_fp_status; \
int c; \
\
set_float_exception_flags(0, &env->active_tc.msa_fp_status); \
set_float_rounding_mode(float_round_down, \
&env->active_tc.msa_fp_status); \
DEST = float ## BITS ## _ ## log2(ARG, \
&env->active_tc.msa_fp_status); \
DEST = float ## BITS ## _ ## round_to_int(DEST, \
&env->active_tc.msa_fp_status); \
set_float_exception_flags(0, status); \
set_float_rounding_mode(float_round_down, status); \
DEST = float ## BITS ## _ ## log2(ARG, status); \
DEST = float ## BITS ## _ ## round_to_int(DEST, status); \
set_float_rounding_mode(ieee_rm[(env->active_tc.msacsr & \
MSACSR_RM_MASK) >> MSACSR_RM], \
&env->active_tc.msa_fp_status); \
status); \
\
set_float_exception_flags( \
get_float_exception_flags(&env->active_tc.msa_fp_status) \
& (~float_flag_inexact), \
&env->active_tc.msa_fp_status); \
set_float_exception_flags(get_float_exception_flags(status) & \
(~float_flag_inexact), \
status); \
\
c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
\
......
此差异已折叠。
此差异已折叠。
......@@ -334,7 +334,7 @@ static const mips_def_t mips_defs[] =
(1 << CP0C1_CA),
.CP0_Config2 = MIPS_CONFIG2,
.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) |
(0 << CP0C3_VInt),
(1 << CP0C3_VInt),
.CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 4,
.SYNCI_Step = 32,
......@@ -347,6 +347,47 @@ static const mips_def_t mips_defs[] =
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_DSPR2,
.mmu_type = MMU_TYPE_R4000,
},
{
.name = "M14K",
.CP0_PRid = 0x00019b00,
/* Config1 implemented, fixed mapping MMU,
no virtual icache, uncached coherency. */
.CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_KU) | (0x2 << CP0C0_K23) |
(0x1 << CP0C0_AR) | (MMU_TYPE_FMT << CP0C0_MT),
.CP0_Config1 = MIPS_CONFIG1,
.CP0_Config2 = MIPS_CONFIG2,
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (1 << CP0C3_VInt),
.CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 4,
.SYNCI_Step = 32,
.CCRes = 2,
.CP0_Status_rw_bitmask = 0x1258FF17,
.SEGBITS = 32,
.PABITS = 32,
.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS,
.mmu_type = MMU_TYPE_FMT,
},
{
.name = "M14Kc",
/* This is the TLB-based MMU core. */
.CP0_PRid = 0x00019c00,
.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
(MMU_TYPE_R4000 << CP0C0_MT),
.CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
(0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
(0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
.CP0_Config2 = MIPS_CONFIG2,
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (0 << CP0C3_VInt),
.CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 4,
.SYNCI_Step = 32,
.CCRes = 2,
.CP0_Status_rw_bitmask = 0x1278FF17,
.SEGBITS = 32,
.PABITS = 32,
.insn_flags = CPU_MIPS32R2 | ASE_MICROMIPS,
.mmu_type = MMU_TYPE_R4000,
},
{
/* A generic CPU providing MIPS32 Release 5 features.
FIXME: Eventually this should be replaced by a real CPU model. */
......@@ -519,6 +560,51 @@ static const mips_def_t mips_defs[] =
.insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
.mmu_type = MMU_TYPE_R4000,
},
{
.name = "5KEc",
.CP0_PRid = 0x00018900,
.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
(MMU_TYPE_R4000 << CP0C0_MT),
.CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) |
(1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
(1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
(1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
.CP0_Config2 = MIPS_CONFIG2,
.CP0_Config3 = MIPS_CONFIG3,
.CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 4,
.SYNCI_Step = 32,
.CCRes = 2,
.CP0_Status_rw_bitmask = 0x32F8FFFF,
.SEGBITS = 42,
.PABITS = 36,
.insn_flags = CPU_MIPS64R2,
.mmu_type = MMU_TYPE_R4000,
},
{
.name = "5KEf",
.CP0_PRid = 0x00018900,
.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
(MMU_TYPE_R4000 << CP0C0_MT),
.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) |
(1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
(1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
(1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
.CP0_Config2 = MIPS_CONFIG2,
.CP0_Config3 = MIPS_CONFIG3,
.CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 4,
.SYNCI_Step = 32,
.CCRes = 2,
.CP0_Status_rw_bitmask = 0x36F8FFFF,
.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
(1 << FCR0_D) | (1 << FCR0_S) |
(0x89 << FCR0_PRID) | (0x0 << FCR0_REV),
.SEGBITS = 42,
.PABITS = 36,
.insn_flags = CPU_MIPS64R2,
.mmu_type = MMU_TYPE_R4000,
},
{
/* A generic CPU supporting MIPS64 Release 6 ISA.
FIXME: Support IEEE 754-2008 FP and misaligned memory accesses.
......@@ -559,10 +645,11 @@ static const mips_def_t mips_defs[] =
{
.name = "Loongson-2E",
.CP0_PRid = 0x6302,
/*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
.CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) |
(0x1<<4) | (0x1<<1),
/* Note: Config1 is only used internally, Loongson-2E has only Config0. */
/* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */
.CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) |
(0x1<<5) | (0x1<<4) | (0x1<<1),
/* Note: Config1 is only used internally,
Loongson-2E has only Config0. */
.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
.SYNCI_Step = 16,
.CCRes = 2,
......@@ -574,21 +661,22 @@ static const mips_def_t mips_defs[] =
.mmu_type = MMU_TYPE_R4000,
},
{
.name = "Loongson-2F",
.CP0_PRid = 0x6303,
/*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
.CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) |
(0x1<<4) | (0x1<<1),
/* Note: Config1 is only used internally, Loongson-2F has only Config0. */
.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
.SYNCI_Step = 16,
.CCRes = 2,
.CP0_Status_rw_bitmask = 0xF5D0FF1F, /*bit5:7 not writable*/
.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
.SEGBITS = 40,
.PABITS = 40,
.insn_flags = CPU_LOONGSON2F,
.mmu_type = MMU_TYPE_R4000,
.name = "Loongson-2F",
.CP0_PRid = 0x6303,
/* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */
.CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) |
(0x1<<5) | (0x1<<4) | (0x1<<1),
/* Note: Config1 is only used internally,
Loongson-2F has only Config0. */
.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
.SYNCI_Step = 16,
.CCRes = 2,
.CP0_Status_rw_bitmask = 0xF5D0FF1F, /* Bits 7:5 not writable. */
.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
.SEGBITS = 40,
.PABITS = 40,
.insn_flags = CPU_LOONGSON2F,
.mmu_type = MMU_TYPE_R4000,
},
{
/* A generic CPU providing MIPS64 ASE DSP 2 features.
......
......@@ -1540,7 +1540,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
branch. */
#if defined(TARGET_MIPS)
if ((env->hflags & MIPS_HFLAG_BMASK) != 0 && n > 1) {
env->active_tc.PC -= 4;
env->active_tc.PC -= (env->hflags & MIPS_HFLAG_B16 ? 2 : 4);
cpu->icount_decr.u16.low++;
env->hflags &= ~MIPS_HFLAG_BMASK;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册