target/ppc: Split out decode_legacy

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Luis Pires <luis.pires@eldorado.org.br>
Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
Message-Id: <20210512185441.3619828-3-matheus.ferst@eldorado.org.br>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Richard Henderson 2021-05-12 15:54:12 -03:00 committed by David Gibson
parent 2c2bcb1b50
commit 624cb07fde

View file

@ -9062,6 +9062,62 @@ void ppc_cpu_dump_statistics(CPUState *cs, int flags)
#endif
}
static bool decode_legacy(PowerPCCPU *cpu, DisasContext *ctx, uint32_t insn)
{
opc_handler_t **table, *handler;
uint32_t inval;
ctx->opcode = insn;
LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n",
insn, opc1(insn), opc2(insn), opc3(insn), opc4(insn),
ctx->le_mode ? "little" : "big");
table = cpu->opcodes;
handler = table[opc1(insn)];
if (is_indirect_opcode(handler)) {
table = ind_table(handler);
handler = table[opc2(insn)];
if (is_indirect_opcode(handler)) {
table = ind_table(handler);
handler = table[opc3(insn)];
if (is_indirect_opcode(handler)) {
table = ind_table(handler);
handler = table[opc4(insn)];
}
}
}
/* Is opcode *REALLY* valid ? */
if (unlikely(handler->handler == &gen_invalid)) {
qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
"%02x - %02x - %02x - %02x (%08x) "
TARGET_FMT_lx "\n",
opc1(insn), opc2(insn), opc3(insn), opc4(insn),
insn, ctx->cia);
return false;
}
if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE)
&& Rc(insn))) {
inval = handler->inval2;
} else {
inval = handler->inval1;
}
if (unlikely((insn & inval) != 0)) {
qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
"%02x - %02x - %02x - %02x (%08x) "
TARGET_FMT_lx "\n", insn & inval,
opc1(insn), opc2(insn), opc3(insn), opc4(insn),
insn, ctx->cia);
return false;
}
handler->handler(ctx);
return true;
}
static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
@ -9143,66 +9199,23 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
DisasContext *ctx = container_of(dcbase, DisasContext, base);
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = cs->env_ptr;
opc_handler_t **table, *handler;
uint32_t insn;
bool ok;
LOG_DISAS("----------------\n");
LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
ctx->base.pc_next, ctx->mem_idx, (int)msr_ir);
ctx->cia = ctx->base.pc_next;
ctx->opcode = translator_ldl_swap(env, ctx->base.pc_next,
need_byteswap(ctx));
LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n",
ctx->opcode, opc1(ctx->opcode), opc2(ctx->opcode),
opc3(ctx->opcode), opc4(ctx->opcode),
ctx->le_mode ? "little" : "big");
insn = translator_ldl_swap(env, ctx->base.pc_next, need_byteswap(ctx));
ctx->base.pc_next += 4;
table = cpu->opcodes;
handler = table[opc1(ctx->opcode)];
if (is_indirect_opcode(handler)) {
table = ind_table(handler);
handler = table[opc2(ctx->opcode)];
if (is_indirect_opcode(handler)) {
table = ind_table(handler);
handler = table[opc3(ctx->opcode)];
if (is_indirect_opcode(handler)) {
table = ind_table(handler);
handler = table[opc4(ctx->opcode)];
}
}
}
/* Is opcode *REALLY* valid ? */
if (unlikely(handler->handler == &gen_invalid)) {
qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
"%02x - %02x - %02x - %02x (%08x) "
TARGET_FMT_lx " %d\n",
opc1(ctx->opcode), opc2(ctx->opcode),
opc3(ctx->opcode), opc4(ctx->opcode),
ctx->opcode, ctx->cia, (int)msr_ir);
} else {
uint32_t inval;
if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE)
&& Rc(ctx->opcode))) {
inval = handler->inval2;
} else {
inval = handler->inval1;
}
if (unlikely((ctx->opcode & inval) != 0)) {
qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
"%02x - %02x - %02x - %02x (%08x) "
TARGET_FMT_lx "\n", ctx->opcode & inval,
opc1(ctx->opcode), opc2(ctx->opcode),
opc3(ctx->opcode), opc4(ctx->opcode),
ctx->opcode, ctx->cia);
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
ctx->base.is_jmp = DISAS_NORETURN;
return;
}
ok = decode_legacy(cpu, ctx, insn);
if (!ok) {
gen_invalid(ctx);
ctx->base.is_jmp = DISAS_NORETURN;
}
(*(handler->handler))(ctx);
#if defined(DO_PPC_STATISTICS)
handler->count++;
#endif