mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-24 00:45:38 +00:00
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
This commit is contained in:
parent
907bb26e5f
commit
95ed79d9c2
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue