* [PATCH] gdb/gdbserver: LoongArch: Improve implementation of fcc registers
@ 2022-07-22 9:08 Feiyang Chen
0 siblings, 0 replies; only message in thread
From: Feiyang Chen @ 2022-07-22 9:08 UTC (permalink / raw)
To: yangtiezhu; +Cc: Feiyang Chen, chris.chenfeiyang, gdb-patches
According to "Condition Flag Register" in "LoongArch Reference Manual" [1],
there are 8 condition flag registers of size 1. The fcc register is now a
64-bit fputype register, which is a little confusing. Use 8 registers of
uint8 to make it easier for users to view the register groups.
[1] https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_condition_flag_register
Signed-off-by: Feiyang Chen <chenfeiyang@loongson.cn>
---
gdb/arch/loongarch.h | 7 ++--
gdb/features/loongarch/fpu.c | 9 +++-
gdb/features/loongarch/fpu.xml | 9 +++-
gdb/loongarch-linux-tdep.c | 70 ++++++++++++++++++++++++++------
gdb/loongarch-tdep.c | 6 ++-
gdbserver/linux-loongarch-low.cc | 26 +++++++++++-
6 files changed, 105 insertions(+), 22 deletions(-)
diff --git a/gdb/arch/loongarch.h b/gdb/arch/loongarch.h
index 799595b3e60..6a97cb3dbd2 100644
--- a/gdb/arch/loongarch.h
+++ b/gdb/arch/loongarch.h
@@ -37,9 +37,10 @@ enum loongarch_regnum
LOONGARCH_ARG_REGNUM = 8, /* r4-r11: general-purpose argument registers.
f0-f7: floating-point argument registers. */
LOONGARCH_FIRST_FP_REGNUM = LOONGARCH_LINUX_NUM_GREGSET,
- LOONGARCH_FCC_REGNUM = LOONGARCH_FIRST_FP_REGNUM + 32,
- LOONGARCH_FCSR_REGNUM = LOONGARCH_FCC_REGNUM + 1,
- LOONGARCH_LINUX_NUM_FPREGSET = 34,
+ LOONGARCH_LINUX_NUM_FP = 32,
+ LOONGARCH_FIRST_FCC_REGNUM = LOONGARCH_FIRST_FP_REGNUM + LOONGARCH_LINUX_NUM_FP,
+ LOONGARCH_LINUX_NUM_FCC = 8,
+ LOONGARCH_FCSR_REGNUM = LOONGARCH_FIRST_FCC_REGNUM + LOONGARCH_LINUX_NUM_FCC,
};
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 @@
<reg name="f29" bitsize="64" type="fputype" group="float"/>
<reg name="f30" bitsize="64" type="fputype" group="float"/>
<reg name="f31" bitsize="64" type="fputype" group="float"/>
- <reg name="fcc" bitsize="64" type="fputype" group="float"/>
+ <reg name="fcc0" bitsize="8" type="uint8" group="float"/>
+ <reg name="fcc1" bitsize="8" type="uint8" group="float"/>
+ <reg name="fcc2" bitsize="8" type="uint8" group="float"/>
+ <reg name="fcc3" bitsize="8" type="uint8" group="float"/>
+ <reg name="fcc4" bitsize="8" type="uint8" group="float"/>
+ <reg name="fcc5" bitsize="8" type="uint8" group="float"/>
+ <reg name="fcc6" bitsize="8" type="uint8" group="float"/>
+ <reg name="fcc7" bitsize="8" type="uint8" group="float"/>
<reg name="fcsr" bitsize="32" type="uint32" group="float"/>
</feature>
diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c
index 3a81ff31972..df2b7031c69 100644
--- a/gdb/loongarch-linux-tdep.c
+++ b/gdb/loongarch-linux-tdep.c
@@ -122,19 +122,40 @@ loongarch_supply_fpregset (const struct regset *r,
const void *fprs, size_t len)
{
const gdb_byte *buf = nullptr;
- int fprsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM);
+ int fpsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM);
+ int fccsize = register_size (regcache->arch (), LOONGARCH_FIRST_FCC_REGNUM);
if (regnum == -1)
{
- for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++)
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FP; i++)
{
- buf = (const gdb_byte *)fprs + fprsize * i;
+ buf = (const gdb_byte *)fprs + fpsize * i;
regcache->raw_supply (LOONGARCH_FIRST_FP_REGNUM + i, (const void *)buf);
}
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++)
+ {
+ buf = (const gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP + fccsize * i;
+ regcache->raw_supply (LOONGARCH_FIRST_FCC_REGNUM + i, (const void *)buf);
+ }
+ buf = (const gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP +
+ fccsize * LOONGARCH_LINUX_NUM_FCC;
+ regcache->raw_supply (LOONGARCH_FCSR_REGNUM, (const void *)buf);
+ }
+ else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIRST_FCC_REGNUM)
+ {
+ buf = (const gdb_byte *)fprs + fpsize * (regnum - LOONGARCH_FIRST_FP_REGNUM);
+ regcache->raw_supply (regnum, (const void *)buf);
+ }
+ else if (regnum >= LOONGARCH_FIRST_FCC_REGNUM && regnum < LOONGARCH_FCSR_REGNUM)
+ {
+ buf = (const gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP +
+ fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM);
+ regcache->raw_supply (regnum, (const void *)buf);
}
- else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM)
+ else if (regnum == LOONGARCH_FCSR_REGNUM)
{
- buf = (const gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_REGNUM);
+ buf = (const gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP +
+ fccsize * LOONGARCH_LINUX_NUM_FCC;
regcache->raw_supply (regnum, (const void *)buf);
}
}
@@ -146,19 +167,40 @@ loongarch_fill_fpregset (const struct regset *r,
void *fprs, size_t len)
{
gdb_byte *buf = nullptr;
- int fprsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM);
+ int fpsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM);
+ int fccsize = register_size (regcache->arch (), LOONGARCH_FIRST_FCC_REGNUM);
if (regnum == -1)
{
- for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++)
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FP; i++)
{
- buf = (gdb_byte *)fprs + fprsize * i;
+ buf = (gdb_byte *)fprs + fpsize * i;
regcache->raw_collect (LOONGARCH_FIRST_FP_REGNUM + i, (void *)buf);
}
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++)
+ {
+ buf = (gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP + fccsize * i;
+ regcache->raw_collect (LOONGARCH_FIRST_FCC_REGNUM + i, (void *)buf);
+ }
+ buf = (gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP +
+ fccsize * LOONGARCH_LINUX_NUM_FCC;
+ regcache->raw_collect (LOONGARCH_FCSR_REGNUM, (void *)buf);
+ }
+ else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIRST_FCC_REGNUM)
+ {
+ buf = (gdb_byte *)fprs + fpsize * (regnum - LOONGARCH_FIRST_FP_REGNUM);
+ regcache->raw_collect (regnum, (void *)buf);
+ }
+ else if (regnum >= LOONGARCH_FIRST_FCC_REGNUM && regnum < LOONGARCH_FCSR_REGNUM)
+ {
+ buf = (gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP +
+ fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM);
+ regcache->raw_collect (regnum, (void *)buf);
}
- else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM)
+ else if (regnum == LOONGARCH_FCSR_REGNUM)
{
- buf = (gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_REGNUM);
+ buf = (gdb_byte *)fprs + fpsize * LOONGARCH_LINUX_NUM_FP +
+ fccsize * LOONGARCH_LINUX_NUM_FCC;
regcache->raw_collect (regnum, (void *)buf);
}
}
@@ -220,12 +262,14 @@ loongarch_iterate_over_regset_sections (struct gdbarch *gdbarch,
const struct regcache *regcache)
{
int gprsize = register_size (gdbarch, 0);
- int fprsize = register_size (gdbarch, LOONGARCH_FIRST_FP_REGNUM);
+ int fpsize = register_size (gdbarch, LOONGARCH_FIRST_FP_REGNUM);
+ int fccsize = register_size (gdbarch, LOONGARCH_FIRST_FCC_REGNUM);
+ int fcsrsize = register_size (gdbarch, LOONGARCH_FCSR_REGNUM);
+ int fprsize = fpsize * LOONGARCH_LINUX_NUM_FP + fccsize * LOONGARCH_LINUX_NUM_FCC + fcsrsize;
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", fprsize, fprsize, &loongarch_fpregset, nullptr, cb_data);
}
/* The following value is derived from __NR_rt_sigreturn in
diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c
index 5711e6f05d7..334dad518b9 100644
--- a/gdb/loongarch-tdep.c
+++ b/gdb/loongarch-tdep.c
@@ -1194,10 +1194,12 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Validate the description provides the fpu registers and
allocate their numbers. */
regnum = LOONGARCH_FIRST_FP_REGNUM;
- for (int i = 0; i < 32; i++)
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FP; i++)
valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++,
loongarch_f_normal_name[i] + 1);
- valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++, "fcc");
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++)
+ valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++,
+ loongarch_c_normal_name[i] + 1);
valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (), regnum++, "fcsr");
if (!valid_p)
return nullptr;
diff --git a/gdbserver/linux-loongarch-low.cc b/gdbserver/linux-loongarch-low.cc
index 7180f315b11..d7c18228609 100644
--- a/gdbserver/linux-loongarch-low.cc
+++ b/gdbserver/linux-loongarch-low.cc
@@ -127,12 +127,23 @@ loongarch_fill_fpregset (struct regcache *regcache, void *buf)
{
gdb_byte *regbuf = nullptr;
int fprsize = register_size (regcache->tdesc, LOONGARCH_FIRST_FP_REGNUM);
+ int fccsize = register_size (regcache->tdesc, LOONGARCH_FIRST_FCC_REGNUM);
- for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++)
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FP; i++)
{
regbuf = (gdb_byte *)buf + fprsize * i;
collect_register (regcache, LOONGARCH_FIRST_FP_REGNUM + i, regbuf);
}
+
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++)
+ {
+ regbuf = (gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FP + fccsize * i;
+ collect_register (regcache, LOONGARCH_FIRST_FCC_REGNUM + i, regbuf);
+ }
+
+ regbuf = (gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FP
+ + fccsize * LOONGARCH_LINUX_NUM_FCC;
+ collect_register (regcache, LOONGARCH_FCSR_REGNUM, regbuf);
}
/* Supply FPRs from BUF into REGCACHE. */
@@ -142,12 +153,23 @@ loongarch_store_fpregset (struct regcache *regcache, const void *buf)
{
const gdb_byte *regbuf = nullptr;
int fprsize = register_size (regcache->tdesc, LOONGARCH_FIRST_FP_REGNUM);
+ int fccsize = register_size (regcache->tdesc, LOONGARCH_FIRST_FCC_REGNUM);
- for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++)
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FP; i++)
{
regbuf = (const gdb_byte *)buf + fprsize * i;
supply_register (regcache, LOONGARCH_FIRST_FP_REGNUM + i, regbuf);
}
+
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++)
+ {
+ regbuf = (const gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FP + fccsize * i;
+ supply_register (regcache, LOONGARCH_FIRST_FCC_REGNUM + i, regbuf);
+ }
+
+ regbuf = (const gdb_byte *)buf + fprsize * LOONGARCH_LINUX_NUM_FP
+ + fccsize * LOONGARCH_LINUX_NUM_FCC;
+ supply_register (regcache, LOONGARCH_FCSR_REGNUM, regbuf);
}
/* LoongArch/Linux regsets. */
--
2.37.1
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-07-22 9:09 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-22 9:08 [PATCH] gdb/gdbserver: LoongArch: Improve implementation of fcc registers Feiyang Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).