This is the mail archive of the gdb-patches@sources.redhat.com 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]

[rfc] Add builtin_type_floatformat_*, better handle FP registers?


Hello,

This, believe it or not, is part of muti-arch :-)

As discussed some time ago, one part of the change is more clearly
separating cooked(frame) and raw(regcache) register values/types.
That in turn means eliminating any remaining excuse to hang onto
macros such as the REGISTER_CONVERT*() macros.  Since one of the must
common uses of REGISTER_CONVERT*() is converting floating-point
registers to/from a raw and fudged type, we finally get to the change
below.  As an additional note this should also make it easier to fix
problems such as the non-portable floating point mess I recently (re?)
discovered in arm-tdep.c.

At present GDB has the builtin types:

	builtin_type_float
	builtin_type_double
	builtin_type_long_double

These correspond to C's ``float'', ``double'' and ``long double'' and
their internal representation is determined by the target ABI.  The
GDBARCH macro's TARGET_FLOAT_BIT / TARGET_FLOAT_FORMAT et.al. are
used when definining and interpreting these builtins.

The change below is a first pass at extending this list so that it
includes the more explicit builtin types:

	builtin_type_floatformat_ieee_single_big
	builtin_type_floatformat_ieee_single_little
	...
	builtin_type_floatformat_i386_ext
	...

these builtin types exactly define a very specific floating point
format (right down to the byte order - yes you're looking at byte
order specific types!).  The intention is for targets to use these to
very exactly specify the type of a cooked registers (frame registers).


This in turn:

	o	eliminates the need to fudge the floating
		point representation of registers

		Previously, a target would pretend
		something like an i386_ext register was
		a host double and then truncate part of
		that registers information.

	o	more correctly define the register's type.
		GUI's and even the CLI can consequently more
		exactly display a registers value.

		Previously, since the register was being
		converted, that converted value as raw
		bytes had no relationship to the registers
		true raw value.

Or to put it another way, it stops GDB telling lies about
floating-point registers and their underlying format.  Stopping a
debugger telling lies is always a good thing :-)

If you're wondering, the idea behind the change isn't new.  The MIPS,
has for some time being using a similar technique to define its GPR
(integer) registers.  It specifies the type using builtin_type_int32
etc instead of the less exact and constantly changing builtin_type_int
etc.

+ 	/* FIXME: cagney/2001-07-25: The assertion (TYPE_LENGTH(T) *
+            TARGET_CHAR_BIT == TYPE_FLOATFORMAT(T)->totalsize) should
+            hold.  Unfortunatly, for at least the i386, this is tricky
+            since it has (floatformat_i387_ext.totalsize == 80) yet at
+            the same time (TARGET_LONG_DOUBLE_BIT == 96).  Ulgh!  The
+            list of pre-defined floatformats needs to be extended to
+            include both 80 and 96 bit variants of the i387 format.  */
+ 
+ 	/* FIXME: cagney/2001-07-25: A TYPE_CODE_FLT, such as
+            builtin_type_float, is constructed using information from
+            both TARGET_FLOAT_BIT and TARGET_FLOAT_FORMAT.  That
+            information is redundant.  The target architecture should
+            instead provide a single definition of the format of
+            builtin_type_float using something like
+            TARGET_FLOAT_FLOATFORMAT.  The existing methods all being
+            made obsolete.  */
+ 
+ 	/* FIXME: cagney/2001-07-25: GDB, for the most part uses
+            extract_floating() and store_floating(), to manipulate raw
+            floating point values.  Those functions identify the
+            required conversion by trying to cross match the raw
+            floating-point value's byte size with the various
+            TARGET_*_FORMAT macros supplied by the target architecture.
+            This process is error-proned at best.  GDB should instead
+            be using extract_floatformat() and store_floatformat()
+            functions that take a ``struct floatformat'' (now part of
+            ``struct type'').  */
+ 
+ 	/* FIXME: cagney/2001-07-25: At present most target
+            architectures identify the type of a floating-point
+            register (REGISTER_VIRTUAL_TYPE()) using
+            TARGET_FLOAT_FORMAT et.al.  Targets should instead
+            explicitly identfy the type of the register using the more
+            exact builtin_type_floatformat_*.  This also eliminates the
+            need to use the almost deprecated REGISTER_CONVIRT*()
+            methods when implementing floating-point register types.  */

