Per-CPU instruction decoding implementation
PATCH 1/1 Per-CPU instruction decoding implementation
Hi all,
The patch below implements per-cpu decoding on the MIPS target. The supported instruction set is defined by a set of flags. It assumes that MIPS2 instructions are always supported. It also removes the check for CP0C0_AT when setting MIPS_HFLAG_64 as it is now obsolete.
Cheers,
Aurelien
Index: target-mips/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/cpu.h,v
retrieving revision 1.43
cpu.h +1 -0
@@ -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;
Index: target-mips/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/helper.c,v retrieving revision 1.48
helper.c +3 -6
@@ -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 ;
Index: target-mips/mips-defs.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/mips-defs.h,v retrieving revision 1.15
mips-defs.h +29 -0
@@ -14,6 +14,35 @@#define TARGET_LONG_BITS 32#endif +/* Masks used to mark instructions to indicate which ISA level they +were introduced in. */ +#define INSN_MIPS3 0x00000001 +#define INSN_MIPS4 0x00000002 +#define INSN_MIPS5 0x00000004 +#define INSN_MIPS32 0x00000008 +#define INSN_MIPS32R2 0x00000010 +#define INSN_MIPS64 0x00000020 +#define INSN_MIPS64R2 0x00000040 + +/* MIPS ASE */ +#define INSN_MIPS16 0x00000100 +#define INSN_MIPS3D 0x00000200 +#define INSN_MDMX 0x00000400 + +/* Chip specific instructions. */ +/* Currently void */ + +/* MIPS CPU defines. */ +#define CPU_MIPS3 (INSN_MIPS3) +#define CPU_MIPS4 (CPU_MIPS3 | INSN_MIPS4) +#define CPU_MIPS5 (CPU_MIPS4 | INSN_MIPS5) + +#define CPU_MIPS32 (INSN_MIPS32) +#define CPU_MIPS64 (CPU_MIPS5 | CPU_MIPS32 | INSN_MIPS64) + +#define CPU_MIPS32R2 (CPU_MIPS32 | INSN_MIPS32R2) +#define CPU_MIPS64R2 (CPU_MIPS64 | CPU_MIPS32R2 | INSN_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. */
Index: target-mips/op.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op.c,v
retrieving revision 1.71
op.c +7 -10
@@ -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 &INSN_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 )
Index: target-mips/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/translate.c,v retrieving revision 1.99
translate.c +171 -86
791 lines not on this page · raw message
Index: target-mips/translate_init.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/translate_init.c,v retrieving revision 1.20
translate_init.c +13 -1
@@ -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, }, { .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, }, { .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, }, { .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, }, { .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, }, { .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, },#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, },#endif };
@@ -403,7 +414,7 @@ int cpu_mips_register (CPUMIPSState *env 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 &INSN_MIPS3 ) { env->hflags |=MIPS_HFLAG_64 ; env->SEGBITS = def->SEGBITS;
@@ -423,6 +434,7 @@ int cpu_mips_register (CPUMIPSState *env 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);
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net
Quoted 6 lines · Aurelien Jarno
Hi all,
The patch below implements per-cpu decoding on the MIPS target. The supported instruction set is defined by a set of flags. It assumes that MIPS2 instructions are always supported. It also removes the check for
CP0C0_ATwhen settingMIPS_HFLAG_64as it is now obsolete.
I expanded parts of it to (at least theoretically) cover the whole ISA space, renamed INSN -> ISA / ASE, since that's what we actually check for, and fixed a few misassumptions (e.g. Xcontext is MIPS3).
Thiemo