[RFA] {supply,fill}_fpregset on x86-64

Michal Ludvig
2002-06-07T14:16:29Z

[-- Attachment #1: Type: text/plain, Size: 401 bytes --]

Hi all,
this patch eliminates the need of linking i387-tdep.o into x86-64
targeted gdb. Anyway it didn't work ;-)
I have written supply_fpregset and fill_fpregset from scratch along with
a supporing function x86_64_fxsave_offset. Lots of testsuite failures
was fixed by this patch.

Can I commit it?

Michal Ludvig
--
* SuSE CR, s.r.o * mludvig@suse.cz
* +420 2 9654 5373 * http://www.suse.cz

[-- Attachment #2: fpregset.diff --]
[-- Type: text/plain, Size: 7132 bytes --]

2002-06-05 Michal Ludvig <mludvig@suse.cz>

* x86-64-linux-nat.c (x86_64_fxsave_offset): New.
(supply_fpregset, fill_fpregset): Don't call i387_*_fxsave,
better do the things actually here.
* x86-64-tdep.c (x86_64_register_name2nr): New.
(x86_64_register_name): Renamed to x86_64_register_nr2name.
(x86_64_gdbarch_init): Respect the above change.
* x86-64-tdep.h (x86_64_register_name2nr)
(x86_64_register_nr2name): Add prototypes.
* config/i386/x86-64linux.mt (TDEPFILES): Remove i387-tdep.o.

Index: x86-64-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-linux-nat.c,v
retrieving revision 1.12
diff -c -3 -p -r1.12 x86-64-linux-nat.c
*** x86-64-linux-nat.c 11 May 2002 17:22:26 -0000 1.12
--- x86-64-linux-nat.c 5 Jun 2002 15:27:39 -0000
***************
*** 25,31 ****
#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
- #include "i387-tdep.h"
#include "gdb_assert.h"
#include "x86-64-tdep.h"

--- 25,30 ----
*************** store_regs (int tid, int regno)
*** 195,217 ****

/* Transfering floating-point registers between GDB, inferiors and cores. */

! /* Fill GDB's register array with the floating-point register values in
! *FPREGSETP. */
!
! void
! supply_fpregset (elf_fpregset_t * fpregsetp)
{
! i387_supply_fxsave ((char *) fpregsetp);
! }

! /* Fill register REGNO (if it is a floating-point register) in
! *FPREGSETP with the value in GDB's register array. If REGNO is -1,
! do this for all registers. */

! void
! fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
! {
! i387_fill_fxsave ((char *) fpregsetp, regno);
}

/* Fetch all floating-point registers from process/thread TID and store
--- 194,266 ----

/* Transfering floating-point registers between GDB, inferiors and cores. */

! static void *
! x86_64_fxsave_offset (elf_fpregset_t *fxsave, int regnum)
{
! char *reg_name;
! int reg_index;

! gdb_assert (x86_64_num_gregs-1 < regnum
! && regnum < x86_64_num_regs);

! reg_name = x86_64_register_nr2name (regnum);
!
! if (reg_name[0] == 's' && reg_name[1] == 't')
! {
! reg_index = reg_name[2] - '0';
! return &fxsave->st_space [reg_index * 2];
! }
!
! if (reg_name[0] == 'x' && reg_name[1] == 'm' && reg_name[2] == 'm')
! {
! reg_index = reg_name[3] - '0';
! return &fxsave->xmm_space [reg_index * 4];
! }
!
! if (strcmp (reg_name, "mxcsr") == 0)
! return &fxsave->mxcsr;
!
! return NULL;
! }
! /* Fill GDB's register array with the floating-point and SSE register
! values in *FXSAVE. This function masks off any of the reserved
! bits in *FXSAVE. */
!
! void
! supply_fpregset (elf_fpregset_t *fxsave)
! {
! int i, reg_st0, reg_mxcsr;
!
! reg_st0 = x86_64_register_name2nr ("st0");
! reg_mxcsr = x86_64_register_name2nr ("mxcsr");
!
! gdb_assert (reg_st0 > 0 && reg_mxcsr > reg_st0);
!
! for (i = reg_st0; i <= reg_mxcsr; i++)
! supply_register (i, x86_64_fxsave_offset (fxsave, i));
! }
!
! /* Fill register REGNUM (if it is a floating-point or SSE register) in
! *FXSAVE with the value in GDB's register array. If REGNUM is -1, do
! this for all registers. This function doesn't touch any of the
! reserved bits in *FXSAVE. */
!
! void
! fill_fpregset (elf_fpregset_t *fxsave, int regnum)
! {
! int i, last_regnum = MXCSR_REGNUM;
! void *ptr;
!
! if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
! last_regnum = FOP_REGNUM;
!
! for (i = FP0_REGNUM; i <= last_regnum; i++)
! if (regnum == -1 || regnum == i)
! {
! ptr = x86_64_fxsave_offset (fxsave, i);
! if (ptr)
! regcache_collect (i, ptr);
! }
}

/* Fetch all floating-point registers from process/thread TID and store
Index: x86-64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v
retrieving revision 1.20
diff -c -3 -p -r1.20 x86-64-tdep.c
*** x86-64-tdep.c 27 May 2002 13:37:38 -0000 1.20
--- x86-64-tdep.c 5 Jun 2002 15:27:39 -0000
*************** x86_64_store_return_value (struct type *
*** 797,809 ****
}
\f

! static char *
! x86_64_register_name (int reg_nr)
{
if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS)
return NULL;
return x86_64_register_info_table[reg_nr].name;
}
\f

--- 797,820 ----
}
\f

! char *
! x86_64_register_nr2name (int reg_nr)
{
if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS)
return NULL;
return x86_64_register_info_table[reg_nr].name;
}
+
+ int
+ x86_64_register_name2nr (const char *name)
+ {
+ int reg_nr;
+
+ for (reg_nr = 0; reg_nr < X86_64_NUM_REGS; reg_nr++)
+ if (strcmp (name, x86_64_register_info_table[reg_nr].name) == 0)
+ return reg_nr;
+ return -1;
+ }
\f

*************** x86_64_gdbarch_init (struct gdbarch_info
*** 982,988 ****
set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext);

set_gdbarch_num_regs (gdbarch, X86_64_NUM_REGS);
! set_gdbarch_register_name (gdbarch, x86_64_register_name);
set_gdbarch_register_size (gdbarch, 8);
set_gdbarch_register_raw_size (gdbarch, x86_64_register_raw_size);
set_gdbarch_max_register_raw_size (gdbarch, 16);
--- 988,994 ----
set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext);

set_gdbarch_num_regs (gdbarch, X86_64_NUM_REGS);
! set_gdbarch_register_name (gdbarch, x86_64_register_nr2name);
set_gdbarch_register_size (gdbarch, 8);
set_gdbarch_register_raw_size (gdbarch, x86_64_register_raw_size);
set_gdbarch_max_register_raw_size (gdbarch, 16);
Index: x86-64-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.h,v
retrieving revision 1.3
diff -c -3 -p -r1.3 x86-64-tdep.h
*** x86-64-tdep.h 27 Mar 2002 10:21:26 -0000 1.3
--- x86-64-tdep.h 5 Jun 2002 15:27:39 -0000
***************
*** 28,33 ****
--- 28,36 ----
extern int x86_64_num_regs;
extern int x86_64_num_gregs;

+ int x86_64_register_name2nr (const char *name);
+ char *x86_64_register_nr2name (int reg_nr);
+
gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;

Index: config/i386/x86-64linux.mt
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/x86-64linux.mt,v
retrieving revision 1.3
diff -c -3 -p -r1.3 x86-64linux.mt
*** config/i386/x86-64linux.mt 4 May 2002 15:52:39 -0000 1.3
--- config/i386/x86-64linux.mt 5 Jun 2002 15:27:39 -0000
***************
*** 1,3 ****
# Target: AMD x86-64 running GNU/Linux
! TDEPFILES= x86-64-tdep.o x86-64-linux-tdep.o i387-tdep.o dwarf2cfi.o \
solib.o solib-svr4.o solib-legacy.o
--- 1,3 ----
# Target: AMD x86-64 running GNU/Linux
! TDEPFILES= x86-64-tdep.o x86-64-linux-tdep.o dwarf2cfi.o \
solib.o solib-svr4.o solib-legacy.o