Patches to add i387 support to Solaris x86 platforms

Peter.Schauer Peter.Schauer@regent.e-technik.tu-muenchen.de
Mon Feb 28 00:23:00 GMT 2000


> Can you fix that Peter?

Sure, below is a revised patch.
Please note that moving the definition of [LOW,HIGH]_RETURN_REGNUM
to tm-i386.h is still an open issue.

> I'm also not sure about the usefullness of the testsuite change.  The
> absence of the i387 registers on a i386 target probably means that the
> maintainer has some work to do :-).  A reminder in the testsuite
> wouldn't hurt too much I guess.

It might be laziness for native targets, but I am sure that there are
embedded targets without floating point support out there. Anyway,
if you don't like that change, just drop it.


2000-02-28  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>

	Add floating point support for Solaris x86.
	* config/i386/tm-i386sol2.h (HAVE_I387_REGS):  Define.
	* i386-tdep.c (i386_extract_return_value):  Extract floating point
	return value from FP0_REGNUM if NUM_FREGS is non zero, not only
	for I386_GNULINUX_TARGET. Get rid of obsolete FPDATA_REGNUM
	reference.
	* i386v4-nat.c (supply_fpregset, fill_fpregset):  Add code
	to handle floating point registers for the NUM_FREGS non zero case.

	* config/i386/tm-i386sol2.h (LOW_RETURN_REGNUM, HIGH_RETURN_REGNUM):
	Define for correct extraction of long long return values from
	function calls.

2000-02-28  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>

	gdb.base/default.exp (info float):  Allow the absence of i387
	support for x86 targets.

*** ./gdb/config/i386/tm-i386sol2.h.orig	Tue Jan 11 04:07:28 2000
--- ./gdb/config/i386/tm-i386sol2.h	Mon Feb 21 09:51:36 2000
***************
*** 21,28 ****
--- 21,34 ----
  #ifndef TM_I386SOL2_H
  #define TM_I386SOL2_H 1
  
+ #define HAVE_I387_REGS
  #include "i386/tm-i386v4.h"
  
+ /* Define eax/edx as return registers for long long return values. */
+ /* FIXME: Maybe this should be moved to tm-i386.h, as it is pretty generic. */
+ #define LOW_RETURN_REGNUM 0	/* Holds low four bytes of result */
+ #define HIGH_RETURN_REGNUM 2	/* Holds high four bytes of result */
+ 
  /* Signal handler frames under Solaris 2 are recognized by a return address
     of 0xFFFFFFFF, the third parameter on the signal handler stack is
     a pointer to an ucontext.  */
