From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7873) id A117D3856DDA; Tue, 12 Jul 2022 12:16:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A117D3856DDA Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tiezhu Yang To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb: LoongArch: Add floating-point support X-Act-Checkin: binutils-gdb X-Git-Author: Tiezhu Yang X-Git-Refname: refs/heads/master X-Git-Oldrev: 75948417af8f86d1b9b0e3b51f904e1345927885 X-Git-Newrev: 657a50227bbd835c83aadc2405e649c4b982c241 Message-Id: <20220712121614.A117D3856DDA@sourceware.org> Date: Tue, 12 Jul 2022 12:16:14 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jul 2022 12:16:14 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D657a50227bbd= 835c83aadc2405e649c4b982c241 commit 657a50227bbd835c83aadc2405e649c4b982c241 Author: Tiezhu Yang Date: Tue Jul 12 10:33:28 2022 +0800 gdb: LoongArch: Add floating-point support =20 This commit adds floating-point support for LoongArch gdb. =20 Signed-off-by: Tiezhu Yang Diff: --- gdb/arch/loongarch.c | 9 ++++++ gdb/arch/loongarch.h | 17 ++++++++++- gdb/features/Makefile | 1 + gdb/features/loongarch/fpu.c | 55 +++++++++++++++++++++++++++++++++ gdb/features/loongarch/fpu.xml | 50 ++++++++++++++++++++++++++++++ gdb/loongarch-linux-nat.c | 52 +++++++++++++++++++++++++++++++ gdb/loongarch-linux-tdep.c | 69 ++++++++++++++++++++++++++++++++++++++= +--- gdb/loongarch-tdep.c | 66 +++++++++++++++++++++++++++++++-------= -- gdb/loongarch-tdep.h | 1 + 9 files changed, 300 insertions(+), 20 deletions(-) diff --git a/gdb/arch/loongarch.c b/gdb/arch/loongarch.c index 11310c1dd93..c48c2001e96 100644 --- a/gdb/arch/loongarch.c +++ b/gdb/arch/loongarch.c @@ -24,6 +24,7 @@ =20 #include "../features/loongarch/base32.c" #include "../features/loongarch/base64.c" +#include "../features/loongarch/fpu.c" =20 #ifndef GDBSERVER #define STATIC_IN_GDB static @@ -44,6 +45,11 @@ loongarch_create_target_description (const struct loonga= rch_gdbarch_features fea else if (features.xlen =3D=3D 8) arch_name.append ("64"); =20 + if (features.fputype =3D=3D SINGLE_FLOAT) + arch_name.append ("f"); + else if (features.fputype =3D=3D DOUBLE_FLOAT) + arch_name.append ("d"); + set_tdesc_architecture (tdesc.get (), arch_name.c_str ()); =20 long regnum =3D 0; @@ -54,6 +60,9 @@ loongarch_create_target_description (const struct loongar= ch_gdbarch_features fea else if (features.xlen =3D=3D 8) regnum =3D create_feature_loongarch_base64 (tdesc.get (), regnum); =20 + /* For now we only support creating single float and double float. */ + regnum =3D create_feature_loongarch_fpu (tdesc.get (), regnum); + return tdesc; } =20 diff --git a/gdb/arch/loongarch.h b/gdb/arch/loongarch.h index 5cf5498079a..799595b3e60 100644 --- a/gdb/arch/loongarch.h +++ b/gdb/arch/loongarch.h @@ -23,7 +23,7 @@ #include "gdbsupport/tdesc.h" =20 /* Register numbers of various important registers. */ -enum +enum loongarch_regnum { LOONGARCH_RA_REGNUM =3D 1, /* Return Address. */ LOONGARCH_SP_REGNUM =3D 3, /* Stack Pointer. */ @@ -36,6 +36,16 @@ enum LOONGARCH_LINUX_NUM_GREGSET =3D 45, /* 32 GPR, ORIG_A0, PC, BADV, RESERV= ED 10. */ LOONGARCH_ARG_REGNUM =3D 8, /* r4-r11: general-purpose argume= nt registers. f0-f7: floating-point argument registers. */ + LOONGARCH_FIRST_FP_REGNUM =3D LOONGARCH_LINUX_NUM_GREGSET, + LOONGARCH_FCC_REGNUM =3D LOONGARCH_FIRST_FP_REGNUM + 32, + LOONGARCH_FCSR_REGNUM =3D LOONGARCH_FCC_REGNUM + 1, + LOONGARCH_LINUX_NUM_FPREGSET =3D 34, +}; + +enum loongarch_fputype +{ + SINGLE_FLOAT =3D 1, + DOUBLE_FLOAT =3D 2, }; =20 /* The set of LoongArch architectural features that we track that impact h= ow @@ -56,6 +66,11 @@ struct loongarch_gdbarch_features 0 value so we can spot if one of these is used uninitialised. */ int xlen =3D 0; =20 + /* The type of floating-point. This is either 1 (single float) or 2 + (double float). No other value is valid. Initialise to the invalid + 0 value so we can spot if one of these is used uninitialised. */ + int fputype =3D 0; + /* Equality operator. */ bool operator=3D=3D (const struct loongarch_gdbarch_features &rhs) const { diff --git a/gdb/features/Makefile b/gdb/features/Makefile index 15d623c2681..061cb2ed032 100644 --- a/gdb/features/Makefile +++ b/gdb/features/Makefile @@ -231,6 +231,7 @@ FEATURE_XMLFILES =3D aarch64-core.xml \ i386/x32-core.xml \ loongarch/base32.xml \ loongarch/base64.xml \ + loongarch/fpu.xml \ riscv/rv32e-xregs.xml \ riscv/32bit-cpu.xml \ riscv/32bit-fpu.xml \ diff --git a/gdb/features/loongarch/fpu.c b/gdb/features/loongarch/fpu.c new file mode 100644 index 00000000000..ea3e1dd9980 --- /dev/null +++ b/gdb/features/loongarch/fpu.c @@ -0,0 +1,55 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: fpu.xml */ + +#include "gdbsupport/tdesc.h" + +static int +create_feature_loongarch_fpu (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature =3D tdesc_create_feature (result, "org.gnu.gdb.loongarch.fpu"); + tdesc_type_with_fields *type_with_fields; + type_with_fields =3D tdesc_create_union (feature, "fputype"); + tdesc_type *field_type; + field_type =3D tdesc_named_type (feature, "ieee_single"); + tdesc_add_field (type_with_fields, "f", field_type); + field_type =3D tdesc_named_type (feature, "ieee_double"); + tdesc_add_field (type_with_fields, "d", field_type); + + tdesc_create_reg (feature, "f0", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f1", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f2", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f3", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f4", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f5", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f6", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f7", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f8", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f9", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f10", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f11", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f12", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f13", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f14", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f15", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f16", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f17", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f18", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f19", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f20", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f21", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f22", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f23", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f24", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f25", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f26", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f27", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f28", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f29", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f30", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "f31", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "fcc", regnum++, 1, "float", 64, "fputype"); + tdesc_create_reg (feature, "fcsr", regnum++, 1, "float", 32, "uint32"); + return regnum; +} diff --git a/gdb/features/loongarch/fpu.xml b/gdb/features/loongarch/fpu.xml new file mode 100644 index 00000000000..a61057ec442 --- /dev/null +++ b/gdb/features/loongarch/fpu.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/loongarch-linux-nat.c b/gdb/loongarch-linux-nat.c index 1b4a37c94fb..3baa891519a 100644 --- a/gdb/loongarch-linux-nat.c +++ b/gdb/loongarch-linux-nat.c @@ -100,6 +100,52 @@ store_gregs_to_thread (struct regcache *regcache, int = regnum, pid_t tid) } } =20 +/* Fill GDB's register array with the fp, fcc and fcsr + register values from the current thread. */ + +static void +fetch_fpregs_from_thread (struct regcache *regcache, int regnum, pid_t tid) +{ + elf_fpregset_t regset; + + if ((regnum =3D=3D -1) + || (regnum >=3D LOONGARCH_FIRST_FP_REGNUM && regnum <=3D LOONGARCH_F= CSR_REGNUM)) + { + struct iovec iovec =3D { .iov_base =3D ®set, .iov_len =3D sizeof = (regset) }; + + if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0) + perror_with_name (_("Couldn't get NT_FPREGSET registers")); + else + loongarch_fpregset.supply_regset (nullptr, regcache, regnum, + ®set, sizeof (regset)); + } +} + +/* Store to the current thread the valid fp, fcc and fcsr + register values in the GDB's register array. */ + +static void +store_fpregs_to_thread (struct regcache *regcache, int regnum, pid_t tid) +{ + elf_fpregset_t regset; + + if ((regnum =3D=3D -1) + || (regnum >=3D LOONGARCH_FIRST_FP_REGNUM && regnum <=3D LOONGARCH_F= CSR_REGNUM)) + { + struct iovec iovec =3D { .iov_base =3D ®set, .iov_len =3D sizeof = (regset) }; + + if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0) + perror_with_name (_("Couldn't get NT_FPREGSET registers")); + else + { + loongarch_fpregset.collect_regset (nullptr, regcache, regnum, + ®set, sizeof (regset)); + if (ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0) + perror_with_name (_("Couldn't set NT_FPREGSET registers")); + } + } +} + /* Implement the "fetch_registers" target_ops method. */ =20 void @@ -109,6 +155,7 @@ loongarch_linux_nat_target::fetch_registers (struct reg= cache *regcache, pid_t tid =3D get_ptrace_pid (regcache->ptid ()); =20 fetch_gregs_from_thread(regcache, regnum, tid); + fetch_fpregs_from_thread(regcache, regnum, tid); } =20 /* Implement the "store_registers" target_ops method. */ @@ -120,6 +167,7 @@ loongarch_linux_nat_target::store_registers (struct reg= cache *regcache, pid_t tid =3D get_ptrace_pid (regcache->ptid ()); =20 store_gregs_to_thread (regcache, regnum, tid); + store_fpregs_to_thread(regcache, regnum, tid); } =20 /* Return the address in the core dump or inferior of register REGNO. */ @@ -158,12 +206,16 @@ fill_gregset (const struct regcache *regcache, gdb_gr= egset_t *gregset, void supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregset) { + loongarch_fpregset.supply_regset (nullptr, regcache, -1, fpregset, + sizeof (gdb_fpregset_t)); } =20 void fill_fpregset (const struct regcache *regcache, gdb_fpregset_t *fpregset, int regnum) { + loongarch_fpregset.collect_regset (nullptr, regcache, regnum, fpregset, + sizeof (gdb_fpregset_t)); } =20 /* Initialize LoongArch Linux native support. */ diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c index 1076e935997..0a3ea80c173 100644 --- a/gdb/loongarch-linux-tdep.c +++ b/gdb/loongarch-linux-tdep.c @@ -106,7 +106,7 @@ loongarch_fill_gregset (const struct regset *regset, } } =20 -/* Register set definitions. */ +/* Define the general register regset. */ =20 const struct regset loongarch_gregset =3D { @@ -115,6 +115,62 @@ const struct regset loongarch_gregset =3D loongarch_fill_gregset, }; =20 +/* Unpack an elf_fpregset_t into GDB's register cache. */ +static void +loongarch_supply_fpregset (const struct regset *r, + struct regcache *regcache, int regnum, + const void *fprs, size_t len) +{ + const gdb_byte *buf =3D nullptr; + int fprsize =3D register_size (regcache->arch (), LOONGARCH_FIRST_FP_REG= NUM); + + if (regnum =3D=3D -1) + { + for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++) + { + buf =3D (const gdb_byte *)fprs + fprsize * i; + regcache->raw_supply (LOONGARCH_FIRST_FP_REGNUM + i, (const void *)buf); + } + } + else if (regnum >=3D LOONGARCH_FIRST_FP_REGNUM && regnum <=3D LOONGARCH_= FCSR_REGNUM) + { + buf =3D (const gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST= _FP_REGNUM); + regcache->raw_supply (regnum, (const void *)buf); + } +} + +/* Pack the GDB's register cache value into an elf_fpregset_t. */ +static void +loongarch_fill_fpregset (const struct regset *r, + const struct regcache *regcache, int regnum, + void *fprs, size_t len) +{ + gdb_byte *buf =3D nullptr; + int fprsize =3D register_size (regcache->arch (), LOONGARCH_FIRST_FP_REG= NUM); + + if (regnum =3D=3D -1) + { + for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++) + { + buf =3D (gdb_byte *)fprs + fprsize * i; + regcache->raw_collect (LOONGARCH_FIRST_FP_REGNUM + i, (void *)buf); + } + } + else if (regnum >=3D LOONGARCH_FIRST_FP_REGNUM && regnum <=3D LOONGARCH_= FCSR_REGNUM) + { + buf =3D (gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_RE= GNUM); + regcache->raw_collect (regnum, (void *)buf); + } +} + +/* Define the FP register regset. */ +const struct regset loongarch_fpregset =3D +{ + nullptr, + loongarch_supply_fpregset, + loongarch_fill_fpregset, +}; + /* Implement the "init" method of struct tramp_frame. */ =20 #define LOONGARCH_RT_SIGFRAME_UCONTEXT_OFFSET 128 @@ -152,7 +208,7 @@ static const struct tramp_frame loongarch_linux_rt_sigf= rame =3D { TRAMP_SENTINEL_INSN, ULONGEST_MAX } }, loongarch_linux_rt_sigframe_init, - NULL + nullptr }; =20 /* Implement the "iterate_over_regset_sections" gdbarch method. */ @@ -163,10 +219,13 @@ loongarch_iterate_over_regset_sections (struct gdbarc= h *gdbarch, void *cb_data, const struct regcache *regcache) { - int regsize =3D register_size (gdbarch, 0); + int gprsize =3D register_size (gdbarch, 0); + int fprsize =3D register_size (gdbarch, LOONGARCH_FIRST_FP_REGNUM); =20 - cb (".reg", LOONGARCH_LINUX_NUM_GREGSET * regsize, - LOONGARCH_LINUX_NUM_GREGSET * regsize, &loongarch_gregset, NULL, cb_= data); + cb (".reg", LOONGARCH_LINUX_NUM_GREGSET * gprsize, + LOONGARCH_LINUX_NUM_GREGSET * gprsize, &loongarch_gregset, nullptr, = cb_data); + cb (".reg2", LOONGARCH_LINUX_NUM_FPREGSET * fprsize, + LOONGARCH_LINUX_NUM_FPREGSET * fprsize, &loongarch_fpregset, nullptr= , cb_data); } =20 /* The following value is derived from __NR_rt_sigreturn in diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index b8f28a2b142..41422f0445d 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -462,7 +462,7 @@ pass_in_gar (struct regcache *regcache, unsigned int ga= r, const gdb_byte *val) static void pass_in_far (struct regcache *regcache, unsigned int far, const gdb_byte *= val) { - unsigned int regnum =3D LOONGARCH_ARG_REGNUM - far + LOONGARCH_BADV_REGN= UM + 1; + unsigned int regnum =3D LOONGARCH_ARG_REGNUM - far + LOONGARCH_FIRST_FP_= REGNUM; regcache->cooked_write (regnum, val); } =20 @@ -1080,6 +1080,8 @@ loongarch_dwarf2_reg_to_regnum (struct gdbarch *gdbar= ch, int regnum) { if (regnum >=3D 0 && regnum < 32) return regnum; + else if (regnum >=3D 32 && regnum < 66) + return LOONGARCH_FIRST_FP_REGNUM + regnum - 32; else return -1; } @@ -1104,6 +1106,7 @@ loongarch_features_from_bfd (const bfd *abfd) if (abfd !=3D nullptr && bfd_get_flavour (abfd) =3D=3D bfd_target_elf_fl= avour) { unsigned char eclass =3D elf_elfheader (abfd)->e_ident[EI_CLASS]; + int e_flags =3D elf_elfheader (abfd)->e_flags; =20 if (eclass =3D=3D ELFCLASS32) features.xlen =3D 4; @@ -1112,6 +1115,11 @@ loongarch_features_from_bfd (const bfd *abfd) else internal_error (__FILE__, __LINE__, _("unknown ELF header class %d"), eclass); + + if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags)) + features.fputype =3D SINGLE_FLOAT; + else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags)) + features.fputype =3D DOUBLE_FLOAT; } =20 return features; @@ -1130,11 +1138,17 @@ loongarch_find_default_target_description (const st= ruct gdbarch_info info) =20 /* If the XLEN field is still 0 then we got nothing useful from INFO.BFD, maybe there was no bfd object. In this case we fall back to a minimal - useful target with no floating point, the x-register size is selected - based on the architecture from INFO. */ + useful target, the x-register size is selected based on the architect= ure + from INFO. */ if (features.xlen =3D=3D 0) features.xlen =3D info.bfd_arch_info->bits_per_address =3D=3D 32 ? 4 := 8; =20 + /* If the FPUTYPE field is still 0 then we got nothing useful from INFO.= BFD, + maybe there was no bfd object. In this case we fall back to a usual = useful + target with double float. */ + if (features.fputype =3D=3D 0) + features.fputype =3D DOUBLE_FLOAT; + /* Now build a target description based on the feature set. */ return loongarch_lookup_target_description (features); } @@ -1144,6 +1158,10 @@ loongarch_find_default_target_description (const str= uct gdbarch_info info) static struct gdbarch * loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arc= hes) { + size_t regnum =3D 0; + struct loongarch_gdbarch_features features; + tdesc_arch_data_up tdesc_data =3D tdesc_data_alloc (); + loongarch_gdbarch_tdep *tdep =3D new loongarch_gdbarch_tdep; const struct target_desc *tdesc =3D info.target_desc; =20 /* Ensure we always have a target description. */ @@ -1155,13 +1173,6 @@ loongarch_gdbarch_init (struct gdbarch_info info, st= ruct gdbarch_list *arches) if (feature_cpu =3D=3D nullptr) return nullptr; =20 - int xlen_bitsize =3D tdesc_register_bitsize (feature_cpu, "pc"); - struct loongarch_gdbarch_features features; - features.xlen =3D (xlen_bitsize / 8); - - size_t regnum =3D 0; - tdesc_arch_data_up tdesc_data =3D tdesc_data_alloc (); - loongarch_gdbarch_tdep *tdep =3D new loongarch_gdbarch_tdep; =20 /* Validate the description provides the mandatory base registers and allocate their numbers. */ @@ -1175,6 +1186,22 @@ loongarch_gdbarch_init (struct gdbarch_info info, st= ruct gdbarch_list *arches) if (!valid_p) return nullptr; =20 + const struct tdesc_feature *feature_fpu + =3D tdesc_find_feature (tdesc, "org.gnu.gdb.loongarch.fpu"); + if (feature_fpu =3D=3D nullptr) + return nullptr; + + /* Validate the description provides the fpu registers and + allocate their numbers. */ + regnum =3D LOONGARCH_FIRST_FP_REGNUM; + for (int i =3D 0; i < 32; i++) + valid_p &=3D tdesc_numbered_register (feature_fpu, tdesc_data.get (), = regnum++, + loongarch_f_normal_name[i] + 1); + valid_p &=3D tdesc_numbered_register (feature_fpu, tdesc_data.get (), re= gnum++, "fcc"); + valid_p &=3D tdesc_numbered_register (feature_fpu, tdesc_data.get (), re= gnum++, "fcsr"); + if (!valid_p) + return nullptr; + /* LoongArch code is always little-endian. */ info.byte_order_for_code =3D BFD_ENDIAN_LITTLE; =20 @@ -1184,11 +1211,22 @@ loongarch_gdbarch_init (struct gdbarch_info info, s= truct gdbarch_list *arches) struct loongarch_gdbarch_features abi_features =3D loongarch_features_from_bfd (info.abfd); =20 - /* If the ABI_FEATURES xlen is 0 then this indicates we got no useful abi - features from the INFO object. In this case we just treat the - hardware features as defining the abi. */ + /* If the ABI_FEATURES xlen or fputype is 0 then this indicates we got + no useful abi features from the INFO object. In this case we just + treat the hardware features as defining the abi. */ if (abi_features.xlen =3D=3D 0) - abi_features =3D features; + { + int xlen_bitsize =3D tdesc_register_bitsize (feature_cpu, "pc"); + features.xlen =3D (xlen_bitsize / 8); + features.fputype =3D abi_features.fputype; + abi_features =3D features; + } + if (abi_features.fputype =3D=3D 0) + { + features.xlen =3D abi_features.xlen; + features.fputype =3D DOUBLE_FLOAT; + abi_features =3D features; + } =20 /* Find a candidate among the list of pre-declared architectures. */ for (arches =3D gdbarch_list_lookup_by_info (arches, &info); diff --git a/gdb/loongarch-tdep.h b/gdb/loongarch-tdep.h index b68a7892f2b..e35b6cf4c7a 100644 --- a/gdb/loongarch-tdep.h +++ b/gdb/loongarch-tdep.h @@ -29,6 +29,7 @@ =20 /* Register set definitions. */ extern const struct regset loongarch_gregset; +extern const struct regset loongarch_fpregset; =20 /* Target-dependent structure in gdbarch. */ struct loongarch_gdbarch_tdep : gdbarch_tdep