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 <leon.alrae@imgtec.com> Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
b435f3f3d1
commit
284b731a6a
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user