mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-22 23:11:03 +00:00
target/mips: Add emulation of MXU instructions S32I2M and S32M2I
Add support for emulating the S32I2M and S32M2I MXU instructions. This commit also contains utility functions for reading/writing to MXU registers. This is required for overall MXU instruction support. Backports commit 96992d1aa1b250c0fffc1ff2dad5e6e4f0b9815b from qemu
This commit is contained in:
parent
8a03757fb0
commit
3862cd205d
|
@ -2558,6 +2558,41 @@ static inline void gen_store_srsgpr (DisasContext *s, int from, int to)
|
|||
}
|
||||
}
|
||||
|
||||
/* MXU General purpose registers moves. */
|
||||
static inline void gen_load_mxu_gpr(DisasContext *ctx, TCGv t, unsigned int reg)
|
||||
{
|
||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||
|
||||
if (reg == 0) {
|
||||
tcg_gen_movi_tl(tcg_ctx, t, 0);
|
||||
} else if (reg <= 15) {
|
||||
tcg_gen_mov_tl(tcg_ctx, t, tcg_ctx->mxu_gpr[reg - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gen_store_mxu_gpr(DisasContext *ctx, TCGv t, unsigned int reg)
|
||||
{
|
||||
if (reg > 0 && reg <= 15) {
|
||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||
tcg_gen_mov_tl(tcg_ctx, tcg_ctx->mxu_gpr[reg - 1], t);
|
||||
}
|
||||
}
|
||||
|
||||
/* MXU control register moves. */
|
||||
static inline void gen_load_mxu_cr(DisasContext *ctx, TCGv t)
|
||||
{
|
||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||
tcg_gen_mov_tl(tcg_ctx, t, tcg_ctx->mxu_CR);
|
||||
}
|
||||
|
||||
static inline void gen_store_mxu_cr(DisasContext *ctx, TCGv t)
|
||||
{
|
||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||
/* TODO: Add handling of RW rules for MXU_CR. */
|
||||
tcg_gen_mov_tl(tcg_ctx, tcg_ctx->mxu_CR, t);
|
||||
}
|
||||
|
||||
|
||||
/* Tests */
|
||||
static inline void gen_save_pc(DisasContext *ctx, target_ulong pc)
|
||||
{
|
||||
|
@ -24154,6 +24189,61 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
|
|||
#define MXU_OPTN3_PTN7 7
|
||||
|
||||
|
||||
/*
|
||||
* S32I2M XRa, rb - Register move from GRF to XRF
|
||||
*/
|
||||
static void gen_mxu_s32i2m(DisasContext *ctx)
|
||||
{
|
||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||
TCGv t0;
|
||||
uint32_t XRa, Rb;
|
||||
|
||||
t0 = tcg_temp_new(tcg_ctx);
|
||||
|
||||
XRa = extract32(ctx->opcode, 6, 5);
|
||||
Rb = extract32(ctx->opcode, 16, 5);
|
||||
|
||||
gen_load_gpr(ctx, t0, Rb);
|
||||
if (XRa <= 15) {
|
||||
gen_store_mxu_gpr(ctx, t0, XRa);
|
||||
} else if (XRa == 16) {
|
||||
gen_store_mxu_cr(ctx, t0);
|
||||
}
|
||||
|
||||
tcg_temp_free(tcg_ctx, t0);
|
||||
}
|
||||
|
||||
/*
|
||||
* S32M2I XRa, rb - Register move from XRF to GRF
|
||||
*/
|
||||
static void gen_mxu_s32m2i(DisasContext *ctx)
|
||||
{
|
||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||
TCGv t0;
|
||||
uint32_t XRa, Rb;
|
||||
|
||||
t0 = tcg_temp_new(tcg_ctx);
|
||||
|
||||
XRa = extract32(ctx->opcode, 6, 5);
|
||||
Rb = extract32(ctx->opcode, 16, 5);
|
||||
|
||||
if (XRa <= 15) {
|
||||
gen_load_mxu_gpr(ctx, t0, XRa);
|
||||
} else if (XRa == 16) {
|
||||
gen_load_mxu_cr(ctx, t0);
|
||||
}
|
||||
|
||||
gen_store_gpr(ctx, t0, Rb);
|
||||
|
||||
tcg_temp_free(tcg_ctx, t0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decoding engine for MXU
|
||||
* =======================
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Decode MXU pool00
|
||||
|
@ -25233,14 +25323,10 @@ static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
|
|||
generate_exception_end(ctx, EXCP_RI);
|
||||
break;
|
||||
case OPC_MXU_S32M2I:
|
||||
/* TODO: Implement emulation of S32M2I instruction. */
|
||||
MIPS_INVAL("OPC_MXU_S32M2I");
|
||||
generate_exception_end(ctx, EXCP_RI);
|
||||
gen_mxu_s32m2i(ctx);
|
||||
break;
|
||||
case OPC_MXU_S32I2M:
|
||||
/* TODO: Implement emulation of S32I2M instruction. */
|
||||
MIPS_INVAL("OPC_MXU_S32I2M");
|
||||
generate_exception_end(ctx, EXCP_RI);
|
||||
gen_mxu_s32i2m(ctx);
|
||||
break;
|
||||
case OPC_MXU_D32SLL:
|
||||
/* TODO: Implement emulation of D32SLL instruction. */
|
||||
|
|
Loading…
Reference in a new issue