target/mips: Add emulation of MMI instruction PCPYLD

Add emulation of MMI instruction PCPYLD. The emulation is implemented
using TCG front end operations directly to achieve better performance.

Backports commit b87eef31f2f8047077d79c3180e9c8e762d2a50f from qemu
This commit is contained in:
Mateja Marjanovic 2019-06-03 11:05:48 -04:00 committed by Lioncash
parent 7443387030
commit c5e3fc601c
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -24550,6 +24550,46 @@ static void gen_mmi_pcpyh(DisasContext *ctx)
}
}
/*
* PCPYLD rd, rs, rt
*
* Parallel Copy Lower Doubleword
*
* 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 | rs | rt | rd | PCPYLD | MMI2 |
* +-----------+---------+---------+---------+---------+-----------+
*/
static void gen_mmi_pcpyld(DisasContext *ctx)
{
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
uint32_t rs, rt, rd;
uint32_t opcode;
opcode = ctx->opcode;
rs = extract32(opcode, 21, 5);
rt = extract32(opcode, 16, 5);
rd = extract32(opcode, 11, 5);
if (rd == 0) {
/* nop */
} else {
if (rs == 0) {
tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_mmr[rd], 0);
} else {
tcg_gen_mov_i64(tcg_ctx, tcg_ctx->cpu_mmr[rd], tcg_ctx->cpu_gpr[rs]);
}
if (rt == 0) {
tcg_gen_movi_i64(tcg_ctx, tcg_ctx->cpu_gpr[rd], 0);
} else {
if (rd != rt) {
tcg_gen_mov_i64(tcg_ctx, tcg_ctx->cpu_gpr[rd], tcg_ctx->cpu_gpr[rt]);
}
}
}
}
#endif
@ -27578,7 +27618,6 @@ static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
case MMI_OPC_2_PCPYLD: /* TODO: MMI_OPC_2_PCPYLD */
case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
@ -27593,6 +27632,9 @@ static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
break;
case MMI_OPC_2_PCPYLD:
gen_mmi_pcpyld(ctx);
break;
default:
MIPS_INVAL("TX79 MMI class MMI2");
generate_exception_end(ctx, EXCP_RI);