On Thu, Apr 29, 2021 at 01:21:24PM -0300, Bruno Larsen (billionai) wrote: 65;6203;1c> code motion to remove opcode callback table from > translate_init.c.inc to translate.c in preparation to remove > the #include <translate_init.c.inc> from translate.c. Also created > destroy_ppc_opcodes and removed that logic from ppc_cpu_unrealize > > Signed-off-by: Bruno Larsen (billionai) > <bruno.lar...@eldorado.org.br>
Applied to ppc-for-6.1, thanks. > --- > target/ppc/internal.h | 8 + > target/ppc/translate.c | 394 ++++++++++++++++++++++++++++++++ > target/ppc/translate_init.c.inc | 391 +------------------------------ > 3 files changed, 403 insertions(+), 390 deletions(-) > > diff --git a/target/ppc/internal.h b/target/ppc/internal.h > index c401658e8d..184ba6d6b3 100644 > --- a/target/ppc/internal.h > +++ b/target/ppc/internal.h > @@ -216,6 +216,14 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr > addr, > MMUAccessType access_type, > int mmu_idx, uintptr_t retaddr); > > +/* translate.c */ > + > +/* #define PPC_DUMP_CPU */ > + > +int ppc_fixup_cpu(PowerPCCPU *cpu); > +void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp); > +void destroy_ppc_opcodes(PowerPCCPU *cpu); > + > /* gdbstub.c */ > void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc); > gchar *ppc_gdb_arch_name(CPUState *cs); > diff --git a/target/ppc/translate.c b/target/ppc/translate.c > index 0984ce637b..b319d409c6 100644 > --- a/target/ppc/translate.c > +++ b/target/ppc/translate.c > @@ -7825,6 +7825,400 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int > flags) > #undef RFPL > } > > +/*****************************************************************************/ > +/* Opcode types */ > +enum { > + PPC_DIRECT = 0, /* Opcode routine */ > + PPC_INDIRECT = 1, /* Indirect opcode table */ > +}; > + > +#define PPC_OPCODE_MASK 0x3 > + > +static inline int is_indirect_opcode(void *handler) > +{ > + return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT; > +} > + > +static inline opc_handler_t **ind_table(void *handler) > +{ > + return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK); > +} > + > +/* Instruction table creation */ > +/* Opcodes tables creation */ > +static void fill_new_table(opc_handler_t **table, int len) > +{ > + int i; > + > + for (i = 0; i < len; i++) { > + table[i] = &invalid_handler; > + } > +} > + > +static int create_new_table(opc_handler_t **table, unsigned char idx) > +{ > + opc_handler_t **tmp; > + > + tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN); > + fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN); > + table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT); > + > + return 0; > +} > + > +static int insert_in_table(opc_handler_t **table, unsigned char idx, > + opc_handler_t *handler) > +{ > + if (table[idx] != &invalid_handler) { > + return -1; > + } > + table[idx] = handler; > + > + return 0; > +} > + > +static int register_direct_insn(opc_handler_t **ppc_opcodes, > + unsigned char idx, opc_handler_t *handler) > +{ > + if (insert_in_table(ppc_opcodes, idx, handler) < 0) { > + printf("*** ERROR: opcode %02x already assigned in main " > + "opcode table\n", idx); > +#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) > + printf(" Registered handler '%s' - new handler '%s'\n", > + ppc_opcodes[idx]->oname, handler->oname); > +#endif > + return -1; > + } > + > + return 0; > +} > + > +static int register_ind_in_table(opc_handler_t **table, > + unsigned char idx1, unsigned char idx2, > + opc_handler_t *handler) > +{ > + if (table[idx1] == &invalid_handler) { > + if (create_new_table(table, idx1) < 0) { > + printf("*** ERROR: unable to create indirect table " > + "idx=%02x\n", idx1); > + return -1; > + } > + } else { > + if (!is_indirect_opcode(table[idx1])) { > + printf("*** ERROR: idx %02x already assigned to a direct " > + "opcode\n", idx1); > +#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) > + printf(" Registered handler '%s' - new handler '%s'\n", > + ind_table(table[idx1])[idx2]->oname, handler->oname); > +#endif > + return -1; > + } > + } > + if (handler != NULL && > + insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) { > + printf("*** ERROR: opcode %02x already assigned in " > + "opcode table %02x\n", idx2, idx1); > +#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) > + printf(" Registered handler '%s' - new handler '%s'\n", > + ind_table(table[idx1])[idx2]->oname, handler->oname); > +#endif > + return -1; > + } > + > + return 0; > +} > + > +static int register_ind_insn(opc_handler_t **ppc_opcodes, > + unsigned char idx1, unsigned char idx2, > + opc_handler_t *handler) > +{ > + return register_ind_in_table(ppc_opcodes, idx1, idx2, handler); > +} > + > +static int register_dblind_insn(opc_handler_t **ppc_opcodes, > + unsigned char idx1, unsigned char idx2, > + unsigned char idx3, opc_handler_t *handler) > +{ > + if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { > + printf("*** ERROR: unable to join indirect table idx " > + "[%02x-%02x]\n", idx1, idx2); > + return -1; > + } > + if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3, > + handler) < 0) { > + printf("*** ERROR: unable to insert opcode " > + "[%02x-%02x-%02x]\n", idx1, idx2, idx3); > + return -1; > + } > + > + return 0; > +} > + > +static int register_trplind_insn(opc_handler_t **ppc_opcodes, > + unsigned char idx1, unsigned char idx2, > + unsigned char idx3, unsigned char idx4, > + opc_handler_t *handler) > +{ > + opc_handler_t **table; > + > + if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { > + printf("*** ERROR: unable to join indirect table idx " > + "[%02x-%02x]\n", idx1, idx2); > + return -1; > + } > + table = ind_table(ppc_opcodes[idx1]); > + if (register_ind_in_table(table, idx2, idx3, NULL) < 0) { > + printf("*** ERROR: unable to join 2nd-level indirect table idx " > + "[%02x-%02x-%02x]\n", idx1, idx2, idx3); > + return -1; > + } > + table = ind_table(table[idx2]); > + if (register_ind_in_table(table, idx3, idx4, handler) < 0) { > + printf("*** ERROR: unable to insert opcode " > + "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4); > + return -1; > + } > + return 0; > +} > +static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn) > +{ > + if (insn->opc2 != 0xFF) { > + if (insn->opc3 != 0xFF) { > + if (insn->opc4 != 0xFF) { > + if (register_trplind_insn(ppc_opcodes, insn->opc1, > insn->opc2, > + insn->opc3, insn->opc4, > + &insn->handler) < 0) { > + return -1; > + } > + } else { > + if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2, > + insn->opc3, &insn->handler) < 0) { > + return -1; > + } > + } > + } else { > + if (register_ind_insn(ppc_opcodes, insn->opc1, > + insn->opc2, &insn->handler) < 0) { > + return -1; > + } > + } > + } else { > + if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < > 0) { > + return -1; > + } > + } > + > + return 0; > +} > + > +static int test_opcode_table(opc_handler_t **table, int len) > +{ > + int i, count, tmp; > + > + for (i = 0, count = 0; i < len; i++) { > + /* Consistency fixup */ > + if (table[i] == NULL) { > + table[i] = &invalid_handler; > + } > + if (table[i] != &invalid_handler) { > + if (is_indirect_opcode(table[i])) { > + tmp = test_opcode_table(ind_table(table[i]), > + PPC_CPU_INDIRECT_OPCODES_LEN); > + if (tmp == 0) { > + free(table[i]); > + table[i] = &invalid_handler; > + } else { > + count++; > + } > + } else { > + count++; > + } > + } > + } > + > + return count; > +} > + > +static void fix_opcode_tables(opc_handler_t **ppc_opcodes) > +{ > + if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) { > + printf("*** WARNING: no opcode defined !\n"); > + } > +} > + > +/*****************************************************************************/ > +void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) > +{ > + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); > + opcode_t *opc; > + > + fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN); > + for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) { > + if (((opc->handler.type & pcc->insns_flags) != 0) || > + ((opc->handler.type2 & pcc->insns_flags2) != 0)) { > + if (register_insn(cpu->opcodes, opc) < 0) { > + error_setg(errp, "ERROR initializing PowerPC instruction " > + "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2, > + opc->opc3); > + return; > + } > + } > + } > + fix_opcode_tables(cpu->opcodes); > + fflush(stdout); > + fflush(stderr); > +} > + > +void destroy_ppc_opcodes(PowerPCCPU *cpu) > +{ > + opc_handler_t **table, **table_2; > + int i, j, k; > + > + for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { > + if (cpu->opcodes[i] == &invalid_handler) { > + continue; > + } > + if (is_indirect_opcode(cpu->opcodes[i])) { > + table = ind_table(cpu->opcodes[i]); > + for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { > + if (table[j] == &invalid_handler) { > + continue; > + } > + if (is_indirect_opcode(table[j])) { > + table_2 = ind_table(table[j]); > + for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) { > + if (table_2[k] != &invalid_handler && > + is_indirect_opcode(table_2[k])) { > + g_free((opc_handler_t *)((uintptr_t)table_2[k] & > + ~PPC_INDIRECT)); > + } > + } > + g_free((opc_handler_t *)((uintptr_t)table[j] & > + ~PPC_INDIRECT)); > + } > + } > + g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] & > + ~PPC_INDIRECT)); > + } > + } > +} > + > +#if defined(PPC_DUMP_CPU) > +static void dump_ppc_insns(CPUPPCState *env) > +{ > + opc_handler_t **table, *handler; > + const char *p, *q; > + uint8_t opc1, opc2, opc3, opc4; > + > + printf("Instructions set:\n"); > + /* opc1 is 6 bits long */ > + for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) { > + table = env->opcodes; > + handler = table[opc1]; > + if (is_indirect_opcode(handler)) { > + /* opc2 is 5 bits long */ > + for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) { > + table = env->opcodes; > + handler = env->opcodes[opc1]; > + table = ind_table(handler); > + handler = table[opc2]; > + if (is_indirect_opcode(handler)) { > + table = ind_table(handler); > + /* opc3 is 5 bits long */ > + for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN; > + opc3++) { > + handler = table[opc3]; > + if (is_indirect_opcode(handler)) { > + table = ind_table(handler); > + /* opc4 is 5 bits long */ > + for (opc4 = 0; opc4 < > PPC_CPU_INDIRECT_OPCODES_LEN; > + opc4++) { > + handler = table[opc4]; > + if (handler->handler != &gen_invalid) { > + printf("INSN: %02x %02x %02x %02x -- " > + "(%02d %04d %02d) : %s\n", > + opc1, opc2, opc3, opc4, > + opc1, (opc3 << 5) | opc2, opc4, > + handler->oname); > + } > + } > + } else { > + if (handler->handler != &gen_invalid) { > + /* Special hack to properly dump SPE insns */ > + p = strchr(handler->oname, '_'); > + if (p == NULL) { > + printf("INSN: %02x %02x %02x (%02d %04d) > : " > + "%s\n", > + opc1, opc2, opc3, opc1, > + (opc3 << 5) | opc2, > + handler->oname); > + } else { > + q = "speundef"; > + if ((p - handler->oname) != strlen(q) > + || (memcmp(handler->oname, q, > strlen(q)) > + != 0)) { > + /* First instruction */ > + printf("INSN: %02x %02x %02x" > + "(%02d %04d) : %.*s\n", > + opc1, opc2 << 1, opc3, opc1, > + (opc3 << 6) | (opc2 << 1), > + (int)(p - handler->oname), > + handler->oname); > + } > + if (strcmp(p + 1, q) != 0) { > + /* Second instruction */ > + printf("INSN: %02x %02x %02x " > + "(%02d %04d) : %s\n", opc1, > + (opc2 << 1) | 1, opc3, opc1, > + (opc3 << 6) | (opc2 << 1) | 1, > + p + 1); > + } > + } > + } > + } > + } > + } else { > + if (handler->handler != &gen_invalid) { > + printf("INSN: %02x %02x -- (%02d %04d) : %s\n", > + opc1, opc2, opc1, opc2, handler->oname); > + } > + } > + } > + } else { > + if (handler->handler != &gen_invalid) { > + printf("INSN: %02x -- -- (%02d ----) : %s\n", > + opc1, opc1, handler->oname); > + } > + } > + } > +} > +#endif > +int ppc_fixup_cpu(PowerPCCPU *cpu) > +{ > + CPUPPCState *env = &cpu->env; > + > + /* > + * TCG doesn't (yet) emulate some groups of instructions that are > + * implemented on some otherwise supported CPUs (e.g. VSX and > + * decimal floating point instructions on POWER7). We remove > + * unsupported instruction groups from the cpu state's instruction > + * masks and hope the guest can cope. For at least the pseries > + * machine, the unavailability of these instructions can be > + * advertised to the guest via the device tree. > + */ > + if ((env->insns_flags & ~PPC_TCG_INSNS) > + || (env->insns_flags2 & ~PPC_TCG_INSNS2)) { > + warn_report("Disabling some instructions which are not " > + "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")", > + env->insns_flags & ~PPC_TCG_INSNS, > + env->insns_flags2 & ~PPC_TCG_INSNS2); > + } > + env->insns_flags &= PPC_TCG_INSNS; > + env->insns_flags2 &= PPC_TCG_INSNS2; > + return 0; > +} > + > + > void ppc_cpu_dump_statistics(CPUState *cs, int flags) > { > #if defined(DO_PPC_STATISTICS) > diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc > index 80fef0b90d..6235eb7536 100644 > --- a/target/ppc/translate_init.c.inc > +++ b/target/ppc/translate_init.c.inc > @@ -42,7 +42,6 @@ > #include "fpu/softfloat.h" > #include "qapi/qapi-commands-machine-target.h" > > -/* #define PPC_DUMP_CPU */ > /* #define PPC_DEBUG_SPR */ > /* #define PPC_DUMP_SPR_ACCESSES */ > /* #define USE_APPLE_GDB */ > @@ -9560,366 +9559,6 @@ static void dump_ppc_sprs(CPUPPCState *env) > } > #endif > > -/*****************************************************************************/ > - > -/* Opcode types */ > -enum { > - PPC_DIRECT = 0, /* Opcode routine */ > - PPC_INDIRECT = 1, /* Indirect opcode table */ > -}; > - > -#define PPC_OPCODE_MASK 0x3 > - > -static inline int is_indirect_opcode(void *handler) > -{ > - return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT; > -} > - > -static inline opc_handler_t **ind_table(void *handler) > -{ > - return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK); > -} > - > -/* Instruction table creation */ > -/* Opcodes tables creation */ > -static void fill_new_table(opc_handler_t **table, int len) > -{ > - int i; > - > - for (i = 0; i < len; i++) { > - table[i] = &invalid_handler; > - } > -} > - > -static int create_new_table(opc_handler_t **table, unsigned char idx) > -{ > - opc_handler_t **tmp; > - > - tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN); > - fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN); > - table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT); > - > - return 0; > -} > - > -static int insert_in_table(opc_handler_t **table, unsigned char idx, > - opc_handler_t *handler) > -{ > - if (table[idx] != &invalid_handler) { > - return -1; > - } > - table[idx] = handler; > - > - return 0; > -} > - > -static int register_direct_insn(opc_handler_t **ppc_opcodes, > - unsigned char idx, opc_handler_t *handler) > -{ > - if (insert_in_table(ppc_opcodes, idx, handler) < 0) { > - printf("*** ERROR: opcode %02x already assigned in main " > - "opcode table\n", idx); > -#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) > - printf(" Registered handler '%s' - new handler '%s'\n", > - ppc_opcodes[idx]->oname, handler->oname); > -#endif > - return -1; > - } > - > - return 0; > -} > - > -static int register_ind_in_table(opc_handler_t **table, > - unsigned char idx1, unsigned char idx2, > - opc_handler_t *handler) > -{ > - if (table[idx1] == &invalid_handler) { > - if (create_new_table(table, idx1) < 0) { > - printf("*** ERROR: unable to create indirect table " > - "idx=%02x\n", idx1); > - return -1; > - } > - } else { > - if (!is_indirect_opcode(table[idx1])) { > - printf("*** ERROR: idx %02x already assigned to a direct " > - "opcode\n", idx1); > -#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) > - printf(" Registered handler '%s' - new handler '%s'\n", > - ind_table(table[idx1])[idx2]->oname, handler->oname); > -#endif > - return -1; > - } > - } > - if (handler != NULL && > - insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) { > - printf("*** ERROR: opcode %02x already assigned in " > - "opcode table %02x\n", idx2, idx1); > -#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) > - printf(" Registered handler '%s' - new handler '%s'\n", > - ind_table(table[idx1])[idx2]->oname, handler->oname); > -#endif > - return -1; > - } > - > - return 0; > -} > - > -static int register_ind_insn(opc_handler_t **ppc_opcodes, > - unsigned char idx1, unsigned char idx2, > - opc_handler_t *handler) > -{ > - return register_ind_in_table(ppc_opcodes, idx1, idx2, handler); > -} > - > -static int register_dblind_insn(opc_handler_t **ppc_opcodes, > - unsigned char idx1, unsigned char idx2, > - unsigned char idx3, opc_handler_t *handler) > -{ > - if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { > - printf("*** ERROR: unable to join indirect table idx " > - "[%02x-%02x]\n", idx1, idx2); > - return -1; > - } > - if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3, > - handler) < 0) { > - printf("*** ERROR: unable to insert opcode " > - "[%02x-%02x-%02x]\n", idx1, idx2, idx3); > - return -1; > - } > - > - return 0; > -} > - > -static int register_trplind_insn(opc_handler_t **ppc_opcodes, > - unsigned char idx1, unsigned char idx2, > - unsigned char idx3, unsigned char idx4, > - opc_handler_t *handler) > -{ > - opc_handler_t **table; > - > - if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { > - printf("*** ERROR: unable to join indirect table idx " > - "[%02x-%02x]\n", idx1, idx2); > - return -1; > - } > - table = ind_table(ppc_opcodes[idx1]); > - if (register_ind_in_table(table, idx2, idx3, NULL) < 0) { > - printf("*** ERROR: unable to join 2nd-level indirect table idx " > - "[%02x-%02x-%02x]\n", idx1, idx2, idx3); > - return -1; > - } > - table = ind_table(table[idx2]); > - if (register_ind_in_table(table, idx3, idx4, handler) < 0) { > - printf("*** ERROR: unable to insert opcode " > - "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4); > - return -1; > - } > - return 0; > -} > -static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn) > -{ > - if (insn->opc2 != 0xFF) { > - if (insn->opc3 != 0xFF) { > - if (insn->opc4 != 0xFF) { > - if (register_trplind_insn(ppc_opcodes, insn->opc1, > insn->opc2, > - insn->opc3, insn->opc4, > - &insn->handler) < 0) { > - return -1; > - } > - } else { > - if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2, > - insn->opc3, &insn->handler) < 0) { > - return -1; > - } > - } > - } else { > - if (register_ind_insn(ppc_opcodes, insn->opc1, > - insn->opc2, &insn->handler) < 0) { > - return -1; > - } > - } > - } else { > - if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < > 0) { > - return -1; > - } > - } > - > - return 0; > -} > - > -static int test_opcode_table(opc_handler_t **table, int len) > -{ > - int i, count, tmp; > - > - for (i = 0, count = 0; i < len; i++) { > - /* Consistency fixup */ > - if (table[i] == NULL) { > - table[i] = &invalid_handler; > - } > - if (table[i] != &invalid_handler) { > - if (is_indirect_opcode(table[i])) { > - tmp = test_opcode_table(ind_table(table[i]), > - PPC_CPU_INDIRECT_OPCODES_LEN); > - if (tmp == 0) { > - free(table[i]); > - table[i] = &invalid_handler; > - } else { > - count++; > - } > - } else { > - count++; > - } > - } > - } > - > - return count; > -} > - > -static void fix_opcode_tables(opc_handler_t **ppc_opcodes) > -{ > - if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) { > - printf("*** WARNING: no opcode defined !\n"); > - } > -} > - > -/*****************************************************************************/ > -static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) > -{ > - PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); > - opcode_t *opc; > - > - fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN); > - for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) { > - if (((opc->handler.type & pcc->insns_flags) != 0) || > - ((opc->handler.type2 & pcc->insns_flags2) != 0)) { > - if (register_insn(cpu->opcodes, opc) < 0) { > - error_setg(errp, "ERROR initializing PowerPC instruction " > - "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2, > - opc->opc3); > - return; > - } > - } > - } > - fix_opcode_tables(cpu->opcodes); > - fflush(stdout); > - fflush(stderr); > -} > - > -#if defined(PPC_DUMP_CPU) > -static void dump_ppc_insns(CPUPPCState *env) > -{ > - opc_handler_t **table, *handler; > - const char *p, *q; > - uint8_t opc1, opc2, opc3, opc4; > - > - printf("Instructions set:\n"); > - /* opc1 is 6 bits long */ > - for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) { > - table = env->opcodes; > - handler = table[opc1]; > - if (is_indirect_opcode(handler)) { > - /* opc2 is 5 bits long */ > - for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) { > - table = env->opcodes; > - handler = env->opcodes[opc1]; > - table = ind_table(handler); > - handler = table[opc2]; > - if (is_indirect_opcode(handler)) { > - table = ind_table(handler); > - /* opc3 is 5 bits long */ > - for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN; > - opc3++) { > - handler = table[opc3]; > - if (is_indirect_opcode(handler)) { > - table = ind_table(handler); > - /* opc4 is 5 bits long */ > - for (opc4 = 0; opc4 < > PPC_CPU_INDIRECT_OPCODES_LEN; > - opc4++) { > - handler = table[opc4]; > - if (handler->handler != &gen_invalid) { > - printf("INSN: %02x %02x %02x %02x -- " > - "(%02d %04d %02d) : %s\n", > - opc1, opc2, opc3, opc4, > - opc1, (opc3 << 5) | opc2, opc4, > - handler->oname); > - } > - } > - } else { > - if (handler->handler != &gen_invalid) { > - /* Special hack to properly dump SPE insns */ > - p = strchr(handler->oname, '_'); > - if (p == NULL) { > - printf("INSN: %02x %02x %02x (%02d %04d) > : " > - "%s\n", > - opc1, opc2, opc3, opc1, > - (opc3 << 5) | opc2, > - handler->oname); > - } else { > - q = "speundef"; > - if ((p - handler->oname) != strlen(q) > - || (memcmp(handler->oname, q, > strlen(q)) > - != 0)) { > - /* First instruction */ > - printf("INSN: %02x %02x %02x" > - "(%02d %04d) : %.*s\n", > - opc1, opc2 << 1, opc3, opc1, > - (opc3 << 6) | (opc2 << 1), > - (int)(p - handler->oname), > - handler->oname); > - } > - if (strcmp(p + 1, q) != 0) { > - /* Second instruction */ > - printf("INSN: %02x %02x %02x " > - "(%02d %04d) : %s\n", opc1, > - (opc2 << 1) | 1, opc3, opc1, > - (opc3 << 6) | (opc2 << 1) | 1, > - p + 1); > - } > - } > - } > - } > - } > - } else { > - if (handler->handler != &gen_invalid) { > - printf("INSN: %02x %02x -- (%02d %04d) : %s\n", > - opc1, opc2, opc1, opc2, handler->oname); > - } > - } > - } > - } else { > - if (handler->handler != &gen_invalid) { > - printf("INSN: %02x -- -- (%02d ----) : %s\n", > - opc1, opc1, handler->oname); > - } > - } > - } > -} > -#endif > -static int ppc_fixup_cpu(PowerPCCPU *cpu) > -{ > - CPUPPCState *env = &cpu->env; > - > - /* > - * TCG doesn't (yet) emulate some groups of instructions that are > - * implemented on some otherwise supported CPUs (e.g. VSX and > - * decimal floating point instructions on POWER7). We remove > - * unsupported instruction groups from the cpu state's instruction > - * masks and hope the guest can cope. For at least the pseries > - * machine, the unavailability of these instructions can be > - * advertised to the guest via the device tree. > - */ > - if ((env->insns_flags & ~PPC_TCG_INSNS) > - || (env->insns_flags2 & ~PPC_TCG_INSNS2)) { > - warn_report("Disabling some instructions which are not " > - "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")", > - env->insns_flags & ~PPC_TCG_INSNS, > - env->insns_flags2 & ~PPC_TCG_INSNS2); > - } > - env->insns_flags &= PPC_TCG_INSNS; > - env->insns_flags2 &= PPC_TCG_INSNS2; > - return 0; > -} > - > static void ppc_cpu_realize(DeviceState *dev, Error **errp) > { > CPUState *cs = CPU(dev); > @@ -10131,40 +9770,12 @@ static void ppc_cpu_unrealize(DeviceState *dev) > { > PowerPCCPU *cpu = POWERPC_CPU(dev); > PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); > - opc_handler_t **table, **table_2; > - int i, j, k; > > pcc->parent_unrealize(dev); > > cpu_remove_sync(CPU(cpu)); > > - for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { > - if (cpu->opcodes[i] == &invalid_handler) { > - continue; > - } > - if (is_indirect_opcode(cpu->opcodes[i])) { > - table = ind_table(cpu->opcodes[i]); > - for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { > - if (table[j] == &invalid_handler) { > - continue; > - } > - if (is_indirect_opcode(table[j])) { > - table_2 = ind_table(table[j]); > - for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) { > - if (table_2[k] != &invalid_handler && > - is_indirect_opcode(table_2[k])) { > - g_free((opc_handler_t *)((uintptr_t)table_2[k] & > - ~PPC_INDIRECT)); > - } > - } > - g_free((opc_handler_t *)((uintptr_t)table[j] & > - ~PPC_INDIRECT)); > - } > - } > - g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] & > - ~PPC_INDIRECT)); > - } > - } > + destroy_ppc_opcodes(cpu); > } > > static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b) -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature