diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index f93a82b4..4e1d9c1c 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -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. */