aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2020-04-10 13:32:12 -0700
committerGitHub <noreply@github.com>2020-04-10 13:32:12 -0700
commit464407cfd21b62f1b5aaf975b0e3bdb22afd417f (patch)
treefa597f748c9bac667668db6d254ecae1a2c11854
parentcbb15587dc782ac8ade7ae252e7b760cfba4a178 (diff)
downloadriscv-openocd-464407cfd21b62f1b5aaf975b0e3bdb22afd417f.zip
riscv-openocd-464407cfd21b62f1b5aaf975b0e3bdb22afd417f.tar.gz
riscv-openocd-464407cfd21b62f1b5aaf975b0e3bdb22afd417f.tar.bz2
Expose FPRs as single and double for F and D. (#465)
If a hart support both F and D, then expose the FPRs as a union of float and double. Fixes #336. Change-Id: I3d4503bbf9281d6380c51259388cd01d399b94d6
-rw-r--r--src/target/riscv/riscv.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 0adc299..4650a09 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -3528,6 +3528,19 @@ int riscv_init_registers(struct target *target)
/* These types are built into gdb. */
static struct reg_data_type type_ieee_single = { .type = REG_TYPE_IEEE_SINGLE, .id = "ieee_single" };
static struct reg_data_type type_ieee_double = { .type = REG_TYPE_IEEE_DOUBLE, .id = "ieee_double" };
+ static struct reg_data_type_union_field single_double_fields[] = {
+ {"float", &type_ieee_single, single_double_fields + 1},
+ {"double", &type_ieee_double, NULL},
+ };
+ static struct reg_data_type_union single_double_union = {
+ .fields = single_double_fields
+ };
+ static struct reg_data_type type_ieee_single_double = {
+ .type = REG_TYPE_ARCH_DEFINED,
+ .id = "FPU_FD",
+ .type_class = REG_TYPE_CLASS_UNION,
+ .reg_type_union = &single_double_union
+ };
static struct reg_data_type type_uint8 = { .type = REG_TYPE_UINT8, .id = "uint8" };
static struct reg_data_type type_uint16 = { .type = REG_TYPE_UINT16, .id = "uint16" };
static struct reg_data_type type_uint32 = { .type = REG_TYPE_UINT32, .id = "uint32" };
@@ -3770,8 +3783,11 @@ int riscv_init_registers(struct target *target)
} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
r->caller_save = true;
if (riscv_supports_extension(target, hartid, 'D')) {
- r->reg_data_type = &type_ieee_double;
r->size = 64;
+ if (riscv_supports_extension(target, hartid, 'F'))
+ r->reg_data_type = &type_ieee_single_double;
+ else
+ r->reg_data_type = &type_ieee_double;
} else if (riscv_supports_extension(target, hartid, 'F')) {
r->reg_data_type = &type_ieee_single;
r->size = 32;