From: neder <nicolas.e...@lauterbach.com> --- mcdstub/mcd_shared_defines.h | 1 + mcdstub/mcdstub.c | 117 ++++++++++------ mcdstub/mcdstub.h | 18 ++- target/arm/mcdstub.c | 265 ++++++++++++++++++++++++++++++----- target/arm/mcdstub.h | 16 ++- 5 files changed, 330 insertions(+), 87 deletions(-)
diff --git a/mcdstub/mcd_shared_defines.h b/mcdstub/mcd_shared_defines.h index 88d556cab1..91d476a555 100644 --- a/mcdstub/mcd_shared_defines.h +++ b/mcdstub/mcd_shared_defines.h @@ -74,6 +74,7 @@ #define TCP_ARGUMENT_AMOUNT_TRIGGER "nr_trigger" #define TCP_ARGUMENT_OPTION "option" #define TCP_ARGUMENT_ACTION "action" +#define TCP_ARGUMENT_OPCODE "opcode" /* for packets sent to qemu */ #define ARGUMENT_SEPARATOR ';' diff --git a/mcdstub/mcdstub.c b/mcdstub/mcdstub.c index bd532b0f4c..3772bda0a1 100644 --- a/mcdstub/mcdstub.c +++ b/mcdstub/mcdstub.c @@ -1064,10 +1064,12 @@ CPUState *find_cpu(uint32_t thread_id) } -void parse_reg_xml(const char *xml, int size, GArray *registers) +void parse_reg_xml(const char *xml, int size, GArray *registers, + uint8_t reg_type) { /* iterates over the complete xml file */ int i, j; + uint32_t internal_id = 0; int still_to_skip = 0; char argument[64] = {0}; char value[64] = {0}; @@ -1116,8 +1118,11 @@ void parse_reg_xml(const char *xml, int size, GArray *registers) if (strcmp(argument_j, "name") == 0) { strcpy(my_register.name, value_j); - } else if (strcmp(argument_j, "regnum") == 0) { - my_register.id = atoi(value_j); + /* + * we might want to read out the regnum + * } else if (strcmp(argument_j, "regnum") == 0) { + * my_register.internal_id = atoi(value_j); + */ } else if (strcmp(argument_j, "bitsize") == 0) { my_register.bitsize = atoi(value_j); } else if (strcmp(argument_j, "type") == 0) { @@ -1126,6 +1131,10 @@ void parse_reg_xml(const char *xml, int size, GArray *registers) strcpy(my_register.group, value_j); } } + /* add reg_type and internal id */ + my_register.reg_type = reg_type; + my_register.internal_id = internal_id; + internal_id++; /* store register */ g_array_append_vals(registers, (gconstpointer)&my_register, 1); /* free memory */ @@ -1238,6 +1247,7 @@ int mcd_arm_store_mem_spaces(CPUState *cpu, GArray *memspaces) }; g_array_append_vals(memspaces, (gconstpointer)&space4, 1); } + /* TODO: get dynamically how the per (CP15) space is called */ mcd_mem_space_st space5 = { .name = "GPR Registers", @@ -1263,7 +1273,6 @@ int mcd_arm_store_mem_spaces(CPUState *cpu, GArray *memspaces) .supported_access_options = 0, }; g_array_append_vals(memspaces, (gconstpointer)&space6, 1); - return 0; } @@ -1366,7 +1375,8 @@ int mcd_arm_parse_core_xml_file(CPUClass *cc, GArray *reggroups, /* 3. parse xml */ xml_content = xml_builtin[i][1]; - parse_reg_xml(xml_content, strlen(xml_content), registers); + parse_reg_xml(xml_content, strlen(xml_content), registers, + MCD_ARM_REG_TYPE_GPR); return 0; } @@ -1376,6 +1386,7 @@ int mcd_arm_parse_general_xml_files(CPUState *cpu, GArray *reggroups, const char *current_xml_filename = NULL; const char *xml_content = NULL; int i = 0; + uint8_t reg_type; /* iterate over all gdb xml files*/ GDBRegisterState *r; @@ -1395,6 +1406,7 @@ int mcd_arm_parse_general_xml_files(CPUState *cpu, GArray *reggroups, g_array_append_vals(reggroups, (gconstpointer)&corprocessorregs, 1); *current_group_id = *current_group_id + 1; + reg_type = MCD_ARM_REG_TYPE_CPR; } } else { /* its not a coprocessor xml -> it is a static xml file */ @@ -1407,58 +1419,59 @@ int mcd_arm_parse_general_xml_files(CPUState *cpu, GArray *reggroups, } if (current_xml_filename) { xml_content = xml_builtin[i][1]; + /* select correct reg_type */ + if (strcmp(current_xml_filename, "arm-vfp.xml") == 0) { + reg_type = MCD_ARM_REG_TYPE_VFP; + } else if (strcmp(current_xml_filename, "arm-vfp3.xml") == 0) { + reg_type = MCD_ARM_REG_TYPE_VFP; + } else if (strcmp(current_xml_filename, + "arm-vfp-sysregs.xml") == 0) { + reg_type = MCD_ARM_REG_TYPE_VFP_SYS; + } else if (strcmp(current_xml_filename, + "arm-neon.xml") == 0) { + reg_type = MCD_ARM_REG_TYPE_VFP; + } else if (strcmp(current_xml_filename, + "arm-m-profile-mve.xml") == 0) { + reg_type = MCD_ARM_REG_TYPE_MVE; + } } else { continue; } } /* 2. parse xml */ - parse_reg_xml(xml_content, strlen(xml_content), registers); + parse_reg_xml(xml_content, strlen(xml_content), registers, reg_type); } return 0; } -int mcd_arm_get_additional_register_info(GArray *reggroups, GArray *registers) +int mcd_arm_get_additional_register_info(GArray *reggroups, GArray *registers, + CPUState *cpu) { - GList *register_numbers = NULL; mcd_reg_st *current_register; - int i = 0; - int id_neg_offset = 0; - int effective_id = 0; + uint32_t i = 0; /* iterate over all registers */ for (i = 0; i < registers->len; i++) { current_register = &(g_array_index(registers, mcd_reg_st, i)); - /* 1. ad the id */ - if (current_register->id) { - /* - *id is already in place - *NOTE: qemu doesn't emulate the FPA regs - *(so we are missing the indices 16 to 24) - */ - int used_id = current_register->id; - register_numbers = g_list_append(register_numbers, &used_id); - id_neg_offset++; - } else { - effective_id = i - id_neg_offset; - if (g_list_find_custom(register_numbers, &effective_id, - (GCompareFunc)int_cmp) != NULL) { - id_neg_offset--; - } - current_register->id = i - id_neg_offset; - } - /* 2. add mcd_reg_group_id and mcd_mem_space_id */ + current_register->id = i; + /* add mcd_reg_group_id and mcd_mem_space_id */ if (strcmp(current_register->group, "cp_regs") == 0) { /* coprocessor registers */ current_register->mcd_reg_group_id = 2; current_register->mcd_mem_space_id = 6; - /* TODO: get info for opcode */ + /* + * get info for opcode + * for 32bit the opcode is only 16 bit long + * for 64bit it is 32 bit long + */ + current_register->opcode |= + arm_mcd_get_opcode(cpu, current_register->internal_id); } else { /* gpr register */ current_register->mcd_reg_group_id = 1; current_register->mcd_mem_space_id = 5; } } - g_list_free(register_numbers); return 0; } @@ -1498,7 +1511,7 @@ void handle_open_core(GArray *params, void *user_ctx) } /* 4. add additional data the the regs from the xmls */ return_value = mcd_arm_get_additional_register_info(reggroups, - registers); + registers, cpu); if (return_value != 0) { g_assert_not_reached(); } @@ -1797,13 +1810,15 @@ void handle_query_regs_f(GArray *params, void *user_ctx) /* 3. send data */ mcd_reg_st my_register = g_array_index(registers, mcd_reg_st, 0); g_string_append_printf(mcdserver_state.str_buf, - "%s=%d.%s=%s.%s=%d.%s=%d.%s=%d.%s=%d.%s=%d.", - TCP_ARGUMENT_ID, my_register.id, TCP_ARGUMENT_NAME, - my_register.name, TCP_ARGUMENT_SIZE, my_register.bitsize, + "%s=%u.%s=%s.%s=%u.%s=%u.%s=%u.%s=%u.%s=%u.%s=%u.", + TCP_ARGUMENT_ID, my_register.id, + TCP_ARGUMENT_NAME, my_register.name, + TCP_ARGUMENT_SIZE, my_register.bitsize, TCP_ARGUMENT_REGGROUPID, my_register.mcd_reg_group_id, TCP_ARGUMENT_MEMSPACEID, my_register.mcd_mem_space_id, TCP_ARGUMENT_TYPE, my_register.mcd_reg_type, - TCP_ARGUMENT_THREAD, my_register.mcd_hw_thread_id); + TCP_ARGUMENT_THREAD, my_register.mcd_hw_thread_id, + TCP_ARGUMENT_OPCODE, my_register.opcode); mcd_put_strbuf(); } @@ -1829,13 +1844,15 @@ void handle_query_regs_c(GArray *params, void *user_ctx) /* 3. send the correct register */ mcd_reg_st my_register = g_array_index(registers, mcd_reg_st, query_index); g_string_append_printf(mcdserver_state.str_buf, - "%s=%d.%s=%s.%s=%d.%s=%d.%s=%d.%s=%d.%s=%d.", - TCP_ARGUMENT_ID, my_register.id, TCP_ARGUMENT_NAME, - my_register.name, TCP_ARGUMENT_SIZE, my_register.bitsize, + "%s=%u.%s=%s.%s=%u.%s=%u.%s=%u.%s=%u.%s=%u.%s=%u.", + TCP_ARGUMENT_ID, my_register.id, + TCP_ARGUMENT_NAME, my_register.name, + TCP_ARGUMENT_SIZE, my_register.bitsize, TCP_ARGUMENT_REGGROUPID, my_register.mcd_reg_group_id, TCP_ARGUMENT_MEMSPACEID, my_register.mcd_mem_space_id, TCP_ARGUMENT_TYPE, my_register.mcd_reg_type, - TCP_ARGUMENT_THREAD, my_register.mcd_hw_thread_id); + TCP_ARGUMENT_THREAD, my_register.mcd_hw_thread_id, + TCP_ARGUMENT_OPCODE, my_register.opcode); mcd_put_strbuf(); } @@ -1889,11 +1906,18 @@ void handle_query_state(GArray *params, void *user_ctx) int mcd_read_register(CPUState *cpu, GByteArray *buf, int reg) { + /* 1. get reg type and internal id */ + GArray *registers = + g_list_nth_data(mcdserver_state.all_registers, cpu->cpu_index); + mcd_reg_st desired_register = g_array_index(registers, mcd_reg_st, reg); + uint8_t reg_type = desired_register.reg_type; + uint32_t internal_id = desired_register.internal_id; + /* 2. read register */ CPUClass *cc = CPU_GET_CLASS(cpu); gchar *arch = cc->gdb_arch_name(cpu); if (strcmp(arch, "arm") == 0) { g_free(arch); - return arm_mcd_read_register(cpu, buf, reg); + return arm_mcd_read_register(cpu, buf, reg_type, internal_id); } else { g_free(arch); return 0; @@ -1902,11 +1926,18 @@ int mcd_read_register(CPUState *cpu, GByteArray *buf, int reg) int mcd_write_register(CPUState *cpu, GByteArray *buf, int reg) { + /* 1. get reg type and internal id */ + GArray *registers = + g_list_nth_data(mcdserver_state.all_registers, cpu->cpu_index); + mcd_reg_st desired_register = g_array_index(registers, mcd_reg_st, reg); + uint8_t reg_type = desired_register.reg_type; + uint32_t internal_id = desired_register.internal_id; + /* 2. write register */ CPUClass *cc = CPU_GET_CLASS(cpu); gchar *arch = cc->gdb_arch_name(cpu); if (strcmp(arch, "arm") == 0) { g_free(arch); - return arm_mcd_write_register(cpu, buf, reg); + return arm_mcd_write_register(cpu, buf, reg_type, internal_id); } else { g_free(arch); return 0; diff --git a/mcdstub/mcdstub.h b/mcdstub/mcdstub.h index 7a63a01a39..25475acaf7 100644 --- a/mcdstub/mcdstub.h +++ b/mcdstub/mcdstub.h @@ -203,19 +203,16 @@ typedef struct mcd_reg_st { char group[64]; char type[64]; uint32_t bitsize; - uint32_t id; + uint32_t id; /* id used by the mcd interface */ + uint32_t internal_id; /* id inside reg type */ + uint8_t reg_type; /* mcd metadata */ uint32_t mcd_reg_group_id; uint32_t mcd_mem_space_id; uint32_t mcd_reg_type; uint32_t mcd_hw_thread_id; /* data for op-code */ - uint8_t cp; - uint8_t crn; - uint8_t crm; - uint8_t opc0; /* <- might not be needed! */ - uint8_t opc1; - uint8_t opc2; + uint32_t opcode; } mcd_reg_st; typedef struct mcd_reset_st { @@ -307,7 +304,8 @@ void handle_query_mem_spaces_c(GArray *params, void *user_ctx); void handle_query_regs_f(GArray *params, void *user_ctx); void handle_query_regs_c(GArray *params, void *user_ctx); void handle_open_server(GArray *params, void *user_ctx); -void parse_reg_xml(const char *xml, int size, GArray* registers); +void parse_reg_xml(const char *xml, int size, GArray* registers, + uint8_t reg_type); void handle_reset(GArray *params, void *user_ctx); void handle_query_state(GArray *params, void *user_ctx); void handle_read_register(GArray *params, void *user_ctx); @@ -329,8 +327,8 @@ int mcd_arm_parse_core_xml_file(CPUClass *cc, GArray *reggroups, GArray *registers, int *current_group_id); int mcd_arm_parse_general_xml_files(CPUState *cpu, GArray* reggroups, GArray *registers, int *current_group_id); -int mcd_arm_get_additional_register_info(GArray *reggroups, GArray *registers); - +int mcd_arm_get_additional_register_info(GArray *reggroups, GArray *registers, + CPUState *cpu); /* sycall handling */ void mcd_syscall_reset(void); void mcd_disable_syscalls(void); diff --git a/target/arm/mcdstub.c b/target/arm/mcdstub.c index e4e632d3f3..c0bd5bb545 100644 --- a/target/arm/mcdstub.c +++ b/target/arm/mcdstub.c @@ -17,6 +17,31 @@ static inline int mcd_get_reg32(GByteArray *buf, uint32_t val) return 4; } +static inline int mcd_get_reg64(GByteArray *buf, uint64_t val) +{ + uint64_t to_quad = tswap64(val); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); + return 8; +} + +static inline int mcd_get_reg128(GByteArray *buf, uint64_t val_hi, + uint64_t val_lo) +{ + uint64_t to_quad; +#if TARGET_BIG_ENDIAN + to_quad = tswap64(val_hi); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); + to_quad = tswap64(val_lo); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); +#else + to_quad = tswap64(val_lo); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); + to_quad = tswap64(val_hi); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); +#endif + return 16; +} + static inline int mcd_get_zeroes(GByteArray *array, size_t len) { /*TODO: move this to a separate file */ @@ -45,24 +70,13 @@ const char *arm_mcd_get_dynamic_xml(CPUState *cs, const char *xmlname) return NULL; } -int arm_mcd_read_register(CPUState *cs, GByteArray *mem_buf, int n) +static int arm_mcd_read_gpr_register(CPUARMState *env, GByteArray *mem_buf, + uint32_t n) { - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - if (n < 16) { /* Core integer register. */ return mcd_get_reg32(mem_buf, env->regs[n]); - } - if (n < 24) { - /* TODO: these numbers don't match mine */ - return mcd_get_zeroes(mem_buf, 12); - } - switch (n) { - case 24: - /* TODO: these numbers don't match mine */ - return mcd_get_reg32(mem_buf, 0); - case 25: + } else if (n == 16) { /* CPSR, or XPSR for M-profile */ if (arm_feature(env, ARM_FEATURE_M)) { return mcd_get_reg32(mem_buf, xpsr_read(env)); @@ -70,21 +84,17 @@ int arm_mcd_read_register(CPUState *cs, GByteArray *mem_buf, int n) return mcd_get_reg32(mem_buf, cpsr_read(env)); } } - /* TODO: add funcitons for the remaining regs (including cp_regs) */ return 0; } -int arm_mcd_write_register(CPUState *cs, GByteArray *mem_buf, int n) +static int arm_mcd_write_gpr_register(CPUARMState *env, uint8_t *mem_buf, + uint32_t n) { - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; uint32_t tmp; tmp = ldl_p(mem_buf); - tmp = *((uint32_t *)mem_buf->data); - /* - * Mask out low bits of PC to workaround gdb bugs. + * Mask out low bits of PC * This avoids an assert in thumb_tr_translate_insn, because it is * architecturally impossible to misalign the pc. * This will probably cause problems if we ever implement the @@ -102,16 +112,7 @@ int arm_mcd_write_register(CPUState *cs, GByteArray *mem_buf, int n) } env->regs[n] = tmp; return 4; - } - if (n < 24) { /* 16-23 */ - /* FPA registers (ignored). */ - return 4; - } - switch (n) { - case 24: - /* FPA status register (ignored). */ - return 4; - case 25: + } else if (n == 16) { /* CPSR, or XPSR for M-profile */ if (arm_feature(env, ARM_FEATURE_M)) { /* @@ -126,6 +127,206 @@ int arm_mcd_write_register(CPUState *cs, GByteArray *mem_buf, int n) } return 4; } - /* TODO: add funcitons for the remaining regs (including cp_regs) */ + return 0; +} + +static int arm_mcd_read_vfp_register(CPUARMState *env, GByteArray *buf, + uint32_t reg) +{ + ARMCPU *cpu = env_archcpu(env); + int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16; + + /* VFP data registers are always little-endian. */ + if (reg < nregs) { + return mcd_get_reg64(buf, *aa32_vfp_dreg(env, reg)); + } + if (arm_feature(env, ARM_FEATURE_NEON)) { + /* Aliases for Q regs. */ + nregs += 16; + if (reg < nregs) { + uint64_t *q = aa32_vfp_qreg(env, reg - 32); + return mcd_get_reg128(buf, q[0], q[1]); + } + } + switch (reg - nregs) { + case 0: + return mcd_get_reg32(buf, vfp_get_fpscr(env)); + } + return 0; +} + +static int arm_mcd_write_vfp_register(CPUARMState *env, uint8_t *buf, + uint32_t reg) +{ + ARMCPU *cpu = env_archcpu(env); + int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16; + + if (reg < nregs) { + *aa32_vfp_dreg(env, reg) = ldq_le_p(buf); + return 8; + } + if (arm_feature(env, ARM_FEATURE_NEON)) { + nregs += 16; + if (reg < nregs) { + uint64_t *q = aa32_vfp_qreg(env, reg - 32); + q[0] = ldq_le_p(buf); + q[1] = ldq_le_p(buf + 8); + return 16; + } + } + switch (reg - nregs) { + case 0: + vfp_set_fpscr(env, ldl_p(buf)); + return 4; + } + return 0; +} + +static int arm_mcd_read_vfp_sys_register(CPUARMState *env, GByteArray *buf, + uint32_t reg) +{ + switch (reg) { + case 0: + return mcd_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]); + case 1: + return mcd_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]); + } + return 0; +} + +static int arm_mcd_write_vfp_sys_register(CPUARMState *env, uint8_t *buf, + uint32_t reg) +{ + switch (reg) { + case 0: + env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); + return 4; + case 1: + env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); + return 4; + } + return 0; +} + +static int arm_mcd_read_mve_register(CPUARMState *env, GByteArray *buf, + uint32_t reg) +{ + switch (reg) { + case 0: + return mcd_get_reg32(buf, env->v7m.vpr); + default: + return 0; + } +} + +static int arm_mcd_write_mve_register(CPUARMState *env, uint8_t *buf, + uint32_t reg) +{ + switch (reg) { + case 0: + env->v7m.vpr = ldl_p(buf); + return 4; + default: + return 0; + } +} + +static int arm_mcd_read_cpr_register(CPUARMState *env, GByteArray *buf, + uint32_t reg) +{ + ARMCPU *cpu = env_archcpu(env); + const ARMCPRegInfo *ri; + uint32_t key; + + key = cpu->dyn_sysreg_xml.data.cpregs.keys[reg]; + ri = get_arm_cp_reginfo(cpu->cp_regs, key); + if (ri) { + if (cpreg_field_is_64bit(ri)) { + return mcd_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri)); + } else { + return mcd_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri)); + } + } + return 0; +} + +static int arm_mcd_write_cpr_register(CPUARMState *env, uint8_t *buf, + uint32_t reg) +{ + /* try write_raw_cp_reg here*/ + return 0; +} + +int arm_mcd_read_register(CPUState *cs, GByteArray *mem_buf, uint8_t reg_type, + uint32_t n) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + switch (reg_type) { + case MCD_ARM_REG_TYPE_GPR: + return arm_mcd_read_gpr_register(env, mem_buf, n); + break; + case MCD_ARM_REG_TYPE_VFP: + return arm_mcd_read_vfp_register(env, mem_buf, n); + break; + case MCD_ARM_REG_TYPE_VFP_SYS: + return arm_mcd_read_vfp_sys_register(env, mem_buf, n); + break; + case MCD_ARM_REG_TYPE_MVE: + return arm_mcd_read_mve_register(env, mem_buf, n); + break; + case MCD_ARM_REG_TYPE_CPR: + return arm_mcd_read_cpr_register(env, mem_buf, n); + break; + default: + /* unknown register type*/ + return 0; + } +} + +int arm_mcd_write_register(CPUState *cs, GByteArray *mem_buf, uint8_t reg_type, + uint32_t n) +{ + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + switch (reg_type) { + case MCD_ARM_REG_TYPE_GPR: + return arm_mcd_write_gpr_register(env, mem_buf->data, n); + break; + case MCD_ARM_REG_TYPE_VFP: + return arm_mcd_write_vfp_register(env, mem_buf->data, n); + break; + case MCD_ARM_REG_TYPE_VFP_SYS: + return arm_mcd_write_vfp_sys_register(env, mem_buf->data, n); + break; + case MCD_ARM_REG_TYPE_MVE: + return arm_mcd_write_mve_register(env, mem_buf->data, n); + break; + case MCD_ARM_REG_TYPE_CPR: + return arm_mcd_write_cpr_register(env, mem_buf->data, n); + break; + default: + /* unknown register type*/ + return 0; + } +} + +uint16_t arm_mcd_get_opcode(CPUState *cs, uint32_t n) +{ + /*gets the opcode for a cp register*/ + ARMCPU *cpu = ARM_CPU(cs); + const ARMCPRegInfo *ri; + uint32_t key; + + key = cpu->dyn_sysreg_xml.data.cpregs.keys[n]; + ri = get_arm_cp_reginfo(cpu->cp_regs, key); + if (ri) { + uint16_t opcode = 0; + opcode |= ri->opc1 << 14; + opcode |= ri->opc2 << 10; + opcode |= ri->crm << 7; + opcode |= ri->crn << 3; + return opcode; + } return 0; } diff --git a/target/arm/mcdstub.h b/target/arm/mcdstub.h index 28c7f2baec..81d67246d8 100644 --- a/target/arm/mcdstub.h +++ b/target/arm/mcdstub.h @@ -1,8 +1,20 @@ #ifndef ARM_MCDSTUB_H #define ARM_MCDSTUB_H +/* ids for each different type of register */ +enum { + MCD_ARM_REG_TYPE_GPR, + MCD_ARM_REG_TYPE_VFP, + MCD_ARM_REG_TYPE_VFP_SYS, + MCD_ARM_REG_TYPE_MVE, + MCD_ARM_REG_TYPE_CPR, +}; + const char *arm_mcd_get_dynamic_xml(CPUState *cs, const char *xmlname); -int arm_mcd_read_register(CPUState *cs, GByteArray *mem_buf, int n); -int arm_mcd_write_register(CPUState *cs, GByteArray *mem_buf, int n); +int arm_mcd_read_register(CPUState *cs, GByteArray *mem_buf, uint8_t reg_type, + uint32_t n); +int arm_mcd_write_register(CPUState *cs, GByteArray *mem_buf, uint8_t reg_type, + uint32_t n); +uint16_t arm_mcd_get_opcode(CPUState *cs, uint32_t n); #endif /* ARM_MCDSTUB_H */ -- 2.34.1