aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Janeczek <jancraig@amazon.com>2018-10-18 21:32:20 +0200
committerAleksandar Markovic <amarkovic@wavecomp.com>2018-10-29 14:13:53 +0100
commit96992d1aa1b250c0fffc1ff2dad5e6e4f0b9815b (patch)
treeb975daf4fee55f1173eccea2ef5500323a14970e
parent11d56f61036091206f085e58cff72b6872911d3a (diff)
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. Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com> Signed-off-by: Craig Janeczek <jancraig@amazon.com> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
-rw-r--r--target/mips/translate.c91
1 files changed, 85 insertions, 6 deletions
diff --git a/target/mips/translate.c b/target/mips/translate.c
index bdd46ed49c..3b1dd59382 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2569,6 +2569,36 @@ static inline void gen_store_srsgpr (int from, int to)
}
}
+/* MXU General purpose registers moves. */
+static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
+{
+ if (reg == 0) {
+ tcg_gen_movi_tl(t, 0);
+ } else if (reg <= 15) {
+ tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
+ }
+}
+
+static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
+{
+ if (reg > 0 && reg <= 15) {
+ tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
+ }
+}
+
+/* MXU control register moves. */
+static inline void gen_load_mxu_cr(TCGv t)
+{
+ tcg_gen_mov_tl(t, mxu_CR);
+}
+
+static inline void gen_store_mxu_cr(TCGv t)
+{
+ /* TODO: Add handling of RW rules for MXU_CR. */
+ tcg_gen_mov_tl(mxu_CR, t);
+}
+
+
/* Tests */
static inline void gen_save_pc(target_ulong pc)
{
@@ -24013,6 +24043,59 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
/*
+ * S32I2M XRa, rb - Register move from GRF to XRF
+ */
+static void gen_mxu_s32i2m(DisasContext *ctx)
+{
+ TCGv t0;
+ uint32_t XRa, Rb;
+
+ t0 = tcg_temp_new();
+
+ XRa = extract32(ctx->opcode, 6, 5);
+ Rb = extract32(ctx->opcode, 16, 5);
+
+ gen_load_gpr(t0, Rb);
+ if (XRa <= 15) {
+ gen_store_mxu_gpr(t0, XRa);
+ } else if (XRa == 16) {
+ gen_store_mxu_cr(t0);
+ }
+
+ tcg_temp_free(t0);
+}
+
+/*
+ * S32M2I XRa, rb - Register move from XRF to GRF
+ */
+static void gen_mxu_s32m2i(DisasContext *ctx)
+{
+ TCGv t0;
+ uint32_t XRa, Rb;
+
+ t0 = tcg_temp_new();
+
+ XRa = extract32(ctx->opcode, 6, 5);
+ Rb = extract32(ctx->opcode, 16, 5);
+
+ if (XRa <= 15) {
+ gen_load_mxu_gpr(t0, XRa);
+ } else if (XRa == 16) {
+ gen_load_mxu_cr(t0);
+ }
+
+ gen_store_gpr(t0, Rb);
+
+ tcg_temp_free(t0);
+}
+
+
+/*
+ * Decoding engine for MXU
+ * =======================
+ */
+
+/*
*
* Decode MXU pool00
*
@@ -25091,14 +25174,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. */