diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index 4ffd371f..c9b7dbae 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -24487,6 +24487,69 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) * PEXTUW */ +/* + * PCPYH rd, rt + * + * Parallel Copy Halfword + * + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------+---------+---------+---------+---------+-----------+ + * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 | + * +-----------+---------+---------+---------+---------+-----------+ + */ +static void gen_mmi_pcpyh(DisasContext *ctx) +{ + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + uint32_t pd, rt, rd; + uint32_t opcode; + + opcode = ctx->opcode; + + pd = extract32(opcode, 21, 5); + rt = extract32(opcode, 16, 5); + rd = extract32(opcode, 11, 5); + + if (unlikely(pd != 0)) { + generate_exception_end(ctx, EXCP_RI); + } else if (rd == 0) { + /* nop */ + } else if (rt == 0) { + tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_gpr[rd], 0); + tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_mmr[rd], 0); + } else { + TCGv_i64 t0 = tcg_temp_new(tcg_ctx); + TCGv_i64 t1 = tcg_temp_new(tcg_ctx); + uint64_t mask = (1ULL << 16) - 1; + + tcg_gen_andi_i64(tcg_ctx, t0, tcg_ctx->cpu_gpr[rt], mask); + tcg_gen_movi_i64(tcg_ctx, t1, 0); + tcg_gen_or_i64(tcg_ctx, t1, t0, t1); + tcg_gen_shli_i64(tcg_ctx, t0, t0, 16); + tcg_gen_or_i64(tcg_ctx, t1, t0, t1); + tcg_gen_shli_i64(tcg_ctx, t0, t0, 16); + tcg_gen_or_i64(tcg_ctx, t1, t0, t1); + tcg_gen_shli_i64(tcg_ctx, t0, t0, 16); + tcg_gen_or_i64(tcg_ctx, t1, t0, t1); + + tcg_gen_mov_i64(tcg_ctx, tcg_ctx->cpu_gpr[rd], t1); + + tcg_gen_andi_i64(tcg_ctx, t0, tcg_ctx->cpu_mmr[rt], mask); + tcg_gen_movi_i64(tcg_ctx, t1, 0); + tcg_gen_or_i64(tcg_ctx, t1, t0, t1); + tcg_gen_shli_i64(tcg_ctx, t0, t0, 16); + tcg_gen_or_i64(tcg_ctx, t1, t0, t1); + tcg_gen_shli_i64(tcg_ctx, t0, t0, 16); + tcg_gen_or_i64(tcg_ctx, t1, t0, t1); + tcg_gen_shli_i64(tcg_ctx, t0, t0, 16); + tcg_gen_or_i64(tcg_ctx, t1, t0, t1); + + tcg_gen_mov_i64(tcg_ctx, tcg_ctx->cpu_mmr[rd], t1); + + tcg_temp_free(tcg_ctx, t0); + tcg_temp_free(tcg_ctx, t1); + } +} + #endif @@ -27553,10 +27616,12 @@ static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx) case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */ case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */ case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */ - case MMI_OPC_3_PCPYH: /* TODO: MMI_OPC_3_PCPYH */ case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */ generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */ break; + case MMI_OPC_3_PCPYH: + gen_mmi_pcpyh(ctx); + break; default: MIPS_INVAL("TX79 MMI class MMI3"); generate_exception_end(ctx, EXCP_RI);