This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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 libiberty/floatformat.c VAX formats


This patch is to provide the beginnings of VAX floating point support in
floatformat.c - necessary if someone wants to revive VAX support in gdb.
See <http://sources.redhat.com/ml/gdb-patches/2002-01/msg00544.html>.
The other examples may help converting data from tape someday.

By inspection, the routines in floatformat.c can't cope with
floatformat_littlebyte_bigword or floatformat_arm_ext_littlebyte_bigword
or the VAX formats since the floatformat_littlebyte_bigword enum value
isn't referenced in in floatformat.c(get_field, put_field).
Perhaps enum floatformat_byteorders values should be the size in bytes
of the largest datum loaded as a little-endian value (or log2 of it).

Assuming log2
  floatformat_big			= 0,	/* 1 byte, Big Endian */
  floatformat_littlebyte_bighalfword	= 1,	/* 2 bytes as Little Endian */
  floatformat_littlebyte_bigword	= 2,	/* 4 bytes as Little Endian */
  floatformat_little			= 4,	/* 16 bytes as Little Endian */
That should be able to directly drive the byte loads in
floatformat.c:get_field and put_field.
I agree with Andrew about the VAX 11 Architecture reference. The other two
references described the formats in halfwords (16-bit) which made it much
clearer.

NB My corporate assignment is in abeyance at the moment, most of this is
straight out of the references mentioned. The endian test is from autoconf.

2002-01-28  Rodney Brown  <rbrown64@csc.com.au>

	* include/floatformat.h(enum floatformat_byteorders):
	  Add floatformat_littlebyte_bighalfword.
	* libiberty/floatformat.c: Add VAX, HP3000 float formats.
	  (ieee_test, main): Cope with little_endian IEEE (ix86).


--- include/floatformat.h.orig	Tue Aug 21 10:09:07 2001
+++ include/floatformat.h	Wed Jan 23 09:21:03 2002
@@ -45,7 +45,13 @@ enum floatformat_byteorders {
   /* Little endian byte order but big endian word order.
      EX: 1.2345678e10 => e0 fe 06 42 00 00 80 c5 */
 
-  floatformat_littlebyte_bigword
+  floatformat_littlebyte_bigword,
+
+
+  /* Little endian byte order but big endian halfword (16-bit) order.
+     EX: 1.2345678e10 => 06 42 e0 fe 80 c5 00 00 */
+
+  floatformat_littlebyte_bighalfword
 
 };
 
--- libiberty/floatformat.c.orig	Tue Aug 21 10:09:09 2001
+++ libiberty/floatformat.c	Mon Jan 28 14:44:53 2002
@@ -148,6 +148,153 @@ const struct floatformat floatformat_ia6
   floatformat_intbit_no,
   "floatformat_ia64_quad_little"
 };
