On 25.10.18. 10:49, Aleksandar Markovic wrote: > From: Dimitrije Nikolic <dniko...@wavecomp.com> > > Implement emulation of nanoMIPS EVA instructions. They are all > part of P.LS.E0 instruction pool, or one of its subpools. > > Signed-off-by: Dimitrije Nikolic <dniko...@wavecomp.com> > Signed-off-by: Aleksandar Markovic <amarko...@wavecomp.com> > --- > target/mips/translate.c | 128 > ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 128 insertions(+) > > diff --git a/target/mips/translate.c b/target/mips/translate.c > index 4338b9a..60964c9 100644 > --- a/target/mips/translate.c > +++ b/target/mips/translate.c > @@ -2989,6 +2989,35 @@ static inline void check_nms(DisasContext *ctx) > } > } > > +/* > + * This code generates a "reserved instruction" exception if the > + * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, > + * Config2 TL, and Config5 L2C are unset. > + */ > +static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) > +{ > + if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) && > + !(ctx->CP0_Config1 & (1 << CP0C1_DL)) && > + !(ctx->CP0_Config1 & (1 << CP0C1_IL)) && > + !(ctx->CP0_Config2 & (1 << CP0C2_SL)) && > + !(ctx->CP0_Config2 & (1 << CP0C2_TL)) && > + !(ctx->CP0_Config5 & (1 << CP0C5_L2C))) > + { > + generate_exception_end(ctx, EXCP_RI); > + } > +} > + > +/* > + * This code generates a "reserved instruction" exception if the > + * Config5 EVA bit is NOT set. > + */ > +static inline void check_eva(DisasContext *ctx) > +{ > + if (!unlikely(ctx->CP0_Config5 & (1 << CP0C5_EVA))) {
Proper condition would be: unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) Otherwise: Reviewed-by: Stefan Markovic <smarko...@wavecomp.com> > + generate_exception_end(ctx, EXCP_RI); > + } > +} > + > > /* Define small wrappers for gen_load_fpr* so that we have a uniform > calling interface for 32 and 64-bit FPRs. No sense in changing > @@ -21218,6 +21247,105 @@ static int decode_nanomips_32_48_opc(CPUMIPSState > *env, DisasContext *ctx) > break; > } > break; > + case NM_P_LS_E0: > + switch (extract32(ctx->opcode, 11, 4)) { > + case NM_LBE: > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_ld(ctx, OPC_LBE, rt, rs, s); > + break; > + case NM_SBE: > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_st(ctx, OPC_SBE, rt, rs, s); > + break; > + case NM_LBUE: > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_ld(ctx, OPC_LBUE, rt, rs, s); > + break; > + case NM_P_PREFE: > + if (rt == 31) { > + /* case NM_SYNCIE */ > + check_eva(ctx); > + check_cp0_enabled(ctx); > + /* Break the TB to be able to sync copied > instructions > + immediately */ > + ctx->base.is_jmp = DISAS_STOP; > + } else { > + /* case NM_PREFE */ > + check_eva(ctx); > + check_cp0_enabled(ctx); > + /* Treat as NOP. */ > + } > + break; > + case NM_LHE: > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_ld(ctx, OPC_LHE, rt, rs, s); > + break; > + case NM_SHE: > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_st(ctx, OPC_SHE, rt, rs, s); > + break; > + case NM_LHUE: > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_ld(ctx, OPC_LHUE, rt, rs, s); > + break; > + case NM_CACHEE: > + check_nms_dl_il_sl_tl_l2c(ctx); > + gen_cache_operation(ctx, rt, rs, s); > + break; > + case NM_LWE: > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_ld(ctx, OPC_LWE, rt, rs, s); > + break; > + case NM_SWE: > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_st(ctx, OPC_SWE, rt, rs, s); > + break; > + case NM_P_LLE: > + switch (extract32(ctx->opcode, 2, 2)) { > + case NM_LLE: > + check_xnp(ctx); > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_ld(ctx, OPC_LLE, rt, rs, s); > + break; > + case NM_LLWPE: > + check_xnp(ctx); > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, > 5)); > + default: > + generate_exception_end(ctx, EXCP_RI); > + break; > + } > + break; > + case NM_P_SCE: > + switch (extract32(ctx->opcode, 2, 2)) { > + case NM_SCE: > + check_xnp(ctx); > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_st_cond(ctx, OPC_SCE, rt, rs, s); > + break; > + case NM_SCWPE: > + check_xnp(ctx); > + check_eva(ctx); > + check_cp0_enabled(ctx); > + gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, > 5)); > + default: > + generate_exception_end(ctx, EXCP_RI); > + break; > + } > + break; > + } > + break; > case NM_P_LS_WM: > case NM_P_LS_UAWM: > check_nms(ctx);