This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch, libiberty, gdb] IEEE 754 half floating-point format
- From: Ken Werner <ken at linux dot vnet dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 2 Jul 2010 19:11:31 +0200
- Subject: Re: [patch, libiberty, gdb] IEEE 754 half floating-point format
- References: <201007021859.05191.ken@linux.vnet.ibm.com>
On Friday, July 02, 2010 06:59:05 pm Ken Werner wrote:
> Hi,
>
> The attached patch adds the half precision floating-point format as
> described in IEEE 754-2008 as binary16. Languages such as OpenCL and
> architectures like ARM support this representation.
> Any suggestions are welcome.
>
> Regards
> -ken
Whoops, I intended to crosspost this patch on gcc-patches as well because it
touches files within the libiberty and include directory.
Sorry.
Regards
-ken
include/ChangeLog:
2010-07-02 Ken Werner <ken.werner@de.ibm.com>
* gfloatformat.h (floatformat_ieee_half_big): Add declaration.
(floatformat_ieee_half_little): Likewise.
libiberty/ChangeLog:
2010-07-02 Ken Werner <ken.werner@de.ibm.com>
* floatformat.c (floatformat_ieee_half_big): New variable.
(floatformat_ieee_half_little): Likewise.
ChangeLog:
2010-07-02 Ken Werner <ken.werner@de.ibm.com>
* gdbtypes.h (floatformats_ieee_half): Add declaration.
* gdbtypes.c (floatformats_ieee_half): New variable.
* doublest.c (floatformat_from_length): Set format to
gdbarch_half_format if length matches.
* gdbarch.sh (half_bit): New architecture method.
(half_format): Likewise.
* gdbarch.h: Regenerate.
* gdbarch.c: Likewise.
Index: include/floatformat.h
===================================================================
RCS file: /cvs/src/src/include/floatformat.h,v
retrieving revision 1.14
diff -u -p -r1.14 floatformat.h
--- include/floatformat.h 8 Nov 2007 00:08:48 -0000 1.14
+++ include/floatformat.h 2 Jul 2010 15:35:08 -0000
@@ -96,6 +96,8 @@ struct floatformat
/* floatformats for IEEE single and double, big and little endian. */
+extern const struct floatformat floatformat_ieee_half_big;
+extern const struct floatformat floatformat_ieee_half_little;
extern const struct floatformat floatformat_ieee_single_big;
extern const struct floatformat floatformat_ieee_single_little;
extern const struct floatformat floatformat_ieee_double_big;
Index: libiberty/floatformat.c
===================================================================
RCS file: /cvs/src/src/libiberty/floatformat.c,v
retrieving revision 1.25
diff -u -p -r1.25 floatformat.c
--- libiberty/floatformat.c 13 Nov 2007 15:12:42 -0000 1.25
+++ libiberty/floatformat.c 2 Jul 2010 15:35:08 -0000
@@ -77,7 +77,23 @@ floatformat_always_valid (const struct f
a system header, what we do if not, etc. */
#define FLOATFORMAT_CHAR_BIT 8
-/* floatformats for IEEE single and double, big and little endian. */
+/* floatformats for IEEE half, single and double, big and little endian. */
+const struct floatformat floatformat_ieee_half_big =
+{
+ floatformat_big, 16, 0, 1, 5, 15, 31, 6, 10,
+ floatformat_intbit_no,
+ "floatformat_ieee_half_big",
+ floatformat_always_valid,
+ NULL
+};
+const struct floatformat floatformat_ieee_half_little =
+{
+ floatformat_little, 16, 0, 1, 5, 15, 31, 6, 10,
+ floatformat_intbit_no,
+ "floatformat_ieee_half_little",
+ floatformat_always_valid,
+ NULL
+};
const struct floatformat floatformat_ieee_single_big =
{
floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
Index: gdb/gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.132
diff -u -p -r1.132 gdbtypes.h
--- gdb/gdbtypes.h 29 Jun 2010 16:17:58 -0000 1.132
+++ gdb/gdbtypes.h 2 Jul 2010 15:35:08 -0000
@@ -1191,6 +1191,7 @@ extern const struct objfile_type *objfil
/* Explicit floating-point formats. See "floatformat.h". */
+extern const struct floatformat *floatformats_ieee_half[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_ieee_single[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_ieee_double[BFD_ENDIAN_UNKNOWN];
extern const struct floatformat *floatformats_ieee_double_littlebyte_bigword[BFD_ENDIAN_UNKNOWN];
Index: gdb/gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.194
diff -u -p -r1.194 gdbtypes.c
--- gdb/gdbtypes.c 29 Jun 2010 16:53:09 -0000 1.194
+++ gdb/gdbtypes.c 2 Jul 2010 15:35:07 -0000
@@ -42,6 +42,10 @@
/* Floatformat pairs. */
+const struct floatformat *floatformats_ieee_half[BFD_ENDIAN_UNKNOWN] = {
+ &floatformat_ieee_half_big,
+ &floatformat_ieee_half_little
+};
const struct floatformat *floatformats_ieee_single[BFD_ENDIAN_UNKNOWN] = {
&floatformat_ieee_single_big,
&floatformat_ieee_single_little
Index: gdb/doublest.c
===================================================================
RCS file: /cvs/src/src/gdb/doublest.c,v
retrieving revision 1.44
diff -u -p -r1.44 doublest.c
--- gdb/doublest.c 14 May 2010 17:53:16 -0000 1.44
+++ gdb/doublest.c 2 Jul 2010 15:35:05 -0000
@@ -777,7 +777,10 @@ floatformat_from_length (struct gdbarch
{
const struct floatformat *format;
- if (len * TARGET_CHAR_BIT == gdbarch_float_bit (gdbarch))
+ if (len * TARGET_CHAR_BIT == gdbarch_half_bit (gdbarch))
+ format = gdbarch_half_format (gdbarch)
+ [gdbarch_byte_order (gdbarch)];
+ else if (len * TARGET_CHAR_BIT == gdbarch_float_bit (gdbarch))
format = gdbarch_float_format (gdbarch)
[gdbarch_byte_order (gdbarch)];
else if (len * TARGET_CHAR_BIT == gdbarch_double_bit (gdbarch))
Index: gdb/gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.512
diff -u -p -r1.512 gdbarch.sh
--- gdb/gdbarch.sh 26 May 2010 18:19:27 -0000 1.512
+++ gdb/gdbarch.sh 2 Jul 2010 15:35:07 -0000
@@ -363,12 +363,14 @@ v:int:long_bit:::8 * sizeof (long):4*TAR
# machine.
v:int:long_long_bit:::8 * sizeof (LONGEST):2*gdbarch->long_bit::0
-# The ABI default bit-size and format for "float", "double", and "long
-# double". These bit/format pairs should eventually be combined into
-# a single object. For the moment, just initialize them as a pair.
+# The ABI default bit-size and format for "half", "float", "double", and
+# "long double". These bit/format pairs should eventually be combined
+# into a single object. For the moment, just initialize them as a pair.
# Each format describes both the big and little endian layouts (if
# useful).
+v:int:half_bit:::16:2*TARGET_CHAR_BIT::0
+v:const struct floatformat **:half_format:::::floatformats_ieee_half::pformat (gdbarch->half_format)
v:int:float_bit:::8 * sizeof (float):4*TARGET_CHAR_BIT::0
v:const struct floatformat **:float_format:::::floatformats_ieee_single::pformat (gdbarch->float_format)
v:int:double_bit:::8 * sizeof (double):8*TARGET_CHAR_BIT::0
Index: gdb/gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.416
diff -u -p -r1.416 gdbarch.h
--- gdb/gdbarch.h 26 May 2010 18:19:26 -0000 1.416
+++ gdb/gdbarch.h 2 Jul 2010 15:35:06 -0000
@@ -118,12 +118,18 @@ extern void set_gdbarch_long_bit (struct
extern int gdbarch_long_long_bit (struct gdbarch *gdbarch);
extern void set_gdbarch_long_long_bit (struct gdbarch *gdbarch, int long_long_bit);
-/* The ABI default bit-size and format for "float", "double", and "long
- double". These bit/format pairs should eventually be combined into
- a single object. For the moment, just initialize them as a pair.
+/* The ABI default bit-size and format for "half", "float", "double", and
+ "long double". These bit/format pairs should eventually be combined
+ into a single object. For the moment, just initialize them as a pair.
Each format describes both the big and little endian layouts (if
useful). */
+extern int gdbarch_half_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_half_bit (struct gdbarch *gdbarch, int half_bit);
+
+extern const struct floatformat ** gdbarch_half_format (struct gdbarch *gdbarch);
+extern void set_gdbarch_half_format (struct gdbarch *gdbarch, const struct floatformat ** half_format);
+
extern int gdbarch_float_bit (struct gdbarch *gdbarch);
extern void set_gdbarch_float_bit (struct gdbarch *gdbarch, int float_bit);
Index: gdb/gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.468
diff -u -p -r1.468 gdbarch.c
--- gdb/gdbarch.c 26 May 2010 18:19:27 -0000 1.468
+++ gdb/gdbarch.c 2 Jul 2010 15:35:06 -0000
@@ -145,6 +145,8 @@ struct gdbarch
int int_bit;
int long_bit;
int long_long_bit;
+ int half_bit;
+ const struct floatformat ** half_format;
int float_bit;
const struct floatformat ** float_format;
int double_bit;
@@ -293,6 +295,8 @@ struct gdbarch startup_gdbarch =
8 * sizeof (int), /* int_bit */
8 * sizeof (long), /* long_bit */
8 * sizeof (LONGEST), /* long_long_bit */
+ 16, /* half_bit */
+ 0, /* half_format */
8 * sizeof (float), /* float_bit */
0, /* float_format */
8 * sizeof (double), /* double_bit */
@@ -451,6 +455,7 @@ gdbarch_alloc (const struct gdbarch_info
gdbarch->int_bit = 4*TARGET_CHAR_BIT;
gdbarch->long_bit = 4*TARGET_CHAR_BIT;
gdbarch->long_long_bit = 2*gdbarch->long_bit;
+ gdbarch->half_bit = 2*TARGET_CHAR_BIT;
gdbarch->float_bit = 4*TARGET_CHAR_BIT;
gdbarch->double_bit = 8*TARGET_CHAR_BIT;
gdbarch->long_double_bit = 8*TARGET_CHAR_BIT;
@@ -562,6 +567,9 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of int_bit, invalid_p == 0 */
/* Skip verify of long_bit, invalid_p == 0 */
/* Skip verify of long_long_bit, invalid_p == 0 */
+ /* Skip verify of half_bit, invalid_p == 0 */
+ if (gdbarch->half_format == 0)
+ gdbarch->half_format = floatformats_ieee_half;
/* Skip verify of float_bit, invalid_p == 0 */
if (gdbarch->float_format == 0)
gdbarch->float_format = floatformats_ieee_single;
@@ -935,6 +943,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
"gdbarch_dump: get_syscall_number = <%s>\n",
host_address_to_string (gdbarch->get_syscall_number));
fprintf_unfiltered (file,
+ "gdbarch_dump: half_bit = %s\n",
+ plongest (gdbarch->half_bit));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: half_format = %s\n",
+ pformat (gdbarch->half_format));
+ fprintf_unfiltered (file,
"gdbarch_dump: has_dos_based_file_system = %s\n",
plongest (gdbarch->has_dos_based_file_system));
fprintf_unfiltered (file,
@@ -1375,6 +1389,39 @@ set_gdbarch_long_long_bit (struct gdbarc
}
int
+gdbarch_half_bit (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ /* Skip verify of half_bit, invalid_p == 0 */
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_half_bit called\n");
+ return gdbarch->half_bit;
+}
+
+void
+set_gdbarch_half_bit (struct gdbarch *gdbarch,
+ int half_bit)
+{
+ gdbarch->half_bit = half_bit;
+}
+
+const struct floatformat **
+gdbarch_half_format (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_half_format called\n");
+ return gdbarch->half_format;
+}
+
+void
+set_gdbarch_half_format (struct gdbarch *gdbarch,
+ const struct floatformat ** half_format)
+{
+ gdbarch->half_format = half_format;
+}
+
+int
gdbarch_float_bit (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);