Thoughts, comments, suggestions and questions all welcome.  This is
very much a mindset change in how people should expect GDB to
internally handle floating-point registers.

	Andrew
2001-07-25  Andrew Cagney  <ac131313@redhat.com>

	* gdbarch.sh (TARGET_FLOAT_BIT): Make static default 32.
	(TARGET_DOUBLE_BIT, TARGET_LONG_DOUBLE_BIT): Make static default
	64.
	(TARGET_FLOAT_FORMAT): Set static default to
	floatformat_ieee_single_big.
	(TARGET_DOUBLE_FORMAT): Set static default to
 	floatformat_ieee_double_big.
 	(TARGET_LONG_DOUBLE_FORMAT): Set static default to
 	floatformat_ieee_long_double_big.
 
 	* gdbtypes.h (struct type): Add field type_specific.floatformat.
 	(TYPE_FLOATFORMAT): Define.
 	
 	* gdbtypes.c: Include "gdb_assert.h" and "floatformat.h".
 	(build_gdbtypes): Initialize and verify TYPE_FLOATFORMAT for
 	builtin_type_float, builtin_type_double.  Don't verify
 	builtin_type_long_double as it is often floatformat_unknown.
 
 	* gdbtypes.h (builtin_type_floatformat_ieee_single_big)
 	(builtin_type_floatformat_ieee_single_little)
 	(builtin_type_floatformat_ieee_double_big)
 	(builtin_type_floatformat_ieee_double_little)
 	(builtin_type_floatformat_ieee_double_littlebyte_bigword)
 	(builtin_type_floatformat_i387_ext)
 	(builtin_type_floatformat_m68881_ext)
 	(builtin_type_floatformat_i960_ext)
 	(builtin_type_floatformat_m88110_ext)
 	(builtin_type_floatformat_m88110_harris_ext)
 	(builtin_type_floatformat_arm_ext): Declare.
 	* gdbtypes.c (builtin_type_floatformat_ieee_single_big)
 	(builtin_type_floatformat_ieee_single_little)
 	(builtin_type_floatformat_ieee_double_big)
 	(builtin_type_floatformat_ieee_double_little)
 	(builtin_type_floatformat_ieee_double_littlebyte_bigword)
 	(builtin_type_floatformat_i387_ext)
 	(builtin_type_floatformat_m68881_ext)
 	(builtin_type_floatformat_i960_ext)
 	(builtin_type_floatformat_m88110_ext)
 	(builtin_type_floatformat_m88110_harris_ext)
 	(builtin_type_floatformat_arm_ext): Define.
 	(_initialize_gdbtyes): Initialize
 	builtin_type_floatformat_ieee_single_big,
 	builtin_type_floatformat_ieee_single_little,
 	builtin_type_floatformat_ieee_double_big,
 	builtin_type_floatformat_ieee_double_little,
 	builtin_type_floatformat_ieee_double_littlebyte_bigword,
 	builtin_type_floatformat_i387_ext,
 	builtin_type_floatformat_m68881_ext,
 	builtin_type_floatformat_i960_ext,
 	builtin_type_floatformat_m88110_ext,
 	builtin_type_floatformat_m88110_harris_ext and
 	builtin_type_floatformat_arm_ext.
 	(_initialize_gdbtypes): Document why the builtin_type_floatformat
 	variables do not need to be swapped when the architecture changes.
 	
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.73
diff -p -r1.73 gdbarch.sh
*** gdbarch.sh	2001/07/10 21:24:48	1.73
--- gdbarch.sh	2001/07/25 20:48:03
*************** v::TARGET_LONG_BIT:int:long_bit::::8 * s
*** 360,370 ****
  # machine.
  v::TARGET_LONG_LONG_BIT:int:long_long_bit::::8 * sizeof (LONGEST):2*TARGET_LONG_BIT::0
  # Number of bits in a float for the target machine.
