From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7873) id EE3C5385AC1F; Tue, 9 Aug 2022 14:23:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EE3C5385AC1F 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/gdbserver: LoongArch: Improve implementation of fcc registers X-Act-Checkin: binutils-gdb X-Git-Author: Feiyang Chen X-Git-Refname: refs/heads/master X-Git-Oldrev: a88c79b77036e4778e70d62081c3cfd1044bb8e3 X-Git-Newrev: ea3352172ec868b821fa34b31ba8128bde735405 Message-Id: <20220809142304.EE3C5385AC1F@sourceware.org> Date: Tue, 9 Aug 2022 14:23:04 +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, 09 Aug 2022 14:23:05 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dea3352172ec8= 68b821fa34b31ba8128bde735405 commit ea3352172ec868b821fa34b31ba8128bde735405 Author: Feiyang Chen Date: Tue Aug 2 17:16:56 2022 +0800 gdb/gdbserver: LoongArch: Improve implementation of fcc registers =20 The current implementation of the fcc register is referenced to the user_fp_state structure of the kernel uapi [1]. =20 struct user_fp_state { uint64_t fpr[32]; uint64_t fcc; uint32_t fcsr; }; =20 But it is mistakenly defined as a 64-bit fputype register, resulting in a confusing output of "info register". =20 (gdb) info register ... fcc {f =3D 0x0, d =3D 0x0} {f =3D 0, d =3D 0} ... =20 According to "Condition Flag Register" in "LoongArch Reference Manual" [2], there are 8 condition flag registers of size 1. Use 8 registers of uint8 to make it easier for users to view the fcc register groups. =20 (gdb) info register ... fcc0 0x1 1 fcc1 0x0 0 fcc2 0x0 0 fcc3 0x0 0 fcc4 0x0 0 fcc5 0x0 0 fcc6 0x0 0 fcc7 0x0 0 ... =20 [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/= tree/arch/loongarch/include/uapi/asm/ptrace.h [2] https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-E= N.html#_condition_flag_register =20 Signed-off-by: Feiyang Chen Signed-off-by: Tiezhu Yang Diff: --- gdb/arch/loongarch.h | 7 ++--- gdb/features/loongarch/fpu.c | 9 ++++++- gdb/features/loongarch/fpu.xml | 9 ++++++- gdb/loongarch-linux-tdep.c | 55 ++++++++++++++++++++++++++++++++++++= +--- gdb/loongarch-tdep.c | 6 +++-- gdbserver/linux-loongarch-low.cc | 24 ++++++++++++++++++ 6 files changed, 99 insertions(+), 11 deletions(-) diff --git a/gdb/arch/loongarch.h b/gdb/arch/loongarch.h index 799595b3e60..eae061f7f47 100644 --- a/gdb/arch/loongarch.h +++ b/gdb/arch/loongarch.h @@ -37,9 +37,10 @@ enum loongarch_regnum 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, + LOONGARCH_LINUX_NUM_FPREGSET =3D 32, + LOONGARCH_FIRST_FCC_REGNUM =3D LOONGARCH_FIRST_FP_REGNUM + LOONGARCH_LIN= UX_NUM_FPREGSET, + LOONGARCH_LINUX_NUM_FCC =3D 8, + LOONGARCH_FCSR_REGNUM =3D LOONGARCH_FIRST_FCC_REGNUM + LOONGARCH_LINUX_N= UM_FCC, }; =20 enum loongarch_fputype diff --git a/gdb/features/loongarch/fpu.c b/gdb/features/loongarch/fpu.c index ea3e1dd9980..183ed54989f 100644 --- a/gdb/features/loongarch/fpu.c +++ b/gdb/features/loongarch/fpu.c @@ -49,7 +49,14 @@ create_feature_loongarch_fpu (struct target_desc *result= , long regnum) 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, "fcc0", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc1", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc2", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc3", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc4", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc5", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc6", regnum++, 1, "float", 8, "uint8"); + tdesc_create_reg (feature, "fcc7", regnum++, 1, "float", 8, "uint8"); 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 index a61057ec442..e81e3382e7d 100644 --- a/gdb/features/loongarch/fpu.xml +++ b/gdb/features/loongarch/fpu.xml @@ -45,6 +45,13 @@ - + + + + + + + + diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c index 3a81ff31972..883245bec7e 100644 --- a/gdb/loongarch-linux-tdep.c +++ b/gdb/loongarch-linux-tdep.c @@ -123,6 +123,7 @@ loongarch_supply_fpregset (const struct regset *r, { const gdb_byte *buf =3D nullptr; int fprsize =3D register_size (regcache->arch (), LOONGARCH_FIRST_FP_REG= NUM); + int fccsize =3D register_size (regcache->arch (), LOONGARCH_FIRST_FCC_RE= GNUM); =20 if (regnum =3D=3D -1) { @@ -131,12 +132,33 @@ loongarch_supply_fpregset (const struct regset *r, buf =3D (const gdb_byte *)fprs + fprsize * i; regcache->raw_supply (LOONGARCH_FIRST_FP_REGNUM + i, (const void *)buf); } + for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + { + buf =3D (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET= + + fccsize * i; + regcache->raw_supply (LOONGARCH_FIRST_FCC_REGNUM + i, (const void *)buf= ); + } + buf =3D (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREG= SET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_supply (LOONGARCH_FCSR_REGNUM, (const void *)buf); } - else if (regnum >=3D LOONGARCH_FIRST_FP_REGNUM && regnum <=3D LOONGARCH_= FCSR_REGNUM) + else if (regnum >=3D LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIR= ST_FCC_REGNUM) { buf =3D (const gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST= _FP_REGNUM); regcache->raw_supply (regnum, (const void *)buf); } + else if (regnum >=3D LOONGARCH_FIRST_FCC_REGNUM && regnum < LOONGARCH_FC= SR_REGNUM) + { + buf =3D (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREG= SET + + fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM); + regcache->raw_supply (regnum, (const void *)buf); + } + else if (regnum =3D=3D LOONGARCH_FCSR_REGNUM) + { + buf =3D (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREG= SET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_supply (regnum, (const void *)buf); + } } =20 /* Pack the GDB's register cache value into an elf_fpregset_t. */ @@ -147,6 +169,7 @@ loongarch_fill_fpregset (const struct regset *r, { gdb_byte *buf =3D nullptr; int fprsize =3D register_size (regcache->arch (), LOONGARCH_FIRST_FP_REG= NUM); + int fccsize =3D register_size (regcache->arch (), LOONGARCH_FIRST_FCC_RE= GNUM); =20 if (regnum =3D=3D -1) { @@ -155,12 +178,33 @@ loongarch_fill_fpregset (const struct regset *r, buf =3D (gdb_byte *)fprs + fprsize * i; regcache->raw_collect (LOONGARCH_FIRST_FP_REGNUM + i, (void *)buf); } + for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + { + buf =3D (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * i; + regcache->raw_collect (LOONGARCH_FIRST_FCC_REGNUM + i, (void *)buf); + } + buf =3D (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_collect (LOONGARCH_FCSR_REGNUM, (void *)buf); } - else if (regnum >=3D LOONGARCH_FIRST_FP_REGNUM && regnum <=3D LOONGARCH_= FCSR_REGNUM) + else if (regnum >=3D LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIR= ST_FCC_REGNUM) { buf =3D (gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_RE= GNUM); regcache->raw_collect (regnum, (void *)buf); } + else if (regnum >=3D LOONGARCH_FIRST_FCC_REGNUM && regnum < LOONGARCH_FC= SR_REGNUM) + { + buf =3D (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM); + regcache->raw_collect (regnum, (void *)buf); + } + else if (regnum =3D=3D LOONGARCH_FCSR_REGNUM) + { + buf =3D (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + regcache->raw_collect (regnum, (void *)buf); + } } =20 /* Define the FP register regset. */ @@ -221,11 +265,14 @@ loongarch_iterate_over_regset_sections (struct gdbarc= h *gdbarch, { int gprsize =3D register_size (gdbarch, 0); int fprsize =3D register_size (gdbarch, LOONGARCH_FIRST_FP_REGNUM); + int fccsize =3D register_size (gdbarch, LOONGARCH_FIRST_FCC_REGNUM); + int fcsrsize =3D register_size (gdbarch, LOONGARCH_FCSR_REGNUM); + int fpsize =3D fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC + fcsrsize; =20 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); + cb (".reg2", fpsize, fpsize, &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 85a1dd70ebd..e63ff01854d 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -1428,10 +1428,12 @@ loongarch_gdbarch_init (struct gdbarch_info info, s= truct gdbarch_list *arches) /* 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++) + for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FPREGSET; 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"); + for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + valid_p &=3D tdesc_numbered_register (feature_fpu, tdesc_data.get (), = regnum++, + loongarch_c_normal_name[i] + 1); valid_p &=3D tdesc_numbered_register (feature_fpu, tdesc_data.get (), re= gnum++, "fcsr"); if (!valid_p) return nullptr; diff --git a/gdbserver/linux-loongarch-low.cc b/gdbserver/linux-loongarch-l= ow.cc index 7180f315b11..cccf1ba780b 100644 --- a/gdbserver/linux-loongarch-low.cc +++ b/gdbserver/linux-loongarch-low.cc @@ -127,12 +127,24 @@ loongarch_fill_fpregset (struct regcache *regcache, v= oid *buf) { gdb_byte *regbuf =3D nullptr; int fprsize =3D register_size (regcache->tdesc, LOONGARCH_FIRST_FP_REGNU= M); + int fccsize =3D register_size (regcache->tdesc, LOONGARCH_FIRST_FCC_REGN= UM); =20 for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++) { regbuf =3D (gdb_byte *)buf + fprsize * i; collect_register (regcache, LOONGARCH_FIRST_FP_REGNUM + i, regbuf); } + + for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + { + regbuf =3D (gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * i; + collect_register (regcache, LOONGARCH_FIRST_FCC_REGNUM + i, regbuf); + } + + regbuf =3D (gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FPREGSET + + fccsize * LOONGARCH_LINUX_NUM_FCC; + collect_register (regcache, LOONGARCH_FCSR_REGNUM, regbuf); } =20 /* Supply FPRs from BUF into REGCACHE. */ @@ -142,12 +154,24 @@ loongarch_store_fpregset (struct regcache *regcache, = const void *buf) { const gdb_byte *regbuf =3D nullptr; int fprsize =3D register_size (regcache->tdesc, LOONGARCH_FIRST_FP_REGNU= M); + int fccsize =3D register_size (regcache->tdesc, LOONGARCH_FIRST_FCC_REGN= UM); =20 for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++) { regbuf =3D (const gdb_byte *)buf + fprsize * i; supply_register (regcache, LOONGARCH_FIRST_FP_REGNUM + i, regbuf); } + + for (int i =3D 0; i < LOONGARCH_LINUX_NUM_FCC; i++) + { + regbuf =3D (const gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FPR= EGSET + + fccsize * i; + supply_register (regcache, LOONGARCH_FIRST_FCC_REGNUM + i, regbuf); + } + + regbuf =3D (const gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FPREGSE= T + + fccsize * LOONGARCH_LINUX_NUM_FCC; + supply_register (regcache, LOONGARCH_FCSR_REGNUM, regbuf); } =20 /* LoongArch/Linux regsets. */