提交 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 { ...@@ -441,6 +441,7 @@ struct CPUMIPSState {
int CCRes; /* Cycle count resolution/divisor */ int CCRes; /* Cycle count resolution/divisor */
uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */ uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */
uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */ uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */
int insn_flags; /* Supported instruction set */
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
target_ulong tls_value; target_ulong tls_value;
......
...@@ -369,8 +369,7 @@ void do_interrupt (CPUState *env) ...@@ -369,8 +369,7 @@ void do_interrupt (CPUState *env)
} }
enter_debug_mode: enter_debug_mode:
env->hflags |= MIPS_HFLAG_DM; 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; env->hflags &= ~MIPS_HFLAG_UM;
/* EJTAG probe trap enable is not implemented... */ /* EJTAG probe trap enable is not implemented... */
if (!(env->CP0_Status & (1 << CP0St_EXL))) if (!(env->CP0_Status & (1 << CP0St_EXL)))
...@@ -396,8 +395,7 @@ void do_interrupt (CPUState *env) ...@@ -396,8 +395,7 @@ void do_interrupt (CPUState *env)
env->CP0_ErrorEPC = env->PC[env->current_tc]; env->CP0_ErrorEPC = env->PC[env->current_tc];
} }
env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); 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; env->hflags &= ~MIPS_HFLAG_UM;
if (!(env->CP0_Status & (1 << CP0St_EXL))) if (!(env->CP0_Status & (1 << CP0St_EXL)))
env->CP0_Cause &= ~(1 << CP0Ca_BD); env->CP0_Cause &= ~(1 << CP0Ca_BD);
...@@ -499,8 +497,7 @@ void do_interrupt (CPUState *env) ...@@ -499,8 +497,7 @@ void do_interrupt (CPUState *env)
env->CP0_Cause &= ~(1 << CP0Ca_BD); env->CP0_Cause &= ~(1 << CP0Ca_BD);
} }
env->CP0_Status |= (1 << CP0St_EXL); 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_UM;
} }
env->hflags &= ~MIPS_HFLAG_BMASK; env->hflags &= ~MIPS_HFLAG_BMASK;
......
...@@ -14,6 +14,41 @@ ...@@ -14,6 +14,41 @@
#define TARGET_LONG_BITS 32 #define TARGET_LONG_BITS 32
#endif #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: /* Strictly follow the architecture standard:
- Disallow "special" instruction handling for PMON/SPIM. - Disallow "special" instruction handling for PMON/SPIM.
Note that we still maintain Count/Compare to match the host clock. */ Note that we still maintain Count/Compare to match the host clock. */
......
...@@ -1847,10 +1847,9 @@ void op_mtc0_status (void) ...@@ -1847,10 +1847,9 @@ void op_mtc0_status (void)
(val & (1 << CP0St_UM))) (val & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM; env->hflags |= MIPS_HFLAG_UM;
#ifdef TARGET_MIPS64 #ifdef TARGET_MIPS64
if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) || if ((env->hflags & MIPS_HFLAG_UM) &&
((env->hflags & MIPS_HFLAG_UM) &&
!(val & (1 << CP0St_PX)) && !(val & (1 << CP0St_PX)) &&
!(val & (1 << CP0St_UX)))) !(val & (1 << CP0St_UX)))
env->hflags &= ~MIPS_HFLAG_64; env->hflags &= ~MIPS_HFLAG_64;
#endif #endif
if (val & (1 << CP0St_CU1)) if (val & (1 << CP0St_CU1))
...@@ -1906,7 +1905,7 @@ void op_mtc0_cause (void) ...@@ -1906,7 +1905,7 @@ void op_mtc0_cause (void)
{ {
uint32_t mask = 0x00C00300; uint32_t mask = 0x00C00300;
if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) if (env->insn_flags & ISA_MIPS32R2)
mask |= 1 << CP0Ca_DC; mask |= 1 << CP0Ca_DC;
env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask); env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
...@@ -3014,10 +3013,9 @@ void op_eret (void) ...@@ -3014,10 +3013,9 @@ void op_eret (void)
(env->CP0_Status & (1 << CP0St_UM))) (env->CP0_Status & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM; env->hflags |= MIPS_HFLAG_UM;
#ifdef TARGET_MIPS64 #ifdef TARGET_MIPS64
if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) || if ((env->hflags & MIPS_HFLAG_UM) &&
((env->hflags & MIPS_HFLAG_UM) &&
!(env->CP0_Status & (1 << CP0St_PX)) && !(env->CP0_Status & (1 << CP0St_PX)) &&
!(env->CP0_Status & (1 << CP0St_UX)))) !(env->CP0_Status & (1 << CP0St_UX)))
env->hflags &= ~MIPS_HFLAG_64; env->hflags &= ~MIPS_HFLAG_64;
#endif #endif
if (loglevel & CPU_LOG_EXEC) if (loglevel & CPU_LOG_EXEC)
...@@ -3038,10 +3036,9 @@ void op_deret (void) ...@@ -3038,10 +3036,9 @@ void op_deret (void)
(env->CP0_Status & (1 << CP0St_UM))) (env->CP0_Status & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM; env->hflags |= MIPS_HFLAG_UM;
#ifdef TARGET_MIPS64 #ifdef TARGET_MIPS64
if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) || if ((env->hflags & MIPS_HFLAG_UM) &&
((env->hflags & MIPS_HFLAG_UM) &&
!(env->CP0_Status & (1 << CP0St_PX)) && !(env->CP0_Status & (1 << CP0St_PX)) &&
!(env->CP0_Status & (1 << CP0St_UX)))) !(env->CP0_Status & (1 << CP0St_UX)))
env->hflags &= ~MIPS_HFLAG_64; env->hflags &= ~MIPS_HFLAG_64;
#endif #endif
if (loglevel & CPU_LOG_EXEC) if (loglevel & CPU_LOG_EXEC)
......
此差异已折叠。
...@@ -80,6 +80,7 @@ struct mips_def_t { ...@@ -80,6 +80,7 @@ struct mips_def_t {
int32_t CP0_SRSConf3; int32_t CP0_SRSConf3;
int32_t CP0_SRSConf4_rw_bitmask; int32_t CP0_SRSConf4_rw_bitmask;
int32_t CP0_SRSConf4; int32_t CP0_SRSConf4;
int insn_flags;
}; };
/*****************************************************************************/ /*****************************************************************************/
...@@ -98,6 +99,7 @@ static mips_def_t mips_defs[] = ...@@ -98,6 +99,7 @@ static mips_def_t mips_defs[] =
.SYNCI_Step = 32, .SYNCI_Step = 32,
.CCRes = 2, .CCRes = 2,
.CP0_Status_rw_bitmask = 0x1278FF17, .CP0_Status_rw_bitmask = 0x1278FF17,
.insn_flags = CPU_MIPS32 | ASE_MIPS16,
}, },
{ {
.name = "4KEcR1", .name = "4KEcR1",
...@@ -111,6 +113,7 @@ static mips_def_t mips_defs[] = ...@@ -111,6 +113,7 @@ static mips_def_t mips_defs[] =
.SYNCI_Step = 32, .SYNCI_Step = 32,
.CCRes = 2, .CCRes = 2,
.CP0_Status_rw_bitmask = 0x1278FF17, .CP0_Status_rw_bitmask = 0x1278FF17,
.insn_flags = CPU_MIPS32 | ASE_MIPS16,
}, },
{ {
.name = "4KEc", .name = "4KEc",
...@@ -124,6 +127,7 @@ static mips_def_t mips_defs[] = ...@@ -124,6 +127,7 @@ static mips_def_t mips_defs[] =
.SYNCI_Step = 32, .SYNCI_Step = 32,
.CCRes = 2, .CCRes = 2,
.CP0_Status_rw_bitmask = 0x1278FF17, .CP0_Status_rw_bitmask = 0x1278FF17,
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
}, },
{ {
.name = "24Kc", .name = "24Kc",
...@@ -138,6 +142,7 @@ static mips_def_t mips_defs[] = ...@@ -138,6 +142,7 @@ static mips_def_t mips_defs[] =
.CCRes = 2, .CCRes = 2,
/* No DSP implemented. */ /* No DSP implemented. */
.CP0_Status_rw_bitmask = 0x1278FF17, .CP0_Status_rw_bitmask = 0x1278FF17,
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
}, },
{ {
.name = "24Kf", .name = "24Kf",
...@@ -154,6 +159,7 @@ static mips_def_t mips_defs[] = ...@@ -154,6 +159,7 @@ static mips_def_t mips_defs[] =
.CP0_Status_rw_bitmask = 0x3678FF17, .CP0_Status_rw_bitmask = 0x3678FF17,
.CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
(1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
}, },
{ {
.name = "34Kf", .name = "34Kf",
...@@ -193,6 +199,7 @@ static mips_def_t mips_defs[] = ...@@ -193,6 +199,7 @@ static mips_def_t mips_defs[] =
.CP0_SRSConf4_rw_bitmask = 0x3fffffff, .CP0_SRSConf4_rw_bitmask = 0x3fffffff,
.CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) | .CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) |
(0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13), (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13),
.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
}, },
#ifdef TARGET_MIPS64 #ifdef TARGET_MIPS64
{ {
...@@ -210,6 +217,7 @@ static mips_def_t mips_defs[] = ...@@ -210,6 +217,7 @@ static mips_def_t mips_defs[] =
/* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */ /* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
.CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV), .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
.SEGBITS = 40, .SEGBITS = 40,
.insn_flags = CPU_MIPS3,
}, },
{ {
.name = "5Kc", .name = "5Kc",
...@@ -225,6 +233,7 @@ static mips_def_t mips_defs[] = ...@@ -225,6 +233,7 @@ static mips_def_t mips_defs[] =
.CCRes = 2, .CCRes = 2,
.CP0_Status_rw_bitmask = 0x32F8FFFF, .CP0_Status_rw_bitmask = 0x32F8FFFF,
.SEGBITS = 42, .SEGBITS = 42,
.insn_flags = CPU_MIPS64,
}, },
{ {
.name = "5Kf", .name = "5Kf",
...@@ -243,6 +252,7 @@ static mips_def_t mips_defs[] = ...@@ -243,6 +252,7 @@ static mips_def_t mips_defs[] =
.CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) | .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
(0x81 << FCR0_PRID) | (0x0 << FCR0_REV), (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
.SEGBITS = 42, .SEGBITS = 42,
.insn_flags = CPU_MIPS64,
}, },
{ {
.name = "20Kc", .name = "20Kc",
...@@ -264,6 +274,7 @@ static mips_def_t mips_defs[] = ...@@ -264,6 +274,7 @@ static mips_def_t mips_defs[] =
(1 << FCR0_D) | (1 << FCR0_S) | (1 << FCR0_D) | (1 << FCR0_S) |
(0x82 << FCR0_PRID) | (0x0 << FCR0_REV), (0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
.SEGBITS = 40, .SEGBITS = 40,
.insn_flags = CPU_MIPS64 | ASE_MIPS3D,
}, },
#endif #endif
}; };
...@@ -406,7 +417,7 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def) ...@@ -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_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask;
env->CP0_SRSCtl = def->CP0_SRSCtl; env->CP0_SRSCtl = def->CP0_SRSCtl;
#ifdef TARGET_MIPS64 #ifdef TARGET_MIPS64
if ((env->CP0_Config0 & (0x3 << CP0C0_AT))) if (def->insn_flags & ISA_MIPS3)
{ {
env->hflags |= MIPS_HFLAG_64; env->hflags |= MIPS_HFLAG_64;
env->SEGBITS = def->SEGBITS; env->SEGBITS = def->SEGBITS;
...@@ -426,6 +437,7 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def) ...@@ -426,6 +437,7 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
env->CP0_SRSConf3 = def->CP0_SRSConf3; env->CP0_SRSConf3 = def->CP0_SRSConf3;
env->CP0_SRSConf4_rw_bitmask = def->CP0_SRSConf4_rw_bitmask; env->CP0_SRSConf4_rw_bitmask = def->CP0_SRSConf4_rw_bitmask;
env->CP0_SRSConf4 = def->CP0_SRSConf4; env->CP0_SRSConf4 = def->CP0_SRSConf4;
env->insn_flags = def->insn_flags;
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
mmu_init(env, def); mmu_init(env, def);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册