diff options
Diffstat (limited to 'target-mips/cpu.h')
-rw-r--r-- | target-mips/cpu.h | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/target-mips/cpu.h b/target-mips/cpu.h index f9d2b4c5af..474a0e327d 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -34,7 +34,7 @@ struct r4k_tlb_t { uint_fast16_t RI0:1; uint_fast16_t RI1:1; uint_fast16_t EHINV:1; - target_ulong PFN[2]; + uint64_t PFN[2]; }; #if !defined(CONFIG_USER_ONLY) @@ -100,6 +100,7 @@ struct CPUMIPSFPUContext { float_status fp_status; /* fpu implementation/revision register (fir) */ uint32_t fcr0; +#define FCR0_FREP 29 #define FCR0_UFRP 28 #define FCR0_F64 22 #define FCR0_L 21 @@ -223,8 +224,14 @@ struct CPUMIPSState { uint32_t SEGBITS; uint32_t PABITS; +#if defined(TARGET_MIPS64) +# define PABITS_BASE 36 +#else +# define PABITS_BASE 32 +#endif target_ulong SEGMask; - target_ulong PAMask; + uint64_t PAMask; +#define PAMASK_BASE ((1ULL << PABITS_BASE) - 1) int32_t msair; #define MSAIR_ProcID 8 @@ -272,8 +279,8 @@ struct CPUMIPSState { #define CP0VPEOpt_DWX2 2 #define CP0VPEOpt_DWX1 1 #define CP0VPEOpt_DWX0 0 - target_ulong CP0_EntryLo0; - target_ulong CP0_EntryLo1; + uint64_t CP0_EntryLo0; + uint64_t CP0_EntryLo1; #if defined(TARGET_MIPS64) # define CP0EnLo_RI 63 # define CP0EnLo_XI 62 @@ -288,6 +295,7 @@ struct CPUMIPSState { int32_t CP0_PageGrain; #define CP0PG_RIE 31 #define CP0PG_XIE 30 +#define CP0PG_ELPA 29 #define CP0PG_IEC 27 int32_t CP0_Wired; int32_t CP0_SRSConf0_rw_bitmask; @@ -462,17 +470,21 @@ struct CPUMIPSState { #define CP0C5_CV 29 #define CP0C5_EVA 28 #define CP0C5_MSAEn 27 +#define CP0C5_UFE 9 +#define CP0C5_FRE 8 #define CP0C5_SBRI 6 +#define CP0C5_MVH 5 +#define CP0C5_LLB 4 #define CP0C5_UFR 2 #define CP0C5_NFExists 0 int32_t CP0_Config6; int32_t CP0_Config7; /* XXX: Maybe make LLAddr per-TC? */ - target_ulong lladdr; + uint64_t lladdr; target_ulong llval; target_ulong llnewval; target_ulong llreg; - target_ulong CP0_LLAddr_rw_bitmask; + uint64_t CP0_LLAddr_rw_bitmask; int CP0_LLAddr_shift; target_ulong CP0_WatchLo[8]; int32_t CP0_WatchHi[8]; @@ -499,7 +511,7 @@ struct CPUMIPSState { #define CP0DB_DSS 0 target_ulong CP0_DEPC; int32_t CP0_Performance0; - int32_t CP0_TagLo; + uint64_t CP0_TagLo; int32_t CP0_DataLo; int32_t CP0_TagHi; int32_t CP0_DataHi; @@ -514,7 +526,7 @@ struct CPUMIPSState { #define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */ uint32_t hflags; /* CPU State */ /* TMASK defines different execution modes */ -#define MIPS_HFLAG_TMASK 0x15807FF +#define MIPS_HFLAG_TMASK 0x75807FF #define MIPS_HFLAG_MODE 0x00007 /* execution modes */ /* The KSU flags must be the lowest bits in hflags. The flag order must be the same as defined for CP0 Status. This allows to use @@ -561,6 +573,8 @@ struct CPUMIPSState { #define MIPS_HFLAG_SBRI 0x400000 /* R6 SDBBP causes RI excpt. in user mode */ #define MIPS_HFLAG_FBNSLOT 0x800000 /* Forbidden slot */ #define MIPS_HFLAG_MSA 0x1000000 +#define MIPS_HFLAG_FRE 0x2000000 /* FRE enabled */ +#define MIPS_HFLAG_ELPA 0x4000000 target_ulong btarget; /* Jump / branch target */ target_ulong bcond; /* Branch condition (if needed) */ @@ -796,6 +810,15 @@ static inline void restore_msa_fp_status(CPUMIPSState *env) set_flush_inputs_to_zero(flush_to_zero, status); } +static inline void restore_pamask(CPUMIPSState *env) +{ + if (env->hflags & MIPS_HFLAG_ELPA) { + env->PAMask = (1ULL << env->PABITS) - 1; + } else { + env->PAMask = PAMASK_BASE; + } +} + static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc, target_ulong *cs_base, int *flags) { @@ -843,7 +866,8 @@ static inline void compute_hflags(CPUMIPSState *env) env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 | - MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA); + MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE | + MIPS_HFLAG_ELPA); if (!(env->CP0_Status & (1 << CP0St_EXL)) && !(env->CP0_Status & (1 << CP0St_ERL)) && !(env->hflags & MIPS_HFLAG_DM)) { @@ -924,6 +948,16 @@ static inline void compute_hflags(CPUMIPSState *env) env->hflags |= MIPS_HFLAG_MSA; } } + if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) { + if (env->CP0_Config5 & (1 << CP0C5_FRE)) { + env->hflags |= MIPS_HFLAG_FRE; + } + } + if (env->CP0_Config3 & (1 << CP0C3_LPA)) { + if (env->CP0_PageGrain & (1 << CP0PG_ELPA)) { + env->hflags |= MIPS_HFLAG_ELPA; + } + } } #ifndef CONFIG_USER_ONLY |