2002-06-07 Michal Ludvig <mludvig@suse.cz>
authorMichal Ludvig <mludvig@suse.cz>
Fri, 7 Jun 2002 16:11:10 +0000 (16:11 +0000)
committerMichal Ludvig <mludvig@suse.cz>
Fri, 7 Jun 2002 16:11:10 +0000 (16:11 +0000)
* 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.

gdb/ChangeLog
gdb/config/i386/x86-64linux.mt
gdb/x86-64-linux-nat.c
gdb/x86-64-tdep.c
gdb/x86-64-tdep.h

index 1285ec1ac5a50072e8ced67adfec107d33342b78..82d60b3082245fc21de0827bf72f6791acf51737 100644 (file)
@@ -1,3 +1,15 @@
+2002-06-07  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.
+
 2002-06-06  Michael Snyder  <msnyder@redhat.com>
 
        * d10v-tdep.c (d10v_push_arguments): Handle struct_return.
index 85f1972531d89fb41a5c49e740d52c271cd02398..58a9cee1889415efd632671591bb4898e5edc35d 100644 (file)
@@ -1,3 +1,3 @@
 # Target: AMD x86-64 running GNU/Linux
-TDEPFILES= x86-64-tdep.o x86-64-linux-tdep.o i387-tdep.o dwarf2cfi.o \
+TDEPFILES= x86-64-tdep.o x86-64-linux-tdep.o dwarf2cfi.o \
        solib.o solib-svr4.o solib-legacy.o
index f57a5f276757fe4e6e78867f3dd22de3c635a896..4c4f64382c402e97d051573744538105a412e243 100644 (file)
@@ -25,7 +25,6 @@
 #include "inferior.h"
 #include "gdbcore.h"
 #include "regcache.h"
-#include "i387-tdep.h"
 #include "gdb_assert.h"
 #include "x86-64-tdep.h"
 
@@ -195,23 +194,73 @@ store_regs (int tid, int regno)
 
 /* Transfering floating-point registers between GDB, inferiors and cores.  */
 
-/* Fill GDB's register array with the floating-point register values in
-   *FPREGSETP.  */
+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 * fpregsetp)
+supply_fpregset (elf_fpregset_t * fxsave)
 {
-  i387_supply_fxsave ((char *) fpregsetp);
+  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 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.  */
+/* 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 * fpregsetp, int regno)
+fill_fpregset (elf_fpregset_t * fxsave, int regnum)
 {
-  i387_fill_fxsave ((char *) fpregsetp, regno);
+  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 a3f8bee16826cf796957a6bb5cae52441df70f1b..6391e756c9be3be877da5c5447cb09019e714d5b 100644 (file)
@@ -376,14 +376,15 @@ classify_argument (struct type *type,
                {
                  int num = classify_argument (TYPE_FIELDS (type)[j].type,
                                               subclasses,
-                                              (TYPE_FIELDS (type)[j].loc.bitpos
-                                               + bit_offset) % 256);
+                                              (TYPE_FIELDS (type)[j].loc.
+                                               bitpos + bit_offset) % 256);
                  if (!num)
                    return 0;
                  for (i = 0; i < num; i++)
                    {
                      int pos =
-                       (TYPE_FIELDS (type)[j].loc.bitpos + bit_offset) / 8 / 8;
+                       (TYPE_FIELDS (type)[j].loc.bitpos +
+                        bit_offset) / 8 / 8;
                      classes[i + pos] =
                        merge_classes (subclasses[i], classes[i + pos]);
                    }
@@ -490,7 +491,7 @@ classify_argument (struct type *type,
        }
     case TYPE_CODE_VOID:
       return 0;
-    default: /* Avoid warning.  */
+    default:                   /* Avoid warning.  */
       break;
     }
   internal_error (__FILE__, __LINE__,
@@ -797,13 +798,24 @@ x86_64_store_return_value (struct type *type, char *valbuf)
 }
 \f
 
-static char *
-x86_64_register_name (int reg_nr)
+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
 
 
@@ -862,7 +874,7 @@ x86_64_skip_prologue (CORE_ADDR pc)
   /* First check, whether pc points to pushq %rbp, movq %rsp,%rbp.  */
   for (i = 0; i < PROLOG_BUFSIZE; i++)
     if (prolog_expect[i] != prolog_buf[i])
-      return pc;       /* ... no, it doesn't. Nothing to skip.  */
+      return pc;               /* ... no, it doesn't. Nothing to skip.  */
 
   /* OK, we have found the prologue and want PC of the first 
      non-prologue instruction.  */
@@ -982,7 +994,7 @@ x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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_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 d15b8e71e7f0365f8a8fde26d6806cb6f0442814..dda94bc5eb87f458748dcd5bacddf2b060952dac 100644 (file)
@@ -28,6 +28,9 @@
 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;