mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-04-01 23:07:03 +00:00
target-mips: add ERETNC instruction and Config5.LLB bit
ERETNC is identical to ERET except that an ERETNC will not clear the LLbit that is set by execution of an LL instruction, and thus when placed between an LL and SC sequence, will never cause the SC to fail. Presence of ERETNC is denoted by the Config5.LLB. Backports commit ce9782f40ac16660ea9437bfaa2c9c34d5ed8110 from qemu
This commit is contained in:
parent
922d30c448
commit
57f57a9de4
|
@ -3683,6 +3683,7 @@ mips_symbols = (
|
|||
'helper_di',
|
||||
'helper_ei',
|
||||
'helper_eret',
|
||||
'helper_eretnc',
|
||||
'helper_deret',
|
||||
'helper_rdhwr_cpunum',
|
||||
'helper_rdhwr_synci_step',
|
||||
|
|
|
@ -3630,6 +3630,7 @@
|
|||
#define helper_di helper_di_mips
|
||||
#define helper_ei helper_ei_mips
|
||||
#define helper_eret helper_eret_mips
|
||||
#define helper_eretnc helper_eretnc_mips
|
||||
#define helper_deret helper_deret_mips
|
||||
#define helper_rdhwr_cpunum helper_rdhwr_cpunum_mips
|
||||
#define helper_rdhwr_synci_step helper_rdhwr_synci_step_mips
|
||||
|
|
|
@ -3630,6 +3630,7 @@
|
|||
#define helper_di helper_di_mips64
|
||||
#define helper_ei helper_ei_mips64
|
||||
#define helper_eret helper_eret_mips64
|
||||
#define helper_eretnc helper_eretnc_mips64
|
||||
#define helper_deret helper_deret_mips64
|
||||
#define helper_rdhwr_cpunum helper_rdhwr_cpunum_mips64
|
||||
#define helper_rdhwr_synci_step helper_rdhwr_synci_step_mips64
|
||||
|
|
|
@ -3630,6 +3630,7 @@
|
|||
#define helper_di helper_di_mips64el
|
||||
#define helper_ei helper_ei_mips64el
|
||||
#define helper_eret helper_eret_mips64el
|
||||
#define helper_eretnc helper_eretnc_mips64el
|
||||
#define helper_deret helper_deret_mips64el
|
||||
#define helper_rdhwr_cpunum helper_rdhwr_cpunum_mips64el
|
||||
#define helper_rdhwr_synci_step helper_rdhwr_synci_step_mips64el
|
||||
|
|
|
@ -3630,6 +3630,7 @@
|
|||
#define helper_di helper_di_mipsel
|
||||
#define helper_ei helper_ei_mipsel
|
||||
#define helper_eret helper_eret_mipsel
|
||||
#define helper_eretnc helper_eretnc_mipsel
|
||||
#define helper_deret helper_deret_mipsel
|
||||
#define helper_rdhwr_cpunum helper_rdhwr_cpunum_mipsel
|
||||
#define helper_rdhwr_synci_step helper_rdhwr_synci_step_mipsel
|
||||
|
|
|
@ -467,6 +467,7 @@ struct CPUMIPSState {
|
|||
#define CP0C5_UFE 9
|
||||
#define CP0C5_FRE 8
|
||||
#define CP0C5_SBRI 6
|
||||
#define CP0C5_LLB 4
|
||||
#define CP0C5_UFR 2
|
||||
#define CP0C5_NFExists 0
|
||||
int32_t CP0_Config6;
|
||||
|
|
|
@ -350,6 +350,7 @@ DEF_HELPER_1(tlbinvf, void, env)
|
|||
DEF_HELPER_1(di, tl, env)
|
||||
DEF_HELPER_1(ei, tl, env)
|
||||
DEF_HELPER_1(eret, void, env)
|
||||
DEF_HELPER_1(eretnc, void, env)
|
||||
DEF_HELPER_1(deret, void, env)
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
DEF_HELPER_1(rdhwr_cpunum, tl, env)
|
||||
|
|
|
@ -2106,7 +2106,7 @@ static void set_pc(CPUMIPSState *env, target_ulong error_pc)
|
|||
}
|
||||
}
|
||||
|
||||
void helper_eret(CPUMIPSState *env)
|
||||
static inline void exception_return(CPUMIPSState *env)
|
||||
{
|
||||
debug_pre_eret(env);
|
||||
if (env->CP0_Status & (1 << CP0St_ERL)) {
|
||||
|
@ -2118,9 +2118,19 @@ void helper_eret(CPUMIPSState *env)
|
|||
}
|
||||
compute_hflags(env);
|
||||
debug_post_eret(env);
|
||||
}
|
||||
|
||||
void helper_eret(CPUMIPSState *env)
|
||||
{
|
||||
exception_return(env);
|
||||
env->lladdr = 1;
|
||||
}
|
||||
|
||||
void helper_eretnc(CPUMIPSState *env)
|
||||
{
|
||||
exception_return(env);
|
||||
}
|
||||
|
||||
void helper_deret(CPUMIPSState *env)
|
||||
{
|
||||
debug_pre_eret(env);
|
||||
|
|
|
@ -7985,16 +7985,28 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
|
|||
goto die;
|
||||
gen_helper_tlbr(tcg_ctx, tcg_ctx->cpu_env);
|
||||
break;
|
||||
case OPC_ERET:
|
||||
case OPC_ERET: /* OPC_ERETNC */
|
||||
opn = "eret";
|
||||
check_insn(ctx, ISA_MIPS2);
|
||||
if ((ctx->insn_flags & ISA_MIPS32R6) &&
|
||||
(ctx->hflags & MIPS_HFLAG_BMASK)) {
|
||||
MIPS_DEBUG("CTI in delay / forbidden slot");
|
||||
goto die;
|
||||
} else {
|
||||
int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
|
||||
if (ctx->opcode & (1 << bit_shift)) {
|
||||
/* OPC_ERETNC */
|
||||
opn = "eretnc";
|
||||
check_insn(ctx, ISA_MIPS32R5);
|
||||
gen_helper_eretnc(tcg_ctx, tcg_ctx->cpu_env);
|
||||
} else {
|
||||
/* OPC_ERET */
|
||||
opn = "eret";
|
||||
check_insn(ctx, ISA_MIPS2);
|
||||
gen_helper_eret(tcg_ctx, tcg_ctx->cpu_env);
|
||||
}
|
||||
ctx->bstate = BS_EXCP;
|
||||
}
|
||||
gen_helper_eret(tcg_ctx, tcg_ctx->cpu_env);
|
||||
ctx->bstate = BS_EXCP;
|
||||
break;
|
||||
case OPC_DERET:
|
||||
opn = "deret";
|
||||
|
|
Loading…
Reference in a new issue