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:
Craig Janeczek 2018-11-11 06:10:09 -05:00 committed by Lioncash
parent 8a03757fb0
commit 3862cd205d
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -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. */