target/mips: Implement emulation of nanoMIPS EVA instructions
Implement emulation of nanoMIPS EVA instructions. They are all part of P.LS.E0 instruction pool, or one of its subpools. Reviewed-by: Stefan Markovic <smarkovic@wavecomp.com> Signed-off-by: Dimitrije Nikolic <dnikolic@wavecomp.com> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
This commit is contained in:
parent
ba1e81171f
commit
d046a9ea1b
@ -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)))) {
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user