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. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
adc370a48f
commit
ce9782f40a
@ -2407,6 +2407,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
|
||||
{"emt", "", 0x41600be1, 0xffffffff, TRAP, 0, MT32 },
|
||||
{"emt", "t", 0x41600be1, 0xffe0ffff, TRAP|WR_t, 0, MT32 },
|
||||
{"eret", "", 0x42000018, 0xffffffff, 0, 0, I3|I32 },
|
||||
{"eretnc", "", 0x42000058, 0xffffffff, 0, 0, I33},
|
||||
{"evpe", "", 0x41600021, 0xffffffff, TRAP, 0, MT32 },
|
||||
{"evpe", "t", 0x41600021, 0xffe0ffff, TRAP|WR_t, 0, MT32 },
|
||||
{"ext", "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s, 0, I33 },
|
||||
|
@ -466,6 +466,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;
|
||||
|
@ -348,6 +348,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)
|
||||
|
@ -2099,7 +2099,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)) {
|
||||
@ -2111,9 +2111,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);
|
||||
|
@ -7917,16 +7917,26 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
|
||||
goto die;
|
||||
gen_helper_tlbr(cpu_env);
|
||||
break;
|
||||
case OPC_ERET:
|
||||
opn = "eret";
|
||||
check_insn(ctx, ISA_MIPS2);
|
||||
case OPC_ERET: /* OPC_ERETNC */
|
||||
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(cpu_env);
|
||||
} else {
|
||||
/* OPC_ERET */
|
||||
opn = "eret";
|
||||
check_insn(ctx, ISA_MIPS2);
|
||||
gen_helper_eret(cpu_env);
|
||||
}
|
||||
ctx->bstate = BS_EXCP;
|
||||
}
|
||||
break;
|
||||
case OPC_DERET:
|
||||
opn = "deret";
|
||||
|
@ -403,7 +403,7 @@ static const mips_def_t mips_defs[] =
|
||||
.CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP),
|
||||
.CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M),
|
||||
.CP0_Config4_rw_bitmask = 0,
|
||||
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR),
|
||||
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR) | (1 << CP0C5_LLB),
|
||||
.CP0_Config5_rw_bitmask = (0 << CP0C5_M) | (1 << CP0C5_K) |
|
||||
(1 << CP0C5_CV) | (0 << CP0C5_EVA) |
|
||||
(1 << CP0C5_MSAEn) | (1 << CP0C5_UFR) |
|
||||
@ -622,6 +622,7 @@ static const mips_def_t mips_defs[] =
|
||||
(1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1U << CP0C3_M),
|
||||
.CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
|
||||
(3 << CP0C4_IE) | (1 << CP0C4_M),
|
||||
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB),
|
||||
.CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
|
||||
(1 << CP0C5_UFE),
|
||||
.CP0_LLAddr_rw_bitmask = 0,
|
||||
|
Loading…
Reference in New Issue
Block a user