提交 e189e748 编写于 作者: T ths

Per-CPU instruction decoding implementation, by Aurelien Jarno.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3228 c046a42c-6fe2-441c-8c8c-71466251a162
上级 92a34c10
......@@ -441,6 +441,7 @@ struct CPUMIPSState {
int CCRes; /* Cycle count resolution/divisor */
uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */
uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */
int insn_flags; /* Supported instruction set */
#ifdef CONFIG_USER_ONLY
target_ulong tls_value;
......
......@@ -369,8 +369,7 @@ void do_interrupt (CPUState *env)
}
enter_debug_mode:
env->hflags |= MIPS_HFLAG_DM;
if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
env->hflags |= MIPS_HFLAG_64;
env->hflags |= MIPS_HFLAG_64;
env->hflags &= ~MIPS_HFLAG_UM;
/* EJTAG probe trap enable is not implemented... */
if (!(env->CP0_Status & (1 << CP0St_EXL)))
......@@ -396,8 +395,7 @@ void do_interrupt (CPUState *env)
env->CP0_ErrorEPC = env->PC[env->current_tc];
}
env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
env->hflags |= MIPS_HFLAG_64;
env->hflags |= MIPS_HFLAG_64;
env->hflags &= ~MIPS_HFLAG_UM;
if (!(env->CP0_Status & (1 << CP0St_EXL)))
env->CP0_Cause &= ~(1 << CP0Ca_BD);
......@@ -499,8 +497,7 @@ void do_interrupt (CPUState *env)
env->CP0_Cause &= ~(1 << CP0Ca_BD);
}
env->CP0_Status |= (1 << CP0St_EXL);
if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
env->hflags |= MIPS_HFLAG_64;
env->hflags |= MIPS_HFLAG_64;
env->hflags &= ~MIPS_HFLAG_UM;
}
env->hflags &= ~MIPS_HFLAG_BMASK;
......
......@@ -14,6 +14,41 @@
#define TARGET_LONG_BITS 32
#endif
/* Masks used to mark instructions to indicate which ISA level they
were introduced in. */
#define ISA_MIPS1 0x00000001
#define ISA_MIPS2 0x00000002
#define ISA_MIPS3 0x00000004
#define ISA_MIPS4 0x00000008
#define ISA_MIPS5 0x00000010
#define ISA_MIPS32 0x00000020
#define ISA_MIPS32R2 0x00000040
#define ISA_MIPS64 0x00000080
#define ISA_MIPS64R2 0x00000100
/* MIPS ASE */
#define ASE_MIPS16 0x00001000
#define ASE_MIPS3D 0x00002000
#define ASE_MDMX 0x00004000
#define ASE_DSP 0x00008000
#define ASE_DSPR2 0x00010000
/* Chip specific instructions. */
/* Currently void */
/* MIPS CPU defines. */
#define CPU_MIPS1 (ISA_MIPS1)
#define CPU_MIPS2 (CPU_MIPS1 | ISA_MIPS2)
#define CPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3)
#define CPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4)
#define CPU_MIPS5 (CPU_MIPS4 | ISA_MIPS5)
#define CPU_MIPS32 (CPU_MIPS2 | ISA_MIPS32)
#define CPU_MIPS64 (CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64)
#define CPU_MIPS32R2 (CPU_MIPS32 | ISA_MIPS32R2)
#define CPU_MIPS64R2 (CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2)
/* Strictly follow the architecture standard:
- Disallow "special" instruction handling for PMON/SPIM.
Note that we still maintain Count/Compare to match the host clock. */
......
......@@ -1847,10 +1847,9 @@ void op_mtc0_status (void)
(val & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM;
#ifdef TARGET_MIPS64
if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) ||
((env->hflags & MIPS_HFLAG_UM) &&
if ((env->hflags & MIPS_HFLAG_UM) &&
!(val & (1 << CP0St_PX)) &&
!(val & (1 << CP0St_UX))))
!(val & (1 << CP0St_UX)))
env->hflags &= ~MIPS_HFLAG_64;
#endif
if (val & (1 << CP0St_CU1))
......@@ -1906,7 +1905,7 @@ void op_mtc0_cause (void)
{
uint32_t mask = 0x00C00300;
if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
if (env->insn_flags & ISA_MIPS32R2)
mask |= 1 << CP0Ca_DC;
env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
......@@ -3014,10 +3013,9 @@ void op_eret (void)
(env->CP0_Status & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM;
#ifdef TARGET_MIPS64
if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) ||
((env->hflags & MIPS_HFLAG_UM) &&
if ((env->hflags & MIPS_HFLAG_UM) &&
!(env->CP0_Status & (1 << CP0St_PX)) &&
!(env->CP0_Status & (1 << CP0St_UX))))
!(env->CP0_Status & (1 << CP0St_UX)))
env->hflags &= ~MIPS_HFLAG_64;
#endif
if (loglevel & CPU_LOG_EXEC)
......@@ -3038,10 +3036,9 @@ void op_deret (void)
(env->CP0_Status & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM;
#ifdef TARGET_MIPS64
if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) ||
((env->hflags & MIPS_HFLAG_UM) &&
if ((env->hflags & MIPS_HFLAG_UM) &&
!(env->CP0_Status & (1 << CP0St_PX)) &&
!(env->CP0_Status & (1 << CP0St_UX))))
!(env->CP0_Status & (1 << CP0St_UX)))
env->hflags &= ~MIPS_HFLAG_64;
#endif
if (loglevel & CPU_LOG_EXEC)
......
此差异已折叠。
......@@ -80,6 +80,7 @@ struct mips_def_t {
int32_t CP0_SRSConf3;
int32_t CP0_SRSConf4_rw_bitmask;
int32_t CP0_SRSConf4;
int insn_flags;
};
/*****************************************************************************/
......@@ -98,6 +99,7 @@ static mips_def_t mips_defs[] =
.SYNCI_Step = 32,
.CCRes = 2,
.CP0_Status_rw_bitmask = 0x1278FF17,
.insn_flags = CPU_MIPS32 | ASE_MIPS16,
},
{
.name = "4KEcR1",
......@@ -111,6 +113,7 @@ static mips_def_t mips_defs[] =
.SYNCI_Step = 32,
.CCRes = 2,
.CP0_Status_rw_bitmask = 0x1278FF17,
.insn_flags = CPU_MIPS32 | ASE_MIPS16,
},
{
.name = "4KEc",
......@@ -124,6 +127,7 @@ static mips_def_t mips_defs[] =
.SYNCI_Step = 32,
.CCRes = 2,
.CP0_Status_rw_bitmask = 0x1278FF17,
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
},
{
.name = "24Kc",
......@@ -138,6 +142,7 @@ static mips_def_t mips_defs[] =
.CCRes = 2,
/* No DSP implemented. */
.CP0_Status_rw_bitmask = 0x1278FF17,
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
},
{
.name = "24Kf",
......@@ -154,6 +159,7 @@ static mips_def_t mips_defs[] =
.CP0_Status_rw_bitmask = 0x3678FF17,
.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
(1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
},
{
.name = "34Kf",
......@@ -193,6 +199,7 @@ static mips_def_t mips_defs[] =
.CP0_SRSConf4_rw_bitmask = 0x3fffffff,
.CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) |
(0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13),
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
},
#ifdef TARGET_MIPS64
{
......@@ -210,6 +217,7 @@ static mips_def_t mips_defs[] =
/* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
.SEGBITS = 40,
.insn_flags = CPU_MIPS3,
},
{
.name = "5Kc",
......@@ -225,6 +233,7 @@ static mips_def_t mips_defs[] =
.CCRes = 2,
.CP0_Status_rw_bitmask = 0x32F8FFFF,
.SEGBITS = 42,
.insn_flags = CPU_MIPS64,
},
{
.name = "5Kf",
......@@ -243,6 +252,7 @@ static mips_def_t mips_defs[] =
.CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
(0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
.SEGBITS = 42,
.insn_flags = CPU_MIPS64,
},
{
.name = "20Kc",
......@@ -264,6 +274,7 @@ static mips_def_t mips_defs[] =
(1 << FCR0_D) | (1 << FCR0_S) |
(0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
.SEGBITS = 40,
.insn_flags = CPU_MIPS64 | ASE_MIPS3D,
},
#endif
};
......@@ -406,7 +417,7 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask;
env->CP0_SRSCtl = def->CP0_SRSCtl;
#ifdef TARGET_MIPS64
if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
if (def->insn_flags & ISA_MIPS3)
{
env->hflags |= MIPS_HFLAG_64;
env->SEGBITS = def->SEGBITS;
......@@ -426,6 +437,7 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
env->CP0_SRSConf3 = def->CP0_SRSConf3;
env->CP0_SRSConf4_rw_bitmask = def->CP0_SRSConf4_rw_bitmask;
env->CP0_SRSConf4 = def->CP0_SRSConf4;
env->insn_flags = def->insn_flags;
#ifndef CONFIG_USER_ONLY
mmu_init(env, def);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册