! v::TARGET_FLOAT_BIT:int:float_bit::::8 * sizeof (float):4*TARGET_CHAR_BIT::0
  # Number of bits in a double for the target machine.
! v::TARGET_DOUBLE_BIT:int:double_bit::::8 * sizeof (double):8*TARGET_CHAR_BIT::0
  # Number of bits in a long double for the target machine.
! v::TARGET_LONG_DOUBLE_BIT:int:long_double_bit::::8 * sizeof (long double):2*TARGET_DOUBLE_BIT::0
  # For most targets, a pointer on the target and its representation as an
  # address in GDB have the same size and "look the same".  For such a
  # target, you need only set TARGET_PTR_BIT / ptr_bit and TARGET_ADDR_BIT
--- 360,370 ----
  # machine.
  v::TARGET_LONG_LONG_BIT:int:long_long_bit::::8 * sizeof (LONGEST):2*TARGET_LONG_BIT::0
  # Number of bits in a float for the target machine.
! v::TARGET_FLOAT_BIT:int:float_bit::::32:4*TARGET_CHAR_BIT::0
  # Number of bits in a double for the target machine.
! v::TARGET_DOUBLE_BIT:int:double_bit::::64:8*TARGET_CHAR_BIT::0
  # Number of bits in a long double for the target machine.
! v::TARGET_LONG_DOUBLE_BIT:int:long_double_bit::::64:2*TARGET_DOUBLE_BIT::0
  # For most targets, a pointer on the target and its representation as an
  # address in GDB have the same size and "look the same".  For such a
  # target, you need only set TARGET_PTR_BIT / ptr_bit and TARGET_ADDR_BIT
*************** F:2:REG_STRUCT_HAS_ADDR:int:reg_struct_h
*** 512,520 ****
  F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0
  v:2:PARM_BOUNDARY:int:parm_boundary
  #
! v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)
! v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::::default_double_format (gdbarch)
! v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::::&floatformat_unknown
  f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr:addr:::core_addr_identity::0
  # On some machines there are bits in addresses which are not really
  # part of the address, but are used by the kernel, the hardware, etc.
--- 512,520 ----
  F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0
  v:2:PARM_BOUNDARY:int:parm_boundary
  #
! v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::&floatformat_ieee_single_big::default_float_format (gdbarch)
! v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::&floatformat_ieee_double_big::default_double_format (gdbarch)
! v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::&floatformat_ieee_double_big::&floatformat_unknown
  f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr:addr:::core_addr_identity::0
  # On some machines there are bits in addresses which are not really
  # part of the address, but are used by the kernel, the hardware, etc.
Index: gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.23
diff -p -r1.23 gdbtypes.c
*** gdbtypes.c	2001/07/08 20:42:15	1.23
--- gdbtypes.c	2001/07/25 20:48:10
***************
*** 1,5 ****
  /* Support routines for manipulating internal types for GDB.
!    Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
     Free Software Foundation, Inc.
     Contributed by Cygnus Support, using pieces from other GDB modules.
  
--- 1,5 ----
  /* Support routines for manipulating internal types for GDB.
!    Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
     Free Software Foundation, Inc.
     Contributed by Cygnus Support, using pieces from other GDB modules.
  
***************
*** 36,41 ****
--- 36,43 ----
  #include "gdbcmd.h"
  #include "wrapper.h"
  #include "cp-abi.h"
+ #include "gdb_assert.h"
+ #include "floatformat.h"
  
  /* These variables point to the objects
     representing the predefined C data types.  */