+
+#ifdef DEC_ARCHAEOLOGY
+/* For VAX Floating point formats,
+   zero is represented by sign bit of zero and an exponent value of zero.
+   A sign bit of 1 and exponent of zero causes a reserved operand fault.
+   This implies exp_nan should be zero (?).
+   The VAX F & D formats are compatible with the PDP-11 formats, which
+   explains the `littlebyte_bighalfword' byte ordering.
+  
+   VAX Architecture Reference Manual, 1987, ISBN 0-932376-86-X
+       pgs 7 .. 9
+   VAX-11 Assembly Language Programming Sara Baase, 1983, ISBN 0-13-940957-2
+       pgs 305 .. 309
+   Alpha Architecture Handbook, 1992, EC-H1689-10 REL# 4/92
+       pgs 2-3 .. p 2-5  */
+   
+const struct floatformat floatformat_vax_F =
+{
+  floatformat_littlebyte_bighalfword, 32, 0, 1, 8, 128, 0, 9, 23,
+  floatformat_intbit_no,
+  "floatformat_vax_F"
+};
+const struct floatformat floatformat_vax_D =
+{
+  floatformat_littlebyte_bighalfword, 64, 0, 1, 8, 128, 0, 9, 55,
+  floatformat_intbit_no,
+  "floatformat_vax_D"
+};
+const struct floatformat floatformat_vax_G =
+{
+  floatformat_littlebyte_bighalfword, 64, 0, 1, 11, 1024, 0, 12, 52,
+  floatformat_intbit_no,
+  "floatformat_vax_G"
+};
+const struct floatformat floatformat_vax_H =
+{
+  floatformat_littlebyte_bighalfword, 128, 0, 1, 15, 16384, 0, 16, 112,
+  floatformat_intbit_no,
+  "floatformat_vax_H"
+};
+#endif	/* DEC_ARCHAEOLOGY */
+#ifdef HP_ARCHAEOLOGY
+/* HP3000 Floating point formats.
+   HP3000 Machine Instruction Set Reference Manual, 1984, 30000-90022
+       pgs 2-98, 3-17, 3-18  */
+
+const struct floatformat floatformat_hp3000_single =
+{
+  floatformat_big, 32, 0, 1, 9, 256, 0, 10, 22,
+  floatformat_intbit_no,
+  "floatformat_hp3000_single"
+};
+const struct floatformat floatformat_hp3000_double =
+{
+  floatformat_big, 64, 0, 1, 9, 256, 0, 10, 54,
+  floatformat_intbit_no,
+  "floatformat_hp3000_double"
+};
+#endif	/* HP_ARCHAEOLOGY */
+
+/* DG ECLIPSE Floating point formats
+   AOS/VS Macroassembler Reference Manual, 1987, 093-000242-02
+       pg 2-13
+
+This 32-bit format can't be represented with the floatformat struct 
+since the exponent is a power of 16 not 2. Otherwise it would be :-
+
+const struct floatformat floatformat_dg_eclipse_single =
+{
+  floatformat_big, 32, 0, 1, 7, 64, 0, 8, 24,
+  floatformat_intbit_yes,
+  "floatformat_dg_eclipse_single"
+};
+
+Non-zero numbers are normalized to have a one in the first 4 bits
+of the mantissa. 
+
+  Burroughs B 6700 / B 7700 ALGOL Language Reference Manual, 1974, 500649
+      pg B-4, B-5, B-7, B-8
+
+This 48-bit format can't be represented with the floatformat struct 
+since the exponent is a power of 8 not 2, Bit 2 is the sign bit for the
+exponent. Integers on the platform are single floating point numbers with
+an exponent of 0.
+Otherwise it would be (maybe) :-
+
+const struct floatformat floatformat_dg_b6700_single =
+{
+  floatformat_big?, 48, 1, 3, 6, 0, 0, 9, 39,
+  floatformat_intbit_yes,
+  "floatformat_dg_b6700_single"
+};
+
+         0.5 => 0x26C000000000   10 => 0x00000000000A
+ 99999999999 => 0x00174876E7FF  -10 => 0x40000000000A
+549755813887 => 0x007FFFFFFFFF
+
+The double precision format uses two 48-bit words to give a 15-bit exponent
++ exponent sign bit and a 78-bit mantissa. The first word is as the
+single precision format, but contains the least significant 6-bits of the
+exponent and the most-significant 39-bits of the mantissa. The second 48-bit
+word has the most significant 9 bits of the exponent (0, 9) and the least
+significant 39-bits of the mantissa (9, 39).
+A number that can be exactly represented in single precision has a second
+48-bit word identically zero in double precision.
+
+0x1D0 => 0x261000000000 0x000000000000  */
+
+/* Digital Portable Mathematics Library, 1996, AA-PV6VC-TE
+       Appendix A, Critical Floating-Point Values pg A1-A2
+
+      Values for max_float
+Type  Hex            Decimal
+F  FFFF7FFF          1.701411e38		32-bit VAX single-precision
+G  FFFFFFFFFFFF7FFF  8.988465674311579e307	64-bit VAX double-precision
+S  7F7FFFFF          3.402823e28		32-bit IEEE single-precision
+T  7FEFFFFFFFFFFFFF  1.797693134862316e308	64-bit IEEE double-precision
+X  7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF		128-bit IEEE extended-precision
+                     1.189731495357231765085759326628007016196477e4932
+
+      Values for min_float
+Type  Hex            Decimal
+F  00000080          2.9387359e-39
+G  0000000000000010  5.562684646268003e-309
+S  00000001          1.4012985e-45
+T  0000000000000001  4.940656458412465e-324
+X  00000000000000000000000000000001
+                     6.4751751194380251109244389582276465524996e-4966
+
+      Values for ln(max_float)
+Type  Hex            Decimal
+F  0F3443B0          88.029692
+G  7B616E3A28B740A6  709.0895657128241
+S  42B17218          88.7228391
+T  40862E42FEFA39EF  709.7827128933840
+X  400C62E42FEFA39EF35793C7673007E6
+                     11356.5234062941439494919310779707648912527
+
+      Values for ln(min_float)
+Type  Hex            Decimal
+F  7218C3B1          -88.72284
+G  39EFFEFA2E42C0A6  -709.7827128933840
+S  C2CE8ED0          -103.2789
+T  C0874385446D71C3  -744.4400719213813
+X  C00C6546282207802C89D24D65E96274
+                     -11432.7695961557379335278266113311643138373
+*/
 
 static unsigned long get_field PARAMS ((unsigned char *,
 					enum floatformat_byteorders,
@@ -413,6 +560,8 @@ floatformat_from_double (fmt, from, to)
 
 #ifdef IEEE_DEBUG
 
+static const struct floatformat *floatformat_ieee_double = NULL;
+
 /* This is to be run on a host which uses IEEE floating point.  */
 
 void
@@ -422,10 +571,10 @@ ieee_test (n)
   double result;
   char exten[16];
 
-  floatformat_to_double (&floatformat_ieee_double_big, &n, &result);
+  floatformat_to_double (floatformat_ieee_double, &n, &result);
   if (n != result)
     printf ("Differ(to): %.20g -> %.20g\n", n, result);
-  floatformat_from_double (&floatformat_ieee_double_big, &n, &result);
+  floatformat_from_double (floatformat_ieee_double, &n, &result);
   if (n != result)
     printf ("Differ(from): %.20g -> %.20g\n", n, result);
 
@@ -447,6 +596,18 @@ ieee_test (n)
 int
 main ()
 {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  floatformat_ieee_double =
+    ((u.c[sizeof (long) - 1] == 1)
+    ? &floatformat_ieee_double_big
+    : &floatformat_ieee_double_little);
+
   ieee_test (0.5);
   ieee_test (256.0);
   ieee_test (0.12345);


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