This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] i386-nto-tdep.c: Add support for xmm registers.


Hello,

This adds support for xmm registers for QNX target.

Thanks,

Aleksandar


ChangeLog



Add support for XMM registers.
* i386-nto-tdep.c (i386_nto_target): Remove definition.
(i386nto_regset_id): Add case for SSE register set.
(i386nto_register_area): Correctly calculate offsets and sizes for all supported registers.
(I386_NTO_SIGCONTEXT_OFFSET): Remove macro definition.
(i386nto_sigcontext_addr): Use better method of retrieving sigcontext pointer.
(init_i386nto_ops): Remove i386_nto_target.
(i386nto_init_abi): Remove nto_svr4_so_ops indirection. Properly setup tdep params sc_reg_offset and sc_num_regs. Remove nto_svr4_so_ops and make changes accordingly.



Index: gdb/i386-nto-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-nto-tdep.c,v
retrieving revision 1.32
diff -u -p -r1.32 i386-nto-tdep.c
--- gdb/i386-nto-tdep.c	22 Feb 2009 01:02:17 -0000	1.32
+++ gdb/i386-nto-tdep.c	27 May 2009 19:06:41 -0000
@@ -34,9 +34,6 @@
 #include "solib.h"
 #include "solib-svr4.h"
 
-/* Target vector for QNX NTO x86.  */
-static struct nto_target_ops i386_nto_target;
-
 #ifndef X86_CPU_FXSR
 #define X86_CPU_FXSR (1L << 12)
 #endif
@@ -126,6 +123,8 @@ i386nto_regset_id (int regno)
     return NTO_REG_GENERAL;
   else if (regno < I386_NUM_GREGS + I386_NUM_FREGS)
     return NTO_REG_FLOAT;
+  else if (regno < I386_SSE_NUM_REGS)
+    return NTO_REG_FLOAT; /* We store xmm registers in fxsave_area.  */
 
   return -1;			/* Error.  */
 }
@@ -134,6 +133,7 @@ static int
 i386nto_register_area (struct gdbarch *gdbarch,
 		       int regno, int regset, unsigned *off)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int len;
 
   *off = 0;
@@ -149,30 +149,98 @@ i386nto_register_area (struct gdbarch *g
     }
   else if (regset == NTO_REG_FLOAT)
     {
-      unsigned off_adjust, regsize, regset_size;
+      unsigned off_adjust, regsize, regset_size, regno_base;
+      /* The following are flags indicating number in our fxsave_area.  */
+      int first_four = (regno >= I387_FCTRL_REGNUM (tdep)
+			&& regno <= I387_FISEG_REGNUM (tdep));
+      int second_four = (regno > I387_FISEG_REGNUM (tdep)
+			 && regno <= I387_FOP_REGNUM (tdep));
+      int st_reg = (regno >= I387_ST0_REGNUM (tdep)
+		    && regno < I387_ST0_REGNUM (tdep) + 8);
+      int xmm_reg = (regno >= I387_XMM0_REGNUM (tdep)
+		     && regno < I387_MXCSR_REGNUM (tdep));
 
       if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
 	{
-	  off_adjust = 32;
-	  regsize = 16;
 	  regset_size = 512;
+	  /* fxsave_area structure.  */
+	  if (first_four)
+	    {
+	      /* fpu_control_word, fpu_status_word, fpu_tag_word, fpu_operand
+	         registers.  */
+	      regsize = 2; /* Two bytes each.  */
+	      off_adjust = 0;
+	      regno_base = I387_FCTRL_REGNUM (tdep);
+	    }
+	  else if (second_four)
+	    {
+	      /* fpu_ip, fpu_cs, fpu_op, fpu_ds registers.  */
+	      regsize = 4;
+	      off_adjust = 8;
+	      regno_base = I387_FISEG_REGNUM (tdep) + 1;
+	    }
+	  else if (st_reg)
+	    {
+	      /* ST registers.  */
+	      regsize = 16;
+	      off_adjust = 32;
+	      regno_base = I387_ST0_REGNUM (tdep);
+	    }
+	  else if (xmm_reg)
+	    {
+	      /* XMM registers.  */
+	      regsize = 16;
+	      off_adjust = 160;
+	      regno_base = I387_XMM0_REGNUM (tdep);
+	    }
+	  else if (regno == I387_MXCSR_REGNUM (tdep))
+	    {
+	      regsize = 4;
+	      off_adjust = 24;
+	      regno_base = I387_MXCSR_REGNUM (tdep);
+	    }
+	  else
+	    {
+	      /* Whole regset.  */
+	      gdb_assert (regno == -1);
+	      off_adjust = 0;
+	      regno_base = 0;
+	      regsize = regset_size;
+	    }
 	}
       else
 	{
-	  off_adjust = 28;
-	  regsize = 10;
-	  regset_size = 128;
+	  regset_size = 108;
+	  /* fsave_area structure.  */
+	  if (first_four || second_four)
+	    {
+	      /* fpu_control_word, ... , fpu_ds registers.  */
+	      regsize = 4;
+	      off_adjust = 0;
+	      regno_base = I387_FCTRL_REGNUM (tdep);
+	    }
+	  else if (st_reg)
+	    {
+	      /* One of ST registers.  */
+	      regsize = 10;
+	      off_adjust = 7 * 4;
+	      regno_base = I387_ST0_REGNUM (tdep);
+	    }
+	  else
+	    {
+	      /* Whole regset.  */
+	      gdb_assert (regno == -1);
+	      off_adjust = 0;
+	      regno_base = 0;
+	      regsize = regset_size;
+	    }
 	}
 
-      if (regno == -1)
-	return regset_size;
-
-      *off = (regno - gdbarch_fp0_regnum (gdbarch)) * regsize + off_adjust;
-      return 10;
-      /* Why 10 instead of regsize?  GDB only stores 10 bytes per FP
-         register so if we're sending a register back to the target,
-         we only want pdebug to write 10 bytes so as not to clobber
-         the reserved 6 bytes in the fxsave structure.  */
+      if (regno != -1)
+	*off = off_adjust + (regno - regno_base) * regsize;
+      else
+	*off = 0;
+      return regsize;
     }
   return -1;
 }