*************** struct type *builtin_type_int32;
*** 67,72 ****
--- 69,85 ----
  struct type *builtin_type_uint32;
  struct type *builtin_type_int64;
  struct type *builtin_type_uint64;
+ struct type *builtin_type_floatformat_ieee_single_big;
+ struct type *builtin_type_floatformat_ieee_single_little;
+ struct type *builtin_type_floatformat_ieee_double_big;
+ struct type *builtin_type_floatformat_ieee_double_little;
+ struct type *builtin_type_floatformat_ieee_double_littlebyte_bigword;
+ struct type *builtin_type_floatformat_i387_ext;
+ struct type *builtin_type_floatformat_m68881_ext;
+ struct type *builtin_type_floatformat_i960_ext;
+ struct type *builtin_type_floatformat_m88110_ext;
+ struct type *builtin_type_floatformat_m88110_harris_ext;
+ struct type *builtin_type_floatformat_arm_ext;
  struct type *builtin_type_bool;
  struct type *builtin_type_v4sf;
  struct type *builtin_type_v4si;
*************** build_gdbtypes (void)
*** 2848,2861 ****
--- 2861,2886 ----
      init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
  	       0,
  	       "float", (struct objfile *) NULL);
+   TYPE_FLOATFORMAT (builtin_type_float) = TARGET_FLOAT_FORMAT;
+   gdb_assert (TYPE_LENGTH (builtin_type_float) * TARGET_CHAR_BIT
+ 	      == TYPE_FLOATFORMAT (builtin_type_float)->totalsize);
    builtin_type_double =
      init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
  	       0,
  	       "double", (struct objfile *) NULL);
+   TYPE_FLOATFORMAT (builtin_type_double) = TARGET_DOUBLE_FORMAT;
+   gdb_assert (TYPE_LENGTH (builtin_type_double) * TARGET_CHAR_BIT
+ 	      == TYPE_FLOATFORMAT (builtin_type_double)->totalsize);
    builtin_type_long_double =
      init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
  	       0,
  	       "long double", (struct objfile *) NULL);
+   TYPE_FLOATFORMAT (builtin_type_long_double) = TARGET_LONG_DOUBLE_FORMAT;
+   /* NOTE: TARGET_LONG_DOUBLE_FORMAT can have a default value of
+      floatformat_unknown, take care.  */
+   gdb_assert (TARGET_LONG_DOUBLE_FORMAT == &floatformat_unknown
+ 	      || (TYPE_LENGTH (builtin_type_long_double) * TARGET_CHAR_BIT
+ 		  == TYPE_FLOATFORMAT (builtin_type_long_double)->totalsize));
    builtin_type_complex =
      init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
  	       0,
*************** _initialize_gdbtypes (void)
*** 2977,2982 ****
--- 3002,3099 ----
    struct cmd_list_element *c;
    build_gdbtypes ();
  
