diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-10-11 17:55:29 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-10-11 17:55:29 +0000 |
commit | 56aebc891674cd2d07b3f64183415697be200084 (patch) | |
tree | c3cfc08f9593b32d16bb3469be3a7d479f8f99d9 /target-arm | |
parent | 1792f2867c645ac8d587e30b30bdc6e0bb28a0d0 (diff) | |
download | hqemu-56aebc891674cd2d07b3f64183415697be200084.zip hqemu-56aebc891674cd2d07b3f64183415697be200084.tar.gz |
Add GDB XML register description support.
Signed-off-by: Paul Brook <paul@codesourcery.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5459 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-arm')
-rw-r--r-- | target-arm/helper.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index 021f077..b9a8f78 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -173,6 +173,58 @@ void cpu_reset(CPUARMState *env) tlb_flush(env, 1); } +static int vfp_gdb_get_reg(CPUState *env, uint8_t *buf, int reg) +{ + int nregs; + + /* VFP data registers are always little-endian. */ + nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16; + if (reg < nregs) { + stfq_le_p(buf, env->vfp.regs[reg]); + return 8; + } + if (arm_feature(env, ARM_FEATURE_NEON)) { + /* Aliases for Q regs. */ + nregs += 16; + if (reg < nregs) { + stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]); + stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]); + return 16; + } + } + switch (reg - nregs) { + case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4; + case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4; + case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4; + } + return 0; +} + +static int vfp_gdb_set_reg(CPUState *env, uint8_t *buf, int reg) +{ + int nregs; + + nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16; + if (reg < nregs) { + env->vfp.regs[reg] = ldfq_le_p(buf); + return 8; + } + if (arm_feature(env, ARM_FEATURE_NEON)) { + nregs += 16; + if (reg < nregs) { + env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf); + env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8); + return 16; + } + } + switch (reg - nregs) { + case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4; + case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4; + case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf); return 4; + } + return 0; +} + CPUARMState *cpu_arm_init(const char *cpu_model) { CPUARMState *env; @@ -194,6 +246,16 @@ CPUARMState *cpu_arm_init(const char *cpu_model) env->cpu_model_str = cpu_model; env->cp15.c0_cpuid = id; cpu_reset(env); + if (arm_feature(env, ARM_FEATURE_NEON)) { + gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, + 51, "arm-neon.xml", 0); + } else if (arm_feature(env, ARM_FEATURE_VFP3)) { + gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, + 35, "arm-vfp3.xml", 0); + } else if (arm_feature(env, ARM_FEATURE_VFP)) { + gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, + 19, "arm-vfp.xml", 0); + } return env; } |