From 95ed79d9c2c277987ca4dc6df9d9dff5589f7201 Mon Sep 17 00:00:00 2001 From: Leon Alrae Date: Tue, 13 Feb 2018 13:44:52 -0500 Subject: [PATCH] target-mips: extend selected CP0 registers to 64-bits in MIPS32 Extend EntryLo0, EntryLo1, LLAddr and TagLo from 32 to 64 bits in MIPS32. Introduce gen_move_low32() function which moves low 32 bits from 64-bit temp to GPR; it sign extends 32-bit value on MIPS64 and truncates on MIPS32. Backports commit 284b731a6ae47b9ebabb9613e753c4d83cf75dd3 from qemu --- qemu/target-mips/cpu.h | 14 ++++----- qemu/target-mips/op_helper.c | 8 ++--- qemu/target-mips/translate.c | 61 ++++++++++++++++++++++++------------ 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/qemu/target-mips/cpu.h b/qemu/target-mips/cpu.h index e267456b..c32c8fbc 100644 --- a/qemu/target-mips/cpu.h +++ b/qemu/target-mips/cpu.h @@ -35,7 +35,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) @@ -226,7 +226,7 @@ struct CPUMIPSState { uint32_t SEGBITS; uint32_t PABITS; target_ulong SEGMask; - target_ulong PAMask; + uint64_t PAMask; int32_t msair; #define MSAIR_ProcID 8 @@ -274,8 +274,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 @@ -473,11 +473,11 @@ struct CPUMIPSState { 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]; @@ -504,7 +504,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; diff --git a/qemu/target-mips/op_helper.c b/qemu/target-mips/op_helper.c index e8ce2d54..de026d4b 100644 --- a/qemu/target-mips/op_helper.c +++ b/qemu/target-mips/op_helper.c @@ -2004,12 +2004,12 @@ void r4k_helper_tlbr(CPUMIPSState *env) env->CP0_EntryHi = tlb->VPN | tlb->ASID; env->CP0_PageMask = tlb->PageMask; env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) | - ((target_ulong)tlb->RI0 << CP0EnLo_RI) | - ((target_ulong)tlb->XI0 << CP0EnLo_XI) | + ((uint64_t)tlb->RI0 << CP0EnLo_RI) | + ((uint64_t)tlb->XI0 << CP0EnLo_XI) | (tlb->C0 << 3) | (tlb->PFN[0] >> 6); env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) | - ((target_ulong)tlb->RI1 << CP0EnLo_RI) | - ((target_ulong)tlb->XI1 << CP0EnLo_XI) | + ((uint64_t)tlb->RI1 << CP0EnLo_RI) | + ((uint64_t)tlb->XI1 << CP0EnLo_XI) | (tlb->C1 << 3) | (tlb->PFN[1] >> 6); } } diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index d00e9f55..b4de8c14 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -4892,6 +4892,15 @@ static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd) #ifndef CONFIG_USER_ONLY /* CP0 (MMU and control) */ +static inline void gen_move_low32(TCGContext *s, TCGv ret, TCGv_i64 arg) +{ +#if defined(TARGET_MIPS64) + tcg_gen_ext32s_tl(s, ret, arg); +#else + tcg_gen_trunc_i64_tl(s, ret, arg); +#endif +} + static inline void gen_mfc0_load32 (DisasContext *ctx, TCGv arg, target_ulong off) { TCGContext *tcg_ctx = ctx->uc->tcg_ctx; @@ -5026,17 +5035,21 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0)); + { + TCGv_i64 tmp = tcg_temp_new_i64(tcg_ctx); + tcg_gen_ld_i64(tcg_ctx, tmp, tcg_ctx->cpu_env, + offsetof(CPUMIPSState, CP0_EntryLo0)); + #if defined(TARGET_MIPS64) - if (ctx->rxi) { - /* Move RI/XI fields to bits 31:30 */ - TCGv tmp = tcg_temp_new(tcg_ctx); - tcg_gen_shri_tl(tcg_ctx, tmp, arg, CP0EnLo_XI); - tcg_gen_deposit_tl(tcg_ctx, arg, arg, tmp, 30, 2); - tcg_temp_free(tcg_ctx, tmp); - } + if (ctx->rxi) { + /* Move RI/XI fields to bits 31:30 */ + tcg_gen_shri_tl(tcg_ctx, arg, tmp, CP0EnLo_XI); + tcg_gen_deposit_tl(tcg_ctx, tmp, tmp, arg, 30, 2); + } #endif - tcg_gen_ext32s_tl(tcg_ctx, arg, arg); + gen_move_low32(tcg_ctx, arg, tmp); + tcg_temp_free_i64(tcg_ctx, tmp); + } rn = "EntryLo0"; break; case 1: @@ -5081,17 +5094,20 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_ld_tl(tcg_ctx, arg, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); + { + TCGv_i64 tmp = tcg_temp_new_i64(tcg_ctx); + tcg_gen_ld_i64(tcg_ctx, tmp, tcg_ctx->cpu_env, + offsetof(CPUMIPSState, CP0_EntryLo1)); #if defined(TARGET_MIPS64) - if (ctx->rxi) { - /* Move RI/XI fields to bits 31:30 */ - TCGv tmp = tcg_temp_new(tcg_ctx); - tcg_gen_shri_tl(tcg_ctx, tmp, arg, CP0EnLo_XI); - tcg_gen_deposit_tl(tcg_ctx, arg, arg, tmp, 30, 2); - tcg_temp_free(tcg_ctx, tmp); - } + if (ctx->rxi) { + /* Move RI/XI fields to bits 31:30 */ + tcg_gen_shri_tl(tcg_ctx, arg, tmp, CP0EnLo_XI); + tcg_gen_deposit_tl(tcg_ctx, tmp, tmp, arg, 30, 2); + } #endif - tcg_gen_ext32s_tl(tcg_ctx, arg, arg); + gen_move_low32(tcg_ctx, arg, tmp); + tcg_temp_free_i64(tcg_ctx, tmp); + } rn = "EntryLo1"; break; default: @@ -5500,7 +5516,12 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_TagLo)); + { + TCGv_i64 tmp = tcg_temp_new_i64(tcg_ctx); + tcg_gen_ld_i64(tcg_ctx, tmp, tcg_ctx->cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); + gen_move_low32(tcg_ctx, arg, tmp); + tcg_temp_free_i64(tcg_ctx, tmp); + } rn = "TagLo"; break; case 1: @@ -19772,7 +19793,7 @@ void cpu_state_reset(CPUMIPSState *env) } #endif env->PABITS = env->cpu_model->PABITS; - env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1); + env->PAMask = (1ULL << env->cpu_model->PABITS) - 1; env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask; env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0; env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;