+   /* The following types are target architecture (including byte
+      order) independant.  They do not need to be rebuilt everytime the
+      architecture is changed.  */
+   builtin_type_floatformat_ieee_single_big
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_ieee_single_big.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_ieee_single_big",
+ 		 (struct objfile *) NULL);
+   TYPE_FLOATFORMAT(builtin_type_floatformat_ieee_single_big)
+     = &floatformat_ieee_single_big;
+   builtin_type_floatformat_ieee_single_little
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_ieee_single_little.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_ieee_single_little",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_ieee_single_little)
+     = &floatformat_ieee_single_little;
+   builtin_type_floatformat_ieee_double_big
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_ieee_double_big.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_ieee_double_big",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_ieee_double_big)
+     = &floatformat_ieee_double_big;
+   builtin_type_floatformat_ieee_double_little
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_ieee_double_little.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_ieee_double_little",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_ieee_double_little)
+     = &floatformat_ieee_double_little;
+   builtin_type_floatformat_ieee_double_littlebyte_bigword
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_ieee_double_littlebyte_bigword.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_ieee_double_littlebyte_bigword",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_ieee_double_littlebyte_bigword)
+     = &floatformat_ieee_double_littlebyte_bigword;
+   builtin_type_floatformat_i387_ext
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_i387_ext.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_i387_ext",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_i387_ext)
+     = &floatformat_i387_ext;
+   builtin_type_floatformat_m68881_ext
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_m68881_ext.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_m68881_ext",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_m68881_ext)
+     = &floatformat_m68881_ext;
+   builtin_type_floatformat_i960_ext
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_i960_ext.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_i960_ext",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_i960_ext)
+     = &floatformat_i960_ext;
+   builtin_type_floatformat_m88110_ext
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_m88110_ext.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_m88110_ext",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_m88110_ext)
+     = &floatformat_m88110_ext;
+   builtin_type_floatformat_m88110_harris_ext
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_m88110_harris_ext.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_m88110_harris_ext",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_m88110_harris_ext)
+     = &floatformat_m88110_harris_ext;
+   builtin_type_floatformat_arm_ext
+     = init_type (TYPE_CODE_FLT,
+ 		 floatformat_arm_ext.totalsize / TARGET_CHAR_BIT,
+ 		 0,
+ 		 "__builtin_type_floatformat_arm_ext",
+ 		 NULL);
+   TYPE_FLOATFORMAT (builtin_type_floatformat_arm_ext)
+     = &floatformat_arm_ext;
+ 
    /* FIXME - For the moment, handle types by swapping them in and out.
       Should be using the per-architecture data-pointer and a large
       struct. */
*************** _initialize_gdbtypes (void)
*** 3006,3011 ****
--- 3123,3132 ----
    register_gdbarch_swap (&builtin_type_uint32, sizeof (struct type *), NULL);
    register_gdbarch_swap (&builtin_type_int64, sizeof (struct type *), NULL);
    register_gdbarch_swap (&builtin_type_uint64, sizeof (struct type *), NULL);
+   /* NOTE: The builtin_type_floatformat variables do not need to be
+      swapped (i.e rebuilt) every time the architecture changes.  They
+      are host/target independant - they do not have byte order
+      problems.  */
    register_gdbarch_swap (&builtin_type_v4sf, sizeof (struct type *), NULL);
    register_gdbarch_swap (&builtin_type_v4si, sizeof (struct type *), NULL);
    register_gdbarch_swap (&builtin_type_v8qi, sizeof (struct type *), NULL);
Index: gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.11
diff -p -r1.11 gdbtypes.h
*** gdbtypes.h	2001/07/08 20:42:15	1.11
--- gdbtypes.h	2001/07/25 20:48:13
*************** struct type
*** 390,396 ****
  
      int vptr_fieldno;
  
