aboutsummaryrefslogtreecommitdiff
path: root/gdb/loongarch-linux-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/loongarch-linux-tdep.c')
-rw-r--r--gdb/loongarch-linux-tdep.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c
index 726b671..0e82c09 100644
--- a/gdb/loongarch-linux-tdep.c
+++ b/gdb/loongarch-linux-tdep.c
@@ -338,6 +338,107 @@ const struct regset loongarch_lasxregset =
loongarch_fill_lasxregset,
};
+/* Unpack an lbt regset into GDB's register cache. */
+
+static void
+loongarch_supply_lbtregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *regs, size_t len)
+{
+ int scrsize = register_size (regcache->arch (), LOONGARCH_FIRST_SCR_REGNUM);
+ int eflagssize = register_size (regcache->arch (), LOONGARCH_EFLAGS_REGNUM);
+ const gdb_byte *buf = nullptr;
+
+ if (regnum == -1)
+ {
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_SCR; i++)
+ {
+ buf = (const gdb_byte *) regs + scrsize * i;
+ regcache->raw_supply (LOONGARCH_FIRST_SCR_REGNUM + i,
+ (const void *) buf);
+ }
+
+ buf = (const gdb_byte*) regs + scrsize * LOONGARCH_LINUX_NUM_SCR;
+ regcache->raw_supply (LOONGARCH_EFLAGS_REGNUM, (const void *) buf);
+
+ buf = (const gdb_byte*) regs
+ + scrsize * LOONGARCH_LINUX_NUM_SCR
+ + eflagssize;
+ regcache->raw_supply (LOONGARCH_FTOP_REGNUM, (const void *) buf);
+ }
+ else if (regnum >= LOONGARCH_FIRST_SCR_REGNUM
+ && regnum <= LOONGARCH_LAST_SCR_REGNUM)
+ {
+ buf = (const gdb_byte*) regs
+ + scrsize * (regnum - LOONGARCH_FIRST_SCR_REGNUM);
+ regcache->raw_supply (regnum, (const void *) buf);
+ }
+ else if (regnum == LOONGARCH_EFLAGS_REGNUM)
+ {
+ buf = (const gdb_byte*) regs + scrsize * LOONGARCH_LINUX_NUM_SCR;
+ regcache->raw_supply (regnum, (const void *) buf);
+ }
+ else if (regnum == LOONGARCH_FTOP_REGNUM)
+ {
+ buf = (const gdb_byte*) regs
+ + scrsize * LOONGARCH_LINUX_NUM_SCR
+ + eflagssize;
+ regcache->raw_supply (regnum, (const void *) buf);
+ }
+}
+
+/* Pack the GDB's register cache value into an lbt regset. */
+
+static void
+loongarch_fill_lbtregset (const struct regset *regset,
+ const struct regcache *regcache, int regnum,
+ void *regs, size_t len)
+{
+ int scrsize = register_size (regcache->arch (), LOONGARCH_FIRST_SCR_REGNUM);
+ int eflagssize = register_size (regcache->arch (), LOONGARCH_EFLAGS_REGNUM);
+ gdb_byte *buf = nullptr;
+
+ if (regnum == -1)
+ {
+ for (int i = 0; i < LOONGARCH_LINUX_NUM_SCR; i++)
+ {
+ buf = (gdb_byte *) regs + scrsize * i;
+ regcache->raw_collect (LOONGARCH_FIRST_SCR_REGNUM + i, (void *) buf);
+ }
+
+ buf = (gdb_byte *) regs + scrsize * LOONGARCH_LINUX_NUM_SCR;
+ regcache->raw_collect (LOONGARCH_EFLAGS_REGNUM, (void *) buf);
+
+ buf = (gdb_byte *) regs + scrsize * LOONGARCH_LINUX_NUM_SCR + eflagssize;
+ regcache->raw_collect (LOONGARCH_FTOP_REGNUM, (void *) buf);
+ }
+ else if (regnum >= LOONGARCH_FIRST_SCR_REGNUM
+ && regnum <= LOONGARCH_LAST_SCR_REGNUM)
+ {
+ buf = (gdb_byte *) regs + scrsize * (regnum - LOONGARCH_FIRST_SCR_REGNUM);
+ regcache->raw_collect (regnum, (void *) buf);
+ }
+ else if (regnum == LOONGARCH_EFLAGS_REGNUM)
+ {
+ buf = (gdb_byte *) regs + scrsize * LOONGARCH_LINUX_NUM_SCR;
+ regcache->raw_collect (regnum, (void *) buf);
+ }
+ else if (regnum == LOONGARCH_FTOP_REGNUM)
+ {
+ buf = (gdb_byte *) regs + scrsize * LOONGARCH_LINUX_NUM_SCR + eflagssize;
+ regcache->raw_collect (regnum, (void *) buf);
+ }
+}
+
+/* Define the lbt register regset. */
+
+const struct regset loongarch_lbtregset =
+{
+ nullptr,
+ loongarch_supply_lbtregset,
+ loongarch_fill_lbtregset,
+};
+
/* Implement the "init" method of struct tramp_frame. */
#define LOONGARCH_RT_SIGFRAME_UCONTEXT_OFFSET 128
@@ -394,6 +495,10 @@ loongarch_iterate_over_regset_sections (struct gdbarch *gdbarch,
fccsize * LOONGARCH_LINUX_NUM_FCC + fcsrsize;
int lsxrsize = register_size (gdbarch, LOONGARCH_FIRST_LSX_REGNUM);
int lasxrsize = register_size (gdbarch, LOONGARCH_FIRST_LASX_REGNUM);
+ int scrsize = register_size (gdbarch, LOONGARCH_FIRST_SCR_REGNUM);
+ int eflagssize = register_size (gdbarch, LOONGARCH_EFLAGS_REGNUM);
+ int ftopsize = register_size (gdbarch, LOONGARCH_FTOP_REGNUM);
+ int lbtsize = scrsize * LOONGARCH_LINUX_NUM_SCR + eflagssize + ftopsize;
cb (".reg", LOONGARCH_LINUX_NUM_GREGSET * gprsize,
LOONGARCH_LINUX_NUM_GREGSET * gprsize, &loongarch_gregset, nullptr, cb_data);
@@ -402,6 +507,8 @@ loongarch_iterate_over_regset_sections (struct gdbarch *gdbarch,
&loongarch_lsxregset, nullptr, cb_data);
cb (".reg-loongarch-lasx", lasxrsize, lasxrsize,
&loongarch_lasxregset, nullptr, cb_data);
+ cb (".reg-loongarch-lbt", lbtsize, lbtsize,
+ &loongarch_lbtregset, nullptr, cb_data);
}