From 284b731a6ae47b9ebabb9613e753c4d83cf75dd3 Mon Sep 17 00:00:00 2001 From: Leon Alrae Date: Tue, 9 Jun 2015 17:14:13 +0100 Subject: 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. Signed-off-by: Leon Alrae Reviewed-by: Aurelien Jarno --- target-mips/cpu.h | 14 +++++------ target-mips/machine.c | 20 ++++++++-------- target-mips/op_helper.c | 8 +++---- target-mips/translate.c | 63 ++++++++++++++++++++++++++++++++----------------- 4 files changed, 63 insertions(+), 42 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 2c68782..4b81798 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) @@ -225,7 +225,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 @@ -273,8 +273,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 @@ -472,11 +472,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]; @@ -503,7 +503,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/target-mips/machine.c b/target-mips/machine.c index 7d1fa32..559402c 100644 --- a/target-mips/machine.c +++ b/target-mips/machine.c @@ -142,8 +142,8 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size) v->RI0 = (flags >> 13) & 1; v->XI1 = (flags >> 12) & 1; v->XI0 = (flags >> 11) & 1; - qemu_get_betls(f, &v->PFN[0]); - qemu_get_betls(f, &v->PFN[1]); + qemu_get_be64s(f, &v->PFN[0]); + qemu_get_be64s(f, &v->PFN[1]); return 0; } @@ -169,8 +169,8 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size) qemu_put_be32s(f, &v->PageMask); qemu_put_8s(f, &v->ASID); qemu_put_be16s(f, &flags); - qemu_put_betls(f, &v->PFN[0]); - qemu_put_betls(f, &v->PFN[1]); + qemu_put_be64s(f, &v->PFN[0]); + qemu_put_be64s(f, &v->PFN[1]); } const VMStateInfo vmstate_info_tlb = { @@ -201,8 +201,8 @@ const VMStateDescription vmstate_tlb = { const VMStateDescription vmstate_mips_cpu = { .name = "cpu", - .version_id = 6, - .minimum_version_id = 6, + .version_id = 7, + .minimum_version_id = 7, .post_load = cpu_post_load, .fields = (VMStateField[]) { /* Active TC */ @@ -237,8 +237,8 @@ const VMStateDescription vmstate_mips_cpu = { VMSTATE_UINTTL(env.CP0_VPESchedule, MIPSCPU), VMSTATE_UINTTL(env.CP0_VPEScheFBack, MIPSCPU), VMSTATE_INT32(env.CP0_VPEOpt, MIPSCPU), - VMSTATE_UINTTL(env.CP0_EntryLo0, MIPSCPU), - VMSTATE_UINTTL(env.CP0_EntryLo1, MIPSCPU), + VMSTATE_UINT64(env.CP0_EntryLo0, MIPSCPU), + VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU), VMSTATE_UINTTL(env.CP0_Context, MIPSCPU), VMSTATE_INT32(env.CP0_PageMask, MIPSCPU), VMSTATE_INT32(env.CP0_PageGrain, MIPSCPU), @@ -269,7 +269,7 @@ const VMStateDescription vmstate_mips_cpu = { VMSTATE_INT32(env.CP0_Config3, MIPSCPU), VMSTATE_INT32(env.CP0_Config6, MIPSCPU), VMSTATE_INT32(env.CP0_Config7, MIPSCPU), - VMSTATE_UINTTL(env.lladdr, MIPSCPU), + VMSTATE_UINT64(env.lladdr, MIPSCPU), VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8), VMSTATE_INT32_ARRAY(env.CP0_WatchHi, MIPSCPU, 8), VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU), @@ -277,7 +277,7 @@ const VMStateDescription vmstate_mips_cpu = { VMSTATE_INT32(env.CP0_Debug, MIPSCPU), VMSTATE_UINTTL(env.CP0_DEPC, MIPSCPU), VMSTATE_INT32(env.CP0_Performance0, MIPSCPU), - VMSTATE_INT32(env.CP0_TagLo, MIPSCPU), + VMSTATE_UINT64(env.CP0_TagLo, MIPSCPU), VMSTATE_INT32(env.CP0_DataLo, MIPSCPU), VMSTATE_INT32(env.CP0_TagHi, MIPSCPU), VMSTATE_INT32(env.CP0_DataHi, MIPSCPU), diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index b412f94..4dc4970 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1997,12 +1997,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/target-mips/translate.c b/target-mips/translate.c index 2cc5875..f722e95 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -4833,6 +4833,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(TCGv ret, TCGv_i64 arg) +{ +#if defined(TARGET_MIPS64) + tcg_gen_ext32s_tl(ret, arg); +#else + tcg_gen_trunc_i64_tl(ret, arg); +#endif +} + static inline void gen_mfc0_load32 (TCGv arg, target_ulong off) { TCGv_i32 t0 = tcg_temp_new_i32(); @@ -4961,17 +4970,20 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0)); + { + TCGv_i64 tmp = tcg_temp_new_i64(); + tcg_gen_ld_i64(tmp, 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_gen_shri_tl(tmp, arg, CP0EnLo_XI); - tcg_gen_deposit_tl(arg, arg, tmp, 30, 2); - tcg_temp_free(tmp); - } + if (ctx->rxi) { + /* Move RI/XI fields to bits 31:30 */ + tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); + tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); + } #endif - tcg_gen_ext32s_tl(arg, arg); + gen_move_low32(arg, tmp); + tcg_temp_free_i64(tmp); + } rn = "EntryLo0"; break; case 1: @@ -5016,17 +5028,20 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1)); + { + TCGv_i64 tmp = tcg_temp_new_i64(); + tcg_gen_ld_i64(tmp, 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_gen_shri_tl(tmp, arg, CP0EnLo_XI); - tcg_gen_deposit_tl(arg, arg, tmp, 30, 2); - tcg_temp_free(tmp); - } + if (ctx->rxi) { + /* Move RI/XI fields to bits 31:30 */ + tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI); + tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2); + } #endif - tcg_gen_ext32s_tl(arg, arg); + gen_move_low32(arg, tmp); + tcg_temp_free_i64(tmp); + } rn = "EntryLo1"; break; default: @@ -5436,7 +5451,12 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo)); + { + TCGv_i64 tmp = tcg_temp_new_i64(); + tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo)); + gen_move_low32(arg, tmp); + tcg_temp_free_i64(tmp); + } rn = "TagLo"; break; case 1: @@ -19423,7 +19443,8 @@ void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n", env->CP0_Status, env->CP0_Cause, env->CP0_EPC); - cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n", + cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016" + PRIx64 "\n", env->CP0_Config0, env->CP0_Config1, env->lladdr); cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n", env->CP0_Config2, env->CP0_Config3); @@ -19557,7 +19578,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; -- cgit v1.1