@@ -217,8 +285,6 @@ i386nto_sigtramp_p (struct frame_info *t
   return name && strcmp ("__signalstub", name) == 0;
 }
 
-#define I386_NTO_SIGCONTEXT_OFFSET 136
-
 /* Assuming THIS_FRAME is a QNX Neutrino sigtramp routine, return the
    address of the associated sigcontext structure.  */
 
@@ -226,33 +292,33 @@ static CORE_ADDR
 i386nto_sigcontext_addr (struct frame_info *this_frame)
 {
   char buf[4];
-  CORE_ADDR sp;
+  CORE_ADDR ptrctx;
 
-  get_frame_register (this_frame, I386_ESP_REGNUM, buf);
-  sp = extract_unsigned_integer (buf, 4);
+  /* We store __ucontext_t addr in EDI register.  */
+  get_frame_register (this_frame, I386_EDI_REGNUM, buf);
+  ptrctx = extract_unsigned_integer (buf, 4);
+  ptrctx += 24 /* Context pointer is at this offset.  */;
 
-  return sp + I386_NTO_SIGCONTEXT_OFFSET;
+  return ptrctx;
 }
 
 static void
 init_i386nto_ops (void)
 {
-  i386_nto_target.regset_id = i386nto_regset_id;
-  i386_nto_target.supply_gregset = i386nto_supply_gregset;
-  i386_nto_target.supply_fpregset = i386nto_supply_fpregset;
-  i386_nto_target.supply_altregset = nto_dummy_supply_regset;
-  i386_nto_target.supply_regset = i386nto_supply_regset;
-  i386_nto_target.register_area = i386nto_register_area;
-  i386_nto_target.regset_fill = i386nto_regset_fill;
-  i386_nto_target.fetch_link_map_offsets =
-    svr4_ilp32_fetch_link_map_offsets;
+  nto_regset_id = i386nto_regset_id;
+  nto_supply_gregset = i386nto_supply_gregset;
+  nto_supply_fpregset = i386nto_supply_fpregset;
+  nto_supply_altregset = nto_dummy_supply_regset;
+  nto_supply_regset = i386nto_supply_regset;
+  nto_register_area = i386nto_register_area;
+  nto_regset_fill = i386nto_regset_fill;
+  nto_fetch_link_map_offsets = svr4_ilp32_fetch_link_map_offsets;
 }
 
 static void
 i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  static struct target_so_ops nto_svr4_so_ops;
 
   /* Deal with our strange signals.  */
   nto_initialize_signals ();
@@ -270,8 +336,8 @@ i386nto_init_abi (struct gdbarch_info in
 
   tdep->sigtramp_p = i386nto_sigtramp_p;
   tdep->sigcontext_addr = i386nto_sigcontext_addr;
-  tdep->sc_pc_offset = 56;
-  tdep->sc_sp_offset = 68;
+  tdep->sc_reg_offset = i386nto_gregset_reg_offset;
+  tdep->sc_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset);
 
   /* Setjmp()'s return PC saved in EDX (5).  */
   tdep->jb_pc_offset = 20;	/* 5x32 bit ints in.  */
@@ -279,31 +345,17 @@ i386nto_init_abi (struct gdbarch_info in
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
 
-  /* Initialize this lazily, to avoid an initialization order
-     dependency on solib-svr4.c's _initialize routine.  */
-  if (nto_svr4_so_ops.in_dynsym_resolve_code == NULL)
-    {
-      nto_svr4_so_ops = svr4_so_ops;
+  /* Our loader handles solib relocations differently than svr4.  */
+  svr4_so_ops.relocate_section_addresses = nto_relocate_section_addresses;
 
-      /* Our loader handles solib relocations differently than svr4.  */
-      nto_svr4_so_ops.relocate_section_addresses
-        = nto_relocate_section_addresses;
-
-      /* Supply a nice function to find our solibs.  */
-      nto_svr4_so_ops.find_and_open_solib
-        = nto_find_and_open_solib;
-
-      /* Our linker code is in libc.  */
-      nto_svr4_so_ops.in_dynsym_resolve_code
-        = nto_in_dynsym_resolve_code;
-    }
-  set_solib_ops (gdbarch, &nto_svr4_so_ops);
+  /* Supply a nice function to find our solibs.  */
+  svr4_so_ops.find_and_open_solib = nto_find_and_open_solib;
 
-  nto_set_target (&i386_nto_target);
-}
+  /* Our linker code is in libc.  */
+  svr4_so_ops.in_dynsym_resolve_code = nto_in_dynsym_resolve_code;
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_i386nto_tdep;
+  set_solib_ops (gdbarch, &svr4_so_ops);
+}
 
 void
 _initialize_i386nto_tdep (void)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]