Skip to content

Commit

Permalink
target/mips: Implement emulation of nanoMIPS EVA instructions
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dimitrije Nikolic authored and AMarkovic committed Oct 25, 2018
1 parent ba1e811 commit d046a9e
Showing 1 changed file with 128 additions and 0 deletions.
128 changes: 128 additions & 0 deletions target/mips/translate.c
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit d046a9e

Please sign in to comment.