145183ccdSTaylor Simpson /* 245183ccdSTaylor Simpson * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. 345183ccdSTaylor Simpson * 445183ccdSTaylor Simpson * This program is free software; you can redistribute it and/or modify 545183ccdSTaylor Simpson * it under the terms of the GNU General Public License as published by 645183ccdSTaylor Simpson * the Free Software Foundation; either version 2 of the License, or 745183ccdSTaylor Simpson * (at your option) any later version. 845183ccdSTaylor Simpson * 945183ccdSTaylor Simpson * This program is distributed in the hope that it will be useful, 1045183ccdSTaylor Simpson * but WITHOUT ANY WARRANTY; without even the implied warranty of 1145183ccdSTaylor Simpson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1245183ccdSTaylor Simpson * GNU General Public License for more details. 1345183ccdSTaylor Simpson * 1445183ccdSTaylor Simpson * You should have received a copy of the GNU General Public License 1545183ccdSTaylor Simpson * along with this program; if not, see <http://www.gnu.org/licenses/>. 1645183ccdSTaylor Simpson */ 1745183ccdSTaylor Simpson 1845183ccdSTaylor Simpson #include "qemu/osdep.h" 1945183ccdSTaylor Simpson #include "qemu/qemu-print.h" 2045183ccdSTaylor Simpson #include "cpu.h" 2145183ccdSTaylor Simpson #include "internal.h" 2245183ccdSTaylor Simpson #include "exec/exec-all.h" 2345183ccdSTaylor Simpson #include "qapi/error.h" 2445183ccdSTaylor Simpson #include "hw/qdev-properties.h" 25c0336c87STaylor Simpson #include "fpu/softfloat-helpers.h" 2645183ccdSTaylor Simpson 2745183ccdSTaylor Simpson static void hexagon_v67_cpu_init(Object *obj) 2845183ccdSTaylor Simpson { 2945183ccdSTaylor Simpson } 3045183ccdSTaylor Simpson 3145183ccdSTaylor Simpson static ObjectClass *hexagon_cpu_class_by_name(const char *cpu_model) 3245183ccdSTaylor Simpson { 3345183ccdSTaylor Simpson ObjectClass *oc; 3445183ccdSTaylor Simpson char *typename; 3545183ccdSTaylor Simpson char **cpuname; 3645183ccdSTaylor Simpson 3745183ccdSTaylor Simpson cpuname = g_strsplit(cpu_model, ",", 1); 3845183ccdSTaylor Simpson typename = g_strdup_printf(HEXAGON_CPU_TYPE_NAME("%s"), cpuname[0]); 3945183ccdSTaylor Simpson oc = object_class_by_name(typename); 4045183ccdSTaylor Simpson g_strfreev(cpuname); 4145183ccdSTaylor Simpson g_free(typename); 4245183ccdSTaylor Simpson if (!oc || !object_class_dynamic_cast(oc, TYPE_HEXAGON_CPU) || 4345183ccdSTaylor Simpson object_class_is_abstract(oc)) { 4445183ccdSTaylor Simpson return NULL; 4545183ccdSTaylor Simpson } 4645183ccdSTaylor Simpson return oc; 4745183ccdSTaylor Simpson } 4845183ccdSTaylor Simpson 4945183ccdSTaylor Simpson static Property hexagon_lldb_compat_property = 5045183ccdSTaylor Simpson DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false); 5145183ccdSTaylor Simpson static Property hexagon_lldb_stack_adjust_property = 5245183ccdSTaylor Simpson DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, 5345183ccdSTaylor Simpson 0, qdev_prop_uint32, target_ulong); 5445183ccdSTaylor Simpson 5545183ccdSTaylor Simpson const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = { 5645183ccdSTaylor Simpson "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 5745183ccdSTaylor Simpson "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 5845183ccdSTaylor Simpson "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 5945183ccdSTaylor Simpson "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 6045183ccdSTaylor Simpson "sa0", "lc0", "sa1", "lc1", "p3_0", "c5", "m0", "m1", 6145183ccdSTaylor Simpson "usr", "pc", "ugp", "gp", "cs0", "cs1", "c14", "c15", 6240438b67STaylor Simpson "c16", "c17", "c18", "c19", "pkt_cnt", "insn_cnt", "hvx_cnt", "c23", 6345183ccdSTaylor Simpson "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31", 6445183ccdSTaylor Simpson }; 6545183ccdSTaylor Simpson 6645183ccdSTaylor Simpson /* 6745183ccdSTaylor Simpson * One of the main debugging techniques is to use "-d cpu" and compare against 6845183ccdSTaylor Simpson * LLDB output when single stepping. However, the target and qemu put the 6945183ccdSTaylor Simpson * stacks at different locations. This is used to compensate so the diff is 7045183ccdSTaylor Simpson * cleaner. 7145183ccdSTaylor Simpson */ 722d27cebbSTaylor Simpson static target_ulong adjust_stack_ptrs(CPUHexagonState *env, target_ulong addr) 7345183ccdSTaylor Simpson { 747d9ab202STaylor Simpson HexagonCPU *cpu = env_archcpu(env); 7545183ccdSTaylor Simpson target_ulong stack_adjust = cpu->lldb_stack_adjust; 7645183ccdSTaylor Simpson target_ulong stack_start = env->stack_start; 7745183ccdSTaylor Simpson target_ulong stack_size = 0x10000; 7845183ccdSTaylor Simpson 7945183ccdSTaylor Simpson if (stack_adjust == 0) { 8045183ccdSTaylor Simpson return addr; 8145183ccdSTaylor Simpson } 8245183ccdSTaylor Simpson 8345183ccdSTaylor Simpson if (stack_start + 0x1000 >= addr && addr >= (stack_start - stack_size)) { 8445183ccdSTaylor Simpson return addr - stack_adjust; 8545183ccdSTaylor Simpson } 8645183ccdSTaylor Simpson return addr; 8745183ccdSTaylor Simpson } 8845183ccdSTaylor Simpson 8945183ccdSTaylor Simpson /* HEX_REG_P3_0 (aka C4) is an alias for the predicate registers */ 902d27cebbSTaylor Simpson static target_ulong read_p3_0(CPUHexagonState *env) 9145183ccdSTaylor Simpson { 9245183ccdSTaylor Simpson int32_t control_reg = 0; 9345183ccdSTaylor Simpson int i; 9445183ccdSTaylor Simpson for (i = NUM_PREGS - 1; i >= 0; i--) { 9545183ccdSTaylor Simpson control_reg <<= 8; 9645183ccdSTaylor Simpson control_reg |= env->pred[i] & 0xff; 9745183ccdSTaylor Simpson } 9845183ccdSTaylor Simpson return control_reg; 9945183ccdSTaylor Simpson } 10045183ccdSTaylor Simpson 10145183ccdSTaylor Simpson static void print_reg(FILE *f, CPUHexagonState *env, int regnum) 10245183ccdSTaylor Simpson { 10345183ccdSTaylor Simpson target_ulong value; 10445183ccdSTaylor Simpson 10545183ccdSTaylor Simpson if (regnum == HEX_REG_P3_0) { 10645183ccdSTaylor Simpson value = read_p3_0(env); 10745183ccdSTaylor Simpson } else { 10845183ccdSTaylor Simpson value = regnum < 32 ? adjust_stack_ptrs(env, env->gpr[regnum]) 10945183ccdSTaylor Simpson : env->gpr[regnum]; 11045183ccdSTaylor Simpson } 11145183ccdSTaylor Simpson 11245183ccdSTaylor Simpson qemu_fprintf(f, " %s = 0x" TARGET_FMT_lx "\n", 11345183ccdSTaylor Simpson hexagon_regnames[regnum], value); 11445183ccdSTaylor Simpson } 11545183ccdSTaylor Simpson 116a1559537STaylor Simpson static void print_vreg(FILE *f, CPUHexagonState *env, int regnum, 117a1559537STaylor Simpson bool skip_if_zero) 118a1559537STaylor Simpson { 119a1559537STaylor Simpson if (skip_if_zero) { 120a1559537STaylor Simpson bool nonzero_found = false; 121a1559537STaylor Simpson for (int i = 0; i < MAX_VEC_SIZE_BYTES; i++) { 122a1559537STaylor Simpson if (env->VRegs[regnum].ub[i] != 0) { 123a1559537STaylor Simpson nonzero_found = true; 124a1559537STaylor Simpson break; 125a1559537STaylor Simpson } 126a1559537STaylor Simpson } 127a1559537STaylor Simpson if (!nonzero_found) { 128a1559537STaylor Simpson return; 129a1559537STaylor Simpson } 130a1559537STaylor Simpson } 131a1559537STaylor Simpson 132a1559537STaylor Simpson qemu_fprintf(f, " v%d = ( ", regnum); 133a1559537STaylor Simpson qemu_fprintf(f, "0x%02x", env->VRegs[regnum].ub[MAX_VEC_SIZE_BYTES - 1]); 134a1559537STaylor Simpson for (int i = MAX_VEC_SIZE_BYTES - 2; i >= 0; i--) { 135a1559537STaylor Simpson qemu_fprintf(f, ", 0x%02x", env->VRegs[regnum].ub[i]); 136a1559537STaylor Simpson } 137a1559537STaylor Simpson qemu_fprintf(f, " )\n"); 138a1559537STaylor Simpson } 139a1559537STaylor Simpson 140a1559537STaylor Simpson void hexagon_debug_vreg(CPUHexagonState *env, int regnum) 141a1559537STaylor Simpson { 142a1559537STaylor Simpson print_vreg(stdout, env, regnum, false); 143a1559537STaylor Simpson } 144a1559537STaylor Simpson 145a1559537STaylor Simpson static void print_qreg(FILE *f, CPUHexagonState *env, int regnum, 146a1559537STaylor Simpson bool skip_if_zero) 147a1559537STaylor Simpson { 148a1559537STaylor Simpson if (skip_if_zero) { 149a1559537STaylor Simpson bool nonzero_found = false; 150a1559537STaylor Simpson for (int i = 0; i < MAX_VEC_SIZE_BYTES / 8; i++) { 151a1559537STaylor Simpson if (env->QRegs[regnum].ub[i] != 0) { 152a1559537STaylor Simpson nonzero_found = true; 153a1559537STaylor Simpson break; 154a1559537STaylor Simpson } 155a1559537STaylor Simpson } 156a1559537STaylor Simpson if (!nonzero_found) { 157a1559537STaylor Simpson return; 158a1559537STaylor Simpson } 159a1559537STaylor Simpson } 160a1559537STaylor Simpson 161a1559537STaylor Simpson qemu_fprintf(f, " q%d = ( ", regnum); 162a1559537STaylor Simpson qemu_fprintf(f, "0x%02x", 163a1559537STaylor Simpson env->QRegs[regnum].ub[MAX_VEC_SIZE_BYTES / 8 - 1]); 164a1559537STaylor Simpson for (int i = MAX_VEC_SIZE_BYTES / 8 - 2; i >= 0; i--) { 165a1559537STaylor Simpson qemu_fprintf(f, ", 0x%02x", env->QRegs[regnum].ub[i]); 166a1559537STaylor Simpson } 167a1559537STaylor Simpson qemu_fprintf(f, " )\n"); 168a1559537STaylor Simpson } 169a1559537STaylor Simpson 170a1559537STaylor Simpson void hexagon_debug_qreg(CPUHexagonState *env, int regnum) 171a1559537STaylor Simpson { 172a1559537STaylor Simpson print_qreg(stdout, env, regnum, false); 173a1559537STaylor Simpson } 174a1559537STaylor Simpson 175a1559537STaylor Simpson static void hexagon_dump(CPUHexagonState *env, FILE *f, int flags) 17645183ccdSTaylor Simpson { 1777d9ab202STaylor Simpson HexagonCPU *cpu = env_archcpu(env); 17845183ccdSTaylor Simpson 17945183ccdSTaylor Simpson if (cpu->lldb_compat) { 18045183ccdSTaylor Simpson /* 18145183ccdSTaylor Simpson * When comparing with LLDB, it doesn't step through single-cycle 18245183ccdSTaylor Simpson * hardware loops the same way. So, we just skip them here 18345183ccdSTaylor Simpson */ 18445183ccdSTaylor Simpson if (env->gpr[HEX_REG_PC] == env->last_pc_dumped) { 18545183ccdSTaylor Simpson return; 18645183ccdSTaylor Simpson } 18745183ccdSTaylor Simpson env->last_pc_dumped = env->gpr[HEX_REG_PC]; 18845183ccdSTaylor Simpson } 18945183ccdSTaylor Simpson 19045183ccdSTaylor Simpson qemu_fprintf(f, "General Purpose Registers = {\n"); 19145183ccdSTaylor Simpson for (int i = 0; i < 32; i++) { 19245183ccdSTaylor Simpson print_reg(f, env, i); 19345183ccdSTaylor Simpson } 19445183ccdSTaylor Simpson print_reg(f, env, HEX_REG_SA0); 19545183ccdSTaylor Simpson print_reg(f, env, HEX_REG_LC0); 19645183ccdSTaylor Simpson print_reg(f, env, HEX_REG_SA1); 19745183ccdSTaylor Simpson print_reg(f, env, HEX_REG_LC1); 19845183ccdSTaylor Simpson print_reg(f, env, HEX_REG_M0); 19945183ccdSTaylor Simpson print_reg(f, env, HEX_REG_M1); 20045183ccdSTaylor Simpson print_reg(f, env, HEX_REG_USR); 20145183ccdSTaylor Simpson print_reg(f, env, HEX_REG_P3_0); 20245183ccdSTaylor Simpson print_reg(f, env, HEX_REG_GP); 20345183ccdSTaylor Simpson print_reg(f, env, HEX_REG_UGP); 20445183ccdSTaylor Simpson print_reg(f, env, HEX_REG_PC); 20545183ccdSTaylor Simpson #ifdef CONFIG_USER_ONLY 20645183ccdSTaylor Simpson /* 20745183ccdSTaylor Simpson * Not modelled in user mode, print junk to minimize the diff's 20845183ccdSTaylor Simpson * with LLDB output 20945183ccdSTaylor Simpson */ 21045183ccdSTaylor Simpson qemu_fprintf(f, " cause = 0x000000db\n"); 21145183ccdSTaylor Simpson qemu_fprintf(f, " badva = 0x00000000\n"); 21245183ccdSTaylor Simpson qemu_fprintf(f, " cs0 = 0x00000000\n"); 21345183ccdSTaylor Simpson qemu_fprintf(f, " cs1 = 0x00000000\n"); 21445183ccdSTaylor Simpson #else 21545183ccdSTaylor Simpson print_reg(f, env, HEX_REG_CAUSE); 21645183ccdSTaylor Simpson print_reg(f, env, HEX_REG_BADVA); 21745183ccdSTaylor Simpson print_reg(f, env, HEX_REG_CS0); 21845183ccdSTaylor Simpson print_reg(f, env, HEX_REG_CS1); 21945183ccdSTaylor Simpson #endif 22045183ccdSTaylor Simpson qemu_fprintf(f, "}\n"); 221a1559537STaylor Simpson 222a1559537STaylor Simpson if (flags & CPU_DUMP_FPU) { 223a1559537STaylor Simpson qemu_fprintf(f, "Vector Registers = {\n"); 224a1559537STaylor Simpson for (int i = 0; i < NUM_VREGS; i++) { 225a1559537STaylor Simpson print_vreg(f, env, i, true); 226a1559537STaylor Simpson } 227a1559537STaylor Simpson for (int i = 0; i < NUM_QREGS; i++) { 228a1559537STaylor Simpson print_qreg(f, env, i, true); 229a1559537STaylor Simpson } 230a1559537STaylor Simpson qemu_fprintf(f, "}\n"); 231a1559537STaylor Simpson } 23245183ccdSTaylor Simpson } 23345183ccdSTaylor Simpson 23445183ccdSTaylor Simpson static void hexagon_dump_state(CPUState *cs, FILE *f, int flags) 23545183ccdSTaylor Simpson { 23645183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 23745183ccdSTaylor Simpson CPUHexagonState *env = &cpu->env; 23845183ccdSTaylor Simpson 239a1559537STaylor Simpson hexagon_dump(env, f, flags); 24045183ccdSTaylor Simpson } 24145183ccdSTaylor Simpson 24245183ccdSTaylor Simpson void hexagon_debug(CPUHexagonState *env) 24345183ccdSTaylor Simpson { 244a1559537STaylor Simpson hexagon_dump(env, stdout, CPU_DUMP_FPU); 24545183ccdSTaylor Simpson } 24645183ccdSTaylor Simpson 24745183ccdSTaylor Simpson static void hexagon_cpu_set_pc(CPUState *cs, vaddr value) 24845183ccdSTaylor Simpson { 24945183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 25045183ccdSTaylor Simpson CPUHexagonState *env = &cpu->env; 25145183ccdSTaylor Simpson env->gpr[HEX_REG_PC] = value; 25245183ccdSTaylor Simpson } 25345183ccdSTaylor Simpson 254e4fdf9dfSRichard Henderson static vaddr hexagon_cpu_get_pc(CPUState *cs) 255e4fdf9dfSRichard Henderson { 256e4fdf9dfSRichard Henderson HexagonCPU *cpu = HEXAGON_CPU(cs); 257e4fdf9dfSRichard Henderson CPUHexagonState *env = &cpu->env; 258e4fdf9dfSRichard Henderson return env->gpr[HEX_REG_PC]; 259e4fdf9dfSRichard Henderson } 260e4fdf9dfSRichard Henderson 26145183ccdSTaylor Simpson static void hexagon_cpu_synchronize_from_tb(CPUState *cs, 26245183ccdSTaylor Simpson const TranslationBlock *tb) 26345183ccdSTaylor Simpson { 26445183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 26545183ccdSTaylor Simpson CPUHexagonState *env = &cpu->env; 266fbf59aadSRichard Henderson env->gpr[HEX_REG_PC] = tb_pc(tb); 26745183ccdSTaylor Simpson } 26845183ccdSTaylor Simpson 26945183ccdSTaylor Simpson static bool hexagon_cpu_has_work(CPUState *cs) 27045183ccdSTaylor Simpson { 27145183ccdSTaylor Simpson return true; 27245183ccdSTaylor Simpson } 27345183ccdSTaylor Simpson 27490157814SRichard Henderson static void hexagon_restore_state_to_opc(CPUState *cs, 27590157814SRichard Henderson const TranslationBlock *tb, 27690157814SRichard Henderson const uint64_t *data) 27745183ccdSTaylor Simpson { 27890157814SRichard Henderson HexagonCPU *cpu = HEXAGON_CPU(cs); 27990157814SRichard Henderson CPUHexagonState *env = &cpu->env; 28090157814SRichard Henderson 28145183ccdSTaylor Simpson env->gpr[HEX_REG_PC] = data[0]; 28245183ccdSTaylor Simpson } 28345183ccdSTaylor Simpson 284*ab85156dSPeter Maydell static void hexagon_cpu_reset_hold(Object *obj) 28545183ccdSTaylor Simpson { 286*ab85156dSPeter Maydell CPUState *cs = CPU(obj); 28745183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 28845183ccdSTaylor Simpson HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(cpu); 289c0336c87STaylor Simpson CPUHexagonState *env = &cpu->env; 29045183ccdSTaylor Simpson 291*ab85156dSPeter Maydell if (mcc->parent_phases.hold) { 292*ab85156dSPeter Maydell mcc->parent_phases.hold(obj); 293*ab85156dSPeter Maydell } 294c0336c87STaylor Simpson 295c0336c87STaylor Simpson set_default_nan_mode(1, &env->fp_status); 296c0336c87STaylor Simpson set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status); 29745183ccdSTaylor Simpson } 29845183ccdSTaylor Simpson 29945183ccdSTaylor Simpson static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info) 30045183ccdSTaylor Simpson { 30145183ccdSTaylor Simpson info->print_insn = print_insn_hexagon; 30245183ccdSTaylor Simpson } 30345183ccdSTaylor Simpson 30445183ccdSTaylor Simpson static void hexagon_cpu_realize(DeviceState *dev, Error **errp) 30545183ccdSTaylor Simpson { 30645183ccdSTaylor Simpson CPUState *cs = CPU(dev); 30745183ccdSTaylor Simpson HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(dev); 30845183ccdSTaylor Simpson Error *local_err = NULL; 30945183ccdSTaylor Simpson 31045183ccdSTaylor Simpson cpu_exec_realizefn(cs, &local_err); 31145183ccdSTaylor Simpson if (local_err != NULL) { 31245183ccdSTaylor Simpson error_propagate(errp, local_err); 31345183ccdSTaylor Simpson return; 31445183ccdSTaylor Simpson } 31545183ccdSTaylor Simpson 31645183ccdSTaylor Simpson qemu_init_vcpu(cs); 31745183ccdSTaylor Simpson cpu_reset(cs); 31845183ccdSTaylor Simpson 31945183ccdSTaylor Simpson mcc->parent_realize(dev, errp); 32045183ccdSTaylor Simpson } 32145183ccdSTaylor Simpson 32245183ccdSTaylor Simpson static void hexagon_cpu_init(Object *obj) 32345183ccdSTaylor Simpson { 32445183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(obj); 32545183ccdSTaylor Simpson 32645183ccdSTaylor Simpson cpu_set_cpustate_pointers(cpu); 32745183ccdSTaylor Simpson qdev_property_add_static(DEVICE(obj), &hexagon_lldb_compat_property); 32845183ccdSTaylor Simpson qdev_property_add_static(DEVICE(obj), &hexagon_lldb_stack_adjust_property); 32945183ccdSTaylor Simpson } 33045183ccdSTaylor Simpson 33145183ccdSTaylor Simpson #include "hw/core/tcg-cpu-ops.h" 33245183ccdSTaylor Simpson 33311906557SRichard Henderson static const struct TCGCPUOps hexagon_tcg_ops = { 33445183ccdSTaylor Simpson .initialize = hexagon_translate_init, 33545183ccdSTaylor Simpson .synchronize_from_tb = hexagon_cpu_synchronize_from_tb, 33690157814SRichard Henderson .restore_state_to_opc = hexagon_restore_state_to_opc, 33745183ccdSTaylor Simpson }; 33845183ccdSTaylor Simpson 33945183ccdSTaylor Simpson static void hexagon_cpu_class_init(ObjectClass *c, void *data) 34045183ccdSTaylor Simpson { 34145183ccdSTaylor Simpson HexagonCPUClass *mcc = HEXAGON_CPU_CLASS(c); 34245183ccdSTaylor Simpson CPUClass *cc = CPU_CLASS(c); 34345183ccdSTaylor Simpson DeviceClass *dc = DEVICE_CLASS(c); 344*ab85156dSPeter Maydell ResettableClass *rc = RESETTABLE_CLASS(c); 34545183ccdSTaylor Simpson 34645183ccdSTaylor Simpson device_class_set_parent_realize(dc, hexagon_cpu_realize, 34745183ccdSTaylor Simpson &mcc->parent_realize); 34845183ccdSTaylor Simpson 349*ab85156dSPeter Maydell resettable_class_set_parent_phases(rc, NULL, hexagon_cpu_reset_hold, NULL, 350*ab85156dSPeter Maydell &mcc->parent_phases); 35145183ccdSTaylor Simpson 35245183ccdSTaylor Simpson cc->class_by_name = hexagon_cpu_class_by_name; 35345183ccdSTaylor Simpson cc->has_work = hexagon_cpu_has_work; 35445183ccdSTaylor Simpson cc->dump_state = hexagon_dump_state; 35545183ccdSTaylor Simpson cc->set_pc = hexagon_cpu_set_pc; 356e4fdf9dfSRichard Henderson cc->get_pc = hexagon_cpu_get_pc; 35745183ccdSTaylor Simpson cc->gdb_read_register = hexagon_gdb_read_register; 35845183ccdSTaylor Simpson cc->gdb_write_register = hexagon_gdb_write_register; 359a1559537STaylor Simpson cc->gdb_num_core_regs = TOTAL_PER_THREAD_REGS + NUM_VREGS + NUM_QREGS; 36045183ccdSTaylor Simpson cc->gdb_stop_before_watchpoint = true; 36145183ccdSTaylor Simpson cc->disas_set_info = hexagon_cpu_disas_set_info; 36245183ccdSTaylor Simpson cc->tcg_ops = &hexagon_tcg_ops; 36345183ccdSTaylor Simpson } 36445183ccdSTaylor Simpson 36545183ccdSTaylor Simpson #define DEFINE_CPU(type_name, initfn) \ 36645183ccdSTaylor Simpson { \ 36745183ccdSTaylor Simpson .name = type_name, \ 36845183ccdSTaylor Simpson .parent = TYPE_HEXAGON_CPU, \ 36945183ccdSTaylor Simpson .instance_init = initfn \ 37045183ccdSTaylor Simpson } 37145183ccdSTaylor Simpson 37245183ccdSTaylor Simpson static const TypeInfo hexagon_cpu_type_infos[] = { 37345183ccdSTaylor Simpson { 37445183ccdSTaylor Simpson .name = TYPE_HEXAGON_CPU, 37545183ccdSTaylor Simpson .parent = TYPE_CPU, 37645183ccdSTaylor Simpson .instance_size = sizeof(HexagonCPU), 37745183ccdSTaylor Simpson .instance_init = hexagon_cpu_init, 37845183ccdSTaylor Simpson .abstract = true, 37945183ccdSTaylor Simpson .class_size = sizeof(HexagonCPUClass), 38045183ccdSTaylor Simpson .class_init = hexagon_cpu_class_init, 38145183ccdSTaylor Simpson }, 38245183ccdSTaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V67, hexagon_v67_cpu_init), 38345183ccdSTaylor Simpson }; 38445183ccdSTaylor Simpson 38545183ccdSTaylor Simpson DEFINE_TYPES(hexagon_cpu_type_infos) 386