diff options
Diffstat (limited to 'gdb/loongarch-linux-tdep.c')
-rw-r--r-- | gdb/loongarch-linux-tdep.c | 107 |
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); } |