!     /* Slot to point to additional language-specific fields of this type.  */
  
      union type_specific
        {
--- 390,397 ----
  
      int vptr_fieldno;
  
!     /* Slot to point to additional language-specific fields of this
!        type.  */
  
      union type_specific
        {
*************** struct type
*** 409,414 ****
--- 410,457 ----
  
  	struct cplus_struct_type *cplus_stuff;
  
+ 	/* FLOATFORMAT is for TYPE_CODE_FLT.  It is a pointer to the
+            floatformat object that more exactly describes the
+            floating-point number of size LENGTH.  */
+ 
+ 	/* FIXME: cagney/2001-07-25: The assertion (TYPE_LENGTH(T) *
+            TARGET_CHAR_BIT == TYPE_FLOATFORMAT(T)->totalsize) should
+            hold.  Unfortunatly, for at least the i386, this is tricky
+            since it has (floatformat_i387_ext.totalsize == 80) yet at
+            the same time (TARGET_LONG_DOUBLE_BIT == 96).  Ulgh!  The
+            list of pre-defined floatformats needs to be extended to
+            include both 80 and 96 bit variants of the i387 format.  */
+ 
+ 	/* FIXME: cagney/2001-07-25: A TYPE_CODE_FLT, such as
+            builtin_type_float, is constructed using information from
+            both TARGET_FLOAT_BIT and TARGET_FLOAT_FORMAT.  That
+            information is redundant.  The target architecture should
+            instead provide a single definition of the format of
+            builtin_type_float using something like
+            TARGET_FLOAT_FLOATFORMAT.  The existing methods all being
+            made obsolete.  */
+ 
+ 	/* FIXME: cagney/2001-07-25: GDB, for the most part uses
+            extract_floating() and store_floating(), to manipulate raw
+            floating point values.  Those functions identify the
+            required conversion by trying to cross match the raw
+            floating-point value's byte size with the various
+            TARGET_*_FORMAT macros supplied by the target architecture.
+            This process is error-proned at best.  GDB should instead
+            be using extract_floatformat() and store_floatformat()
+            functions that take a ``struct floatformat'' (now part of
+            ``struct type'').  */
+ 
+ 	/* FIXME: cagney/2001-07-25: At present most target
+            architectures identify the type of a floating-point
+            register (REGISTER_VIRTUAL_TYPE()) using
+            TARGET_FLOAT_FORMAT et.al.  Targets should instead
+            explicitly identfy the type of the register using the more
+            exact builtin_type_floatformat_*.  This also eliminates the
+            need to use the almost deprecated REGISTER_CONVIRT*()
+            methods when implementing floating-point register types.  */
+ 
+ 	const struct floatformat *floatformat;
        }
      type_specific;
    };
*************** extern void allocate_cplus_struct_type (
*** 718,723 ****
--- 761,769 ----
  #define	TYPE_TYPE_SPECIFIC(thistype) (thistype)->type_specific
  #define TYPE_ARG_TYPES(thistype) (thistype)->type_specific.arg_types
  #define TYPE_CPLUS_SPECIFIC(thistype) (thistype)->type_specific.cplus_stuff
+ /* FIXME: cagney/2001-07-25: Add assertion check that (TYPE_CODE(T) ==
+    TYPE_CODE_FLT).  Ditto for other type_specific fields above.  */
+ #define TYPE_FLOATFORMAT(thistype) (thistype)->type_specific.floatformat
  #define TYPE_BASECLASS(thistype,index) (thistype)->fields[index].type
  #define TYPE_N_BASECLASSES(thistype) TYPE_CPLUS_SPECIFIC(thistype)->n_baseclasses
  #define TYPE_BASECLASS_NAME(thistype,index) (thistype)->fields[index].name
*************** extern struct type *builtin_type_int32;
*** 876,881 ****
--- 922,941 ----
  extern struct type *builtin_type_uint32;
  extern struct type *builtin_type_int64;
  extern struct type *builtin_type_uint64;
+ 
+ /* Floating point types with explicit size and byte layout (NOTE: That
+    includes the raw byte order).  See floatformat.h for naming scheme.  */
+ extern struct type *builtin_type_floatformat_ieee_single_big;
+ extern struct type *builtin_type_floatformat_ieee_single_little;
+ extern struct type *builtin_type_floatformat_ieee_double_big;
+ extern struct type *builtin_type_floatformat_ieee_double_little;
+ extern struct type *builtin_type_floatformat_ieee_double_littlebyte_bigword;
+ extern struct type *builtin_type_floatformat_i387_ext;
+ extern struct type *builtin_type_floatformat_m68881_ext;
+ extern struct type *builtin_type_floatformat_i960_ext;
+ extern struct type *builtin_type_floatformat_m88110_ext;
+ extern struct type *builtin_type_floatformat_m88110_harris_ext;
+ extern struct type *builtin_type_floatformat_arm_ext;
  
  /* SIMD types.  We inherit these names from GCC.  */
  extern struct type *builtin_type_v4sf;

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