*** ./gdb/i386-tdep.c.orig	Thu Feb 24 18:40:50 2000
--- ./gdb/i386-tdep.c	Mon Feb 28 08:48:28 2000
***************
*** 702,726 ****
       char regbuf[REGISTER_BYTES];
       char *valbuf;
  {
!   /* On AIX and i386 GNU/Linux, floating point values are returned in
       floating point registers.  */
! #if defined(I386_AIX_TARGET) || defined(I386_GNULINUX_TARGET)
    if (TYPE_CODE_FLT == TYPE_CODE (type))
      {
        double d;
        /* 387 %st(0), gcc uses this */
        floatformat_to_double (&floatformat_i387_ext,
- #if defined(FPDATA_REGNUM)
- 			     &regbuf[REGISTER_BYTE (FPDATA_REGNUM)],
- #else /* !FPDATA_REGNUM */
  			     &regbuf[REGISTER_BYTE (FP0_REGNUM)],
- #endif /* FPDATA_REGNUM */
- 
  			     &d);
        store_floating (valbuf, TYPE_LENGTH (type), d);
      }
    else
! #endif /* I386_AIX_TARGET || I386_GNULINUX_TARGET*/
      {
  #if defined(LOW_RETURN_REGNUM)
        int len = TYPE_LENGTH (type);
--- 702,721 ----
       char regbuf[REGISTER_BYTES];
       char *valbuf;
  {
!   /* If we have i387 registers, floating point values are returned in
       floating point registers.  */
! #if defined(I386_AIX_TARGET) || (NUM_FREGS > 0)
    if (TYPE_CODE_FLT == TYPE_CODE (type))
      {
        double d;
        /* 387 %st(0), gcc uses this */
        floatformat_to_double (&floatformat_i387_ext,
  			     &regbuf[REGISTER_BYTE (FP0_REGNUM)],
  			     &d);
        store_floating (valbuf, TYPE_LENGTH (type), d);
      }
    else
! #endif /* I386_AIX_TARGET || (NUM_FREGS > 0) */
      {
  #if defined(LOW_RETURN_REGNUM)
        int len = TYPE_LENGTH (type);
*** ./gdb/i386v4-nat.c.orig	Wed Jul  7 22:07:05 1999
--- ./gdb/i386v4-nat.c	Mon Feb 28 08:57:15 2000
***************
*** 142,158 ****
  
  #endif /* HAVE_GREGSET_T */
  
! #if defined (FP0_REGNUM) && defined (HAVE_FPREGSET_T)
  
  /*  Given a pointer to a floating point register set in /proc format
     (fpregset_t *), unpack the register contents and supply them as gdb's
     idea of the current floating point register values. */
  
  void
  supply_fpregset (fpregsetp)
       fpregset_t *fpregsetp;
  {
!   /* FIXME: see m68k-tdep.c for an example, for the m68k. */
  }
  
  /*  Given a pointer to a floating point register set in /proc format
--- 142,206 ----
  
  #endif /* HAVE_GREGSET_T */
  
! #if defined (HAVE_FPREGSET_T)
  
  /*  Given a pointer to a floating point register set in /proc format
     (fpregset_t *), unpack the register contents and supply them as gdb's
     idea of the current floating point register values. */
  
+ /* FIXME: Assumes that fpregsetp contains an i387 FSAVE area. */
+ static const int freg_offset_map[] =
+ {
+ #if !defined(FPREGSET_FSAVE_OFFSET)
+ #define FPREGSET_FSAVE_OFFSET	0
+ #endif
+   FPREGSET_FSAVE_OFFSET + 28 + 0 * 10,
+   FPREGSET_FSAVE_OFFSET + 28 + 1 * 10,
+   FPREGSET_FSAVE_OFFSET + 28 + 2 * 10,
+   FPREGSET_FSAVE_OFFSET + 28 + 3 * 10,
+   FPREGSET_FSAVE_OFFSET + 28 + 4 * 10,
+   FPREGSET_FSAVE_OFFSET + 28 + 5 * 10,
+   FPREGSET_FSAVE_OFFSET + 28 + 6 * 10,
+   FPREGSET_FSAVE_OFFSET + 28 + 7 * 10,
+   FPREGSET_FSAVE_OFFSET + 0,
+   FPREGSET_FSAVE_OFFSET + 4,
+   FPREGSET_FSAVE_OFFSET + 8,
+   FPREGSET_FSAVE_OFFSET + 16,
+   FPREGSET_FSAVE_OFFSET + 12,
+   FPREGSET_FSAVE_OFFSET + 24,
+   FPREGSET_FSAVE_OFFSET + 20,
+   FPREGSET_FSAVE_OFFSET + 16
+ };
+ 
  void
  supply_fpregset (fpregsetp)
       fpregset_t *fpregsetp;
  {
! #if (NUM_FREGS > 0)
!   int regi;
!   
!   for (regi = FP0_REGNUM; regi <= LAST_FPU_CTRL_REGNUM; regi++)
!     {
!       char tbuf[4];
!       ULONGEST tval;
!       char *from = (char *) fpregsetp + freg_offset_map[regi - FP0_REGNUM];
! 
!       if (regi == FCS_REGNUM)
! 	{
! 	  tval = extract_unsigned_integer (from, 4) & 0xffff;
! 	  store_unsigned_integer (tbuf, 4, tval);
! 	  supply_register (regi, tbuf);
! 	}
!       else if (regi == FOP_REGNUM)
! 	{
! 	  tval = (extract_unsigned_integer (from, 4) >> 16) & ((1 << 11) - 1);
! 	  store_unsigned_integer (tbuf, 4, tval);
! 	  supply_register (regi, tbuf);
! 	}
!       else
! 	supply_register (regi, from);
!     }
! #endif
  }
  
  /*  Given a pointer to a floating point register set in /proc format
***************
*** 165,173 ****
       fpregset_t *fpregsetp;
       int regno;
  {
!   /* FIXME: see m68k-tdep.c for an example, for the m68k. */
  }
  
! #endif /* defined (FP0_REGNUM) && defined (HAVE_FPREGSET_T) */
  
  #endif /* HAVE_SYS_PROCFS_H */
--- 213,253 ----
       fpregset_t *fpregsetp;
       int regno;
  {
! #if (NUM_FREGS > 0)
!   int regi;
! 
!   for (regi = FP0_REGNUM; regi <= LAST_FPU_CTRL_REGNUM; regi++)
!     {
!       if ((regno == -1) || (regno == regi))
! 	{
! 	  char *to = (char *) fpregsetp + freg_offset_map[regi - FP0_REGNUM];
! 	  char *from = (char *) &registers[REGISTER_BYTE (regi)];
! 	  ULONGEST valto;
! 	  ULONGEST valfrom;
! 
! 	  if (regi == FCS_REGNUM)
! 	    {
! 	      valto = extract_unsigned_integer (to, 4);
! 	      valfrom = extract_unsigned_integer (from, 4);
! 	      valto = (valto & ~0xffff) | (valfrom & 0xffff);
! 	      store_unsigned_integer (to, 4, valto);
! 	    }
! 	  else if (regi == FOP_REGNUM)
! 	    {
! 	      valto = extract_unsigned_integer (to, 4);
! 	      valfrom = extract_unsigned_integer (from, 4);
! 	      valto = (valto & 0xffff) | ((valfrom & ((1 << 11) - 1)) << 16);
! 	      store_unsigned_integer (to, 4, valto);
! 	    }
! 	  else
! 	    {
! 	      memcpy (to, from, REGISTER_RAW_SIZE (regi));
! 	    }
! 	}
!     }
! #endif
  }
  
! #endif /* defined (HAVE_FPREGSET_T) */
  
  #endif /* HAVE_SYS_PROCFS_H */


*** ./gdb/testsuite/gdb.base/default.exp.orig	Tue Jan 18 01:54:37 2000
--- ./gdb/testsuite/gdb.base/default.exp	Mon Feb 21 08:10:00 2000
***************
*** 304,311 ****
      gdb_test "info float" "Software FPU type.*mask:.*flags:.*" "info float"
  } elseif [istarget "strongarm*-*-*"] then {
      gdb_test "info float" "Software FPU type.*mask:.*flags:.*" "info float"
! } elseif [istarget "i\[3456\]86-*-*"] then {
!     gdb_test "info float" "R7:.*Status Word:.*Opcode:.*" "info float"
  } else {
      gdb_test "info float" "No floating point info available for this processor." "info float"
  }
--- 304,311 ----
      gdb_test "info float" "Software FPU type.*mask:.*flags:.*" "info float"
  } elseif [istarget "strongarm*-*-*"] then {
      gdb_test "info float" "Software FPU type.*mask:.*flags:.*" "info float"
! } elseif [istarget "i*86-*-*"] then {
!     gdb_test "info float" "R7:.*Status Word:.*Opcode:.*|No floating point info available for this processor." "info float"
  } else {
      gdb_test "info float" "No floating point info available for this processor." "info float"
  }

-- 
Peter Schauer			pes@regent.e-technik.tu-muenchen.de


More information about the Gdb-patches mailing list