diff options
author | Jim Wilson <jimw@sifive.com> | 2018-10-22 14:10:13 -0700 |
---|---|---|
committer | Jim Wilson <jimw@sifive.com> | 2018-10-22 14:10:13 -0700 |
commit | 270b9329b713fdc166f95dfa3a0a2f72f3a49608 (patch) | |
tree | 880ae6d15b5b07aff96c87942acafad62cc23fd3 /gdb | |
parent | 192c2bfbd7a6d4b2069f6b94b020d274a483c198 (diff) | |
download | gdb-270b9329b713fdc166f95dfa3a0a2f72f3a49608.zip gdb-270b9329b713fdc166f95dfa3a0a2f72f3a49608.tar.gz gdb-270b9329b713fdc166f95dfa3a0a2f72f3a49608.tar.bz2 |
RISC-V: Print FP regs as union of float types.
A 64-bit FP register can hold either a single or double float value, so
print it as both types by using a union type for FP registers. Likewise
for 128-bit regs which can also hold long double.
gdb/
* riscv-tdep.c (riscv_fpreg_d_type, riscv_fpreg_q_type): New.
(riscv_register_type): Use them.
(riscv_print_one_register_info): Handle union of floats same as float.
* riscv-tdep.h (struct gdbarch_tdep): Add riscv_fpreg_d_type and
riscv_fpreg_q_type fields.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/riscv-tdep.c | 85 | ||||
-rw-r--r-- | gdb/riscv-tdep.h | 4 |
3 files changed, 94 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0e9b0a1..9055a3a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2018-10-22 Jim Wilson <jimw@sifive.com> + + * riscv-tdep.c (riscv_fpreg_d_type, riscv_fpreg_q_type): New. + (riscv_register_type): Use them. + (riscv_print_one_register_info): Handle union of floats same as float. + * riscv-tdep.h (struct gdbarch_tdep): Add riscv_fpreg_d_type and + riscv_fpreg_q_type fields. + 2018-10-21 Simon Marchi <simon.marchi@ericsson.com> * gdbarch.sh (gdbarch_num_cooked_regs): New. diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 3402241..1a75788 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -495,6 +495,76 @@ riscv_register_name (struct gdbarch *gdbarch, int regnum) return NULL; } +/* Construct a type for 64-bit FP registers. */ + +static struct type * +riscv_fpreg_d_type (struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (tdep->riscv_fpreg_d_type == nullptr) + { + const struct builtin_type *bt = builtin_type (gdbarch); + + /* The type we're building is this: */ +#if 0 + union __gdb_builtin_type_fpreg_d + { + float f; + double d; + }; +#endif + + struct type *t; + + t = arch_composite_type (gdbarch, + "__gdb_builtin_type_fpreg_d", TYPE_CODE_UNION); + append_composite_type_field (t, "float", bt->builtin_float); + append_composite_type_field (t, "double", bt->builtin_double); + TYPE_VECTOR (t) = 1; + TYPE_NAME (t) = "builtin_type_fpreg_d"; + tdep->riscv_fpreg_d_type = t; + } + + return tdep->riscv_fpreg_d_type; +} + +/* Construct a type for 128-bit FP registers. */ + +static struct type * +riscv_fpreg_q_type (struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (tdep->riscv_fpreg_q_type == nullptr) + { + const struct builtin_type *bt = builtin_type (gdbarch); + + /* The type we're building is this: */ +#if 0 + union __gdb_builtin_type_fpreg_d + { + float f; + double d; + long double ld; + }; +#endif + + struct type *t; + + t = arch_composite_type (gdbarch, + "__gdb_builtin_type_fpreg_q", TYPE_CODE_UNION); + append_composite_type_field (t, "float", bt->builtin_float); + append_composite_type_field (t, "double", bt->builtin_double); + append_composite_type_field (t, "long double", bt->builtin_long_double); + TYPE_VECTOR (t) = 1; + TYPE_NAME (t) = "builtin_type_fpreg_q"; + tdep->riscv_fpreg_q_type = t; + } + + return tdep->riscv_fpreg_q_type; +} + /* Implement the register_type gdbarch method. */ static struct type * @@ -537,9 +607,9 @@ riscv_register_type (struct gdbarch *gdbarch, int regnum) case 4: return builtin_type (gdbarch)->builtin_float; case 8: - return builtin_type (gdbarch)->builtin_double; + return riscv_fpreg_d_type (gdbarch); case 16: - return builtin_type (gdbarch)->builtin_long_double; + return riscv_fpreg_q_type (gdbarch); default: internal_error (__FILE__, __LINE__, _("unknown isa regsize %i"), regsize); @@ -591,7 +661,16 @@ riscv_print_one_register_info (struct gdbarch *gdbarch, print_raw_format = (value_entirely_available (val) && !value_optimized_out (val)); - if (TYPE_CODE (regtype) == TYPE_CODE_FLT) + if (TYPE_CODE (regtype) == TYPE_CODE_FLT + || (TYPE_CODE (regtype) == TYPE_CODE_UNION + && TYPE_NFIELDS (regtype) == 2 + && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 0)) == TYPE_CODE_FLT + && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 1)) == TYPE_CODE_FLT) + || (TYPE_CODE (regtype) == TYPE_CODE_UNION + && TYPE_NFIELDS (regtype) == 3 + && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 0)) == TYPE_CODE_FLT + && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 1)) == TYPE_CODE_FLT + && TYPE_CODE (TYPE_FIELD_TYPE (regtype, 2)) == TYPE_CODE_FLT)) { struct value_print_options opts; const gdb_byte *valaddr = value_contents_for_printing (val); diff --git a/gdb/riscv-tdep.h b/gdb/riscv-tdep.h index 8a2454e..e04e728 100644 --- a/gdb/riscv-tdep.h +++ b/gdb/riscv-tdep.h @@ -78,6 +78,10 @@ struct gdbarch_tdep features that are supported on the target. These could be cached from the target, or read from the executable when available. */ unsigned core_features; + + /* ISA-specific data types. */ + struct type *riscv_fpreg_d_type; + struct type *riscv_fpreg_q_type; }; /* Return the width in bytes of the general purpose registers for GDBARCH. */ |