]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Add bfloat16 support for AVX512 register view.
authorFelix Willgerodt <felix.willgerodt@intel.com>
Thu, 10 Sep 2020 12:29:53 +0000 (14:29 +0200)
committerKevin Buettner <kevinb@redhat.com>
Fri, 11 Sep 2020 18:42:47 +0000 (11:42 -0700)
This adds support for the bfloat16 datatype, which can be seen as a short
version of FP32, skipping the least significant 16 bits of the mantissa.
Since the datatype is currently only supported by the AVX512 registers,
the printing of bfloat16 values is only supported for xmm, ymm and zmm
registers.

gdb/ChangeLog:
2020-09-11  Moritz Riesterer  <moritz.riesterer@intel.com>
    Felix Willgerodt  <Felix.Willgerodt@intel.com>

* gdbarch.sh: Added bfloat16 type.
* gdbarch.c: Regenerated.
* gdbarch.h: Regenerated.
* gdbtypes.c (floatformats_bfloat16): New struct.
(gdbtypes_post_init): Add builtin_bfloat16.
* gdbtypes.h (struct builtin_type) <builtin_bfloat16>: New member.
(floatformats_bfloat16): New struct.
* i386-tdep.c (i386_zmm_type): Add field "v32_bfloat16"
(i386_ymm_type): Add field "v16_bfloat16"
(i386_gdbarch_init): Add set_gdbarch_bfloat16_format.
* target-descriptions.c (make_gdb_type): Add case TDESC_TYPE_BFLOAT16.
* gdbsupport/tdesc.cc (tdesc_predefined_types): New member bfloat16.
* gdbsupport/tdesc.h (tdesc_type_kind): New member TDESC_TYPE_BFLOAT16.
* features/i386/64bit-avx512.xml: Add bfloat16 type.
* features/i386/64bit-avx512.c: Regenerated.
* features/i386/64bit-sse.xml: Add bfloat16 type.
* features/i386/64bit-sse.c: Regenerated.

gdb/testsuite/ChangeLog:
2020-09-11  Moritz Riesterer  <moritz.riesterer@intel.com>
    Felix Willgerodt  <Felix.Willgerodt@intel.com>

* x86-avx512bf16.c: New file.
* x86-avx512bf16.exp: Likewise.
* lib/gdb.exp (skip_avx512bf16_tests): New function.

18 files changed:
gdb/ChangeLog
gdb/features/i386/64bit-avx512.c
gdb/features/i386/64bit-avx512.xml
gdb/features/i386/64bit-sse.c
gdb/features/i386/64bit-sse.xml
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/gdbtypes.c
gdb/gdbtypes.h
gdb/i386-tdep.c
gdb/target-descriptions.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.arch/x86-avx512bf16.c [new file with mode: 0644]
gdb/testsuite/gdb.arch/x86-avx512bf16.exp [new file with mode: 0644]
gdb/testsuite/lib/gdb.exp
gdbsupport/tdesc.cc
gdbsupport/tdesc.h

index b3e3d5911a77d3eb9e772a7d4a0266ee1c77a9aa..6b1563a111ed3ae41dc3aac2ea03e17574e5997d 100644 (file)
@@ -1,3 +1,24 @@
+2020-09-11  Moritz Riesterer  <moritz.riesterer@intel.com>
+           Felix Willgerodt  <Felix.Willgerodt@intel.com>
+
+       * gdbarch.sh: Added bfloat16 type.
+       * gdbarch.c: Regenerated.
+       * gdbarch.h: Regenerated.
+       * gdbtypes.c (floatformats_bfloat16): New struct.
+       (gdbtypes_post_init): Add builtin_bfloat16.
+       * gdbtypes.h (struct builtin_type) <builtin_bfloat16>: New member.
+       (floatformats_bfloat16): New struct.
+       * i386-tdep.c (i386_zmm_type): Add field "v32_bfloat16"
+       (i386_ymm_type): Add field "v16_bfloat16"
+       (i386_gdbarch_init): Add set_gdbarch_bfloat16_format.
+       * target-descriptions.c (make_gdb_type): Add case TDESC_TYPE_BFLOAT16.
+       * gdbsupport/tdesc.cc (tdesc_predefined_types): New member bfloat16.
+       * gdbsupport/tdesc.h (tdesc_type_kind): New member TDESC_TYPE_BFLOAT16.
+       * features/i386/64bit-avx512.xml: Add bfloat16 type.
+       * features/i386/64bit-avx512.c: Regenerated.
+       * features/i386/64bit-sse.xml: Add bfloat16 type.
+       * features/i386/64bit-sse.c: Regenerated.
+
 2020-09-11  Felix Willgerodt  <felix.willgerodt@intel.com>
 
        * i386-tdep.c (i386_zmm_type): Fix field names.
index d12234c41ce109489cae0df0fd3a3842379af0c0..1bd49dcd9d5a27705de5c61755fe8322ec981ff2 100644 (file)
@@ -10,6 +10,9 @@ create_feature_i386_64bit_avx512 (struct target_desc *result, long regnum)
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx512");
   tdesc_type *element_type;
+  element_type = tdesc_named_type (feature, "bfloat16");
+  tdesc_create_vector (feature, "v8bf16", element_type, 8);
+
   element_type = tdesc_named_type (feature, "ieee_single");
   tdesc_create_vector (feature, "v4f", element_type, 4);
 
@@ -31,6 +34,8 @@ create_feature_i386_64bit_avx512 (struct target_desc *result, long regnum)
   tdesc_type_with_fields *type_with_fields;
   type_with_fields = tdesc_create_union (feature, "vec128");
   tdesc_type *field_type;
+  field_type = tdesc_named_type (feature, "v8bf16");
+  tdesc_add_field (type_with_fields, "v8_bfloat16", field_type);
   field_type = tdesc_named_type (feature, "v4f");
   tdesc_add_field (type_with_fields, "v4_float", field_type);
   field_type = tdesc_named_type (feature, "v2d");
index 4f02136533d0d71d94abeaaca5599bd60758b482..3636121e8473b4813aab0b668cccf85164ce3711 100644 (file)
@@ -7,13 +7,15 @@
 
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
 <feature name="org.gnu.gdb.i386.avx512">
-<vector id="v4f" type="ieee_single" count="4"/>
+  <vector id="v8bf16" type="bfloat16" count="8"/>
+  <vector id="v4f" type="ieee_single" count="4"/>
   <vector id="v2d" type="ieee_double" count="2"/>
   <vector id="v16i8" type="int8" count="16"/>
   <vector id="v8i16" type="int16" count="8"/>
   <vector id="v4i32" type="int32" count="4"/>
   <vector id="v2i64" type="int64" count="2"/>
   <union id="vec128">
+    <field name="v8_bfloat16" type="v8bf16"/>
     <field name="v4_float" type="v4f"/>
     <field name="v2_double" type="v2d"/>
     <field name="v16_int8" type="v16i8"/>
index 48b5aa097938a5a9941d91ccd00ed45eaefaa6c1..645e31413376539f6f81f61a6b038f524c502a6c 100644 (file)
@@ -10,6 +10,9 @@ create_feature_i386_64bit_sse (struct target_desc *result, long regnum)
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse");
   tdesc_type *element_type;
+  element_type = tdesc_named_type (feature, "bfloat16");
+  tdesc_create_vector (feature, "v8bf16", element_type, 8);
+
   element_type = tdesc_named_type (feature, "ieee_single");
   tdesc_create_vector (feature, "v4f", element_type, 4);
 
@@ -31,6 +34,8 @@ create_feature_i386_64bit_sse (struct target_desc *result, long regnum)
   tdesc_type_with_fields *type_with_fields;
   type_with_fields = tdesc_create_union (feature, "vec128");
   tdesc_type *field_type;
+  field_type = tdesc_named_type (feature, "v8bf16");
+  tdesc_add_field (type_with_fields, "v8_bfloat16", field_type);
   field_type = tdesc_named_type (feature, "v4f");
   tdesc_add_field (type_with_fields, "v4_float", field_type);
   field_type = tdesc_named_type (feature, "v2d");
index 4ec1e7c1e36542b591f9a5990324afcf34d71045..e3dec544cf4c9d85b869d0489d4edd5e40c75859 100644 (file)
@@ -7,6 +7,7 @@
 
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
 <feature name="org.gnu.gdb.i386.sse">
+  <vector id="v8bf16" type="bfloat16" count="8"/>
   <vector id="v4f" type="ieee_single" count="4"/>
   <vector id="v2d" type="ieee_double" count="2"/>
   <vector id="v16i8" type="int8" count="16"/>
@@ -14,6 +15,7 @@
   <vector id="v4i32" type="int32" count="4"/>
   <vector id="v2i64" type="int64" count="2"/>
   <union id="vec128">
+    <field name="v8_bfloat16" type="v8bf16"/>
     <field name="v4_float" type="v4f"/>
     <field name="v2_double" type="v2d"/>
     <field name="v16_int8" type="v16i8"/>
index f8fe03ca6820f9931f4b56ddab610731bf3f497f..062c86bd54aed5b6f57b0cb82913897796931275 100644 (file)
@@ -166,6 +166,8 @@ struct gdbarch
   int int_bit;
   int long_bit;
   int long_long_bit;
+  int bfloat16_bit;
+  const struct floatformat ** bfloat16_format;
   int half_bit;
   const struct floatformat ** half_format;
   int float_bit;
@@ -383,6 +385,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
   gdbarch->int_bit = 4*TARGET_CHAR_BIT;
   gdbarch->long_bit = 4*TARGET_CHAR_BIT;
   gdbarch->long_long_bit = 2*gdbarch->long_bit;
+  gdbarch->bfloat16_bit = 2*TARGET_CHAR_BIT;
   gdbarch->half_bit = 2*TARGET_CHAR_BIT;
   gdbarch->float_bit = 4*TARGET_CHAR_BIT;
   gdbarch->double_bit = 8*TARGET_CHAR_BIT;
@@ -523,6 +526,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 bfloat16_bit, invalid_p == 0 */
+  if (gdbarch->bfloat16_format == 0)
+    gdbarch->bfloat16_format = floatformats_bfloat16;
   /* Skip verify of half_bit, invalid_p == 0 */
   if (gdbarch->half_format == 0)
     gdbarch->half_format = floatformats_ieee_half;
@@ -807,6 +813,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                       "gdbarch_dump: bfd_arch_info = %s\n",
                       gdbarch_bfd_arch_info (gdbarch)->printable_name);
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: bfloat16_bit = %s\n",
+                      plongest (gdbarch->bfloat16_bit));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: bfloat16_format = %s\n",
+                      pformat (gdbarch->bfloat16_format));
   fprintf_unfiltered (file,
                       "gdbarch_dump: breakpoint_from_pc = <%s>\n",
                       host_address_to_string (gdbarch->breakpoint_from_pc));
@@ -1620,6 +1632,39 @@ set_gdbarch_long_long_bit (struct gdbarch *gdbarch,
   gdbarch->long_long_bit = long_long_bit;
 }
 
+int
+gdbarch_bfloat16_bit (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  /* Skip verify of bfloat16_bit, invalid_p == 0 */
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_bfloat16_bit called\n");
+  return gdbarch->bfloat16_bit;
+}
+
+void
+set_gdbarch_bfloat16_bit (struct gdbarch *gdbarch,
+                          int bfloat16_bit)
+{
+  gdbarch->bfloat16_bit = bfloat16_bit;
+}
+
+const struct floatformat **
+gdbarch_bfloat16_format (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_bfloat16_format called\n");
+  return gdbarch->bfloat16_format;
+}
+
+void
+set_gdbarch_bfloat16_format (struct gdbarch *gdbarch,
+                             const struct floatformat ** bfloat16_format)
+{
+  gdbarch->bfloat16_format = bfloat16_format;
+}
+
 int
 gdbarch_half_bit (struct gdbarch *gdbarch)
 {
index 7a3060e628d2aaf8fa3254aad262c383e3c80b0a..87e55fa72b9ec2680ae2ef727e9712e675cc0565 100644 (file)
@@ -158,12 +158,18 @@ extern void set_gdbarch_long_bit (struct gdbarch *gdbarch, int long_bit);
 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 "half", "float", "double", and
+/* The ABI default bit-size and format for "bfloat16", "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_bfloat16_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_bfloat16_bit (struct gdbarch *gdbarch, int bfloat16_bit);
+
+extern const struct floatformat ** gdbarch_bfloat16_format (struct gdbarch *gdbarch);
+extern void set_gdbarch_bfloat16_format (struct gdbarch *gdbarch, const struct floatformat ** bfloat16_format);
+
 extern int gdbarch_half_bit (struct gdbarch *gdbarch);
 extern void set_gdbarch_half_bit (struct gdbarch *gdbarch, int half_bit);
 
index 6d3c5c889d6946fd867df16d9b7ddb42417cced5..8d221601b762761c5f39e922363c8e3dc1c6739a 100755 (executable)
@@ -325,12 +325,14 @@ v;int;long_bit;;;8 * sizeof (long);4*TARGET_CHAR_BIT;;0
 # machine.
 v;int;long_long_bit;;;8 * sizeof (LONGEST);2*gdbarch->long_bit;;0
 
-# The ABI default bit-size and format for "half", "float", "double", and
+# The ABI default bit-size and format for "bfloat16", "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;bfloat16_bit;;;16;2*TARGET_CHAR_BIT;;0
+v;const struct floatformat **;bfloat16_format;;;;;floatformats_bfloat16;;pformat (gdbarch->bfloat16_format)
 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
index ab44ec3bc00a30775542a4060d9e04e3cbb93940..b7c8ec8e6432bccccbe27f8c24f885e5a349e0a6 100644 (file)
@@ -115,6 +115,10 @@ const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN] = {
   &floatformat_ibm_long_double_big,
   &floatformat_ibm_long_double_little
 };
+const struct floatformat *floatformats_bfloat16[BFD_ENDIAN_UNKNOWN] = {
+  &floatformat_bfloat16_big,
+  &floatformat_bfloat16_little
+};
 
 /* Should opaque types be resolved?  */
 
@@ -5760,6 +5764,9 @@ gdbtypes_post_init (struct gdbarch *gdbarch)
   builtin_type->builtin_float
     = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
                       "float", gdbarch_float_format (gdbarch));
+  builtin_type->builtin_bfloat16
+    = arch_float_type (gdbarch, gdbarch_bfloat16_bit (gdbarch),
+                      "bfloat16", gdbarch_bfloat16_format (gdbarch));
   builtin_type->builtin_double
     = arch_float_type (gdbarch, gdbarch_double_bit (gdbarch),
                       "double", gdbarch_double_format (gdbarch));
index b02f6674bf5a83172239f216460d99af11e187e1..9c2059d40c05385b91b521485ce9faea7c848314 100644 (file)
@@ -1847,6 +1847,7 @@ struct builtin_type
   struct type *builtin_unsigned_short;
   struct type *builtin_unsigned_int;
   struct type *builtin_unsigned_long;
+  struct type *builtin_bfloat16;
   struct type *builtin_half;
   struct type *builtin_float;
   struct type *builtin_double;
@@ -1981,7 +1982,7 @@ extern const struct floatformat *floatformats_ia64_quad[BFD_ENDIAN_UNKNOWN];
 extern const struct floatformat *floatformats_vax_f[BFD_ENDIAN_UNKNOWN];
 extern const struct floatformat *floatformats_vax_d[BFD_ENDIAN_UNKNOWN];
 extern const struct floatformat *floatformats_ibm_long_double[BFD_ENDIAN_UNKNOWN];
-
+extern const struct floatformat *floatformats_bfloat16[BFD_ENDIAN_UNKNOWN];
 
 /* Allocate space for storing data associated with a particular
    type.  We ensure that the space is allocated using the same
index 322d2a4b69c0f53c885abddcda09c3a1175b4f78..1b7971c4528bb16bd5c25f3a1bd125c674529ed4 100644 (file)
@@ -3112,6 +3112,7 @@ i386_zmm_type (struct gdbarch *gdbarch)
        int8_t v64_int8[64];
        double v8_double[8];
        float v16_float[16];
+       bfloat16_t v32_bfloat16[32];
       };
 #endif
 
@@ -3119,6 +3120,8 @@ i386_zmm_type (struct gdbarch *gdbarch)
 
       t = arch_composite_type (gdbarch,
                               "__gdb_builtin_type_vec512i", TYPE_CODE_UNION);
+      append_composite_type_field (t, "v32_bfloat16",
+                                  init_vector_type (bt->builtin_bfloat16, 32));
       append_composite_type_field (t, "v16_float",
                                   init_vector_type (bt->builtin_float, 16));
       append_composite_type_field (t, "v8_double",
@@ -3165,6 +3168,7 @@ i386_ymm_type (struct gdbarch *gdbarch)
         int8_t v32_int8[32];
         double v4_double[4];
         float v8_float[8];
+        bfloat16_t v16_bfloat16[16];
       };
 #endif
 
@@ -3172,6 +3176,8 @@ i386_ymm_type (struct gdbarch *gdbarch)
 
       t = arch_composite_type (gdbarch,
                               "__gdb_builtin_type_vec256i", TYPE_CODE_UNION);
+      append_composite_type_field (t, "v16_bfloat16",
+                                  init_vector_type (bt->builtin_bfloat16, 16));
       append_composite_type_field (t, "v8_float",
                                   init_vector_type (bt->builtin_float, 8));
       append_composite_type_field (t, "v4_double",
@@ -8487,6 +8493,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      alignment.  */
   set_gdbarch_long_double_bit (gdbarch, 96);
 
+  /* Support of bfloat16 format.  */
+  set_gdbarch_bfloat16_format (gdbarch, floatformats_bfloat16);
+
   /* Support for floating-point data type variants.  */
   set_gdbarch_floatformat_for_type (gdbarch, i386_floatformat_for_type);
 
index 20d624c0c6524e76dbd51082ef2f2100eb19e8b6..6778b93400b80eb63a1168a2ce47ef0ce411cb6f 100644 (file)
@@ -141,6 +141,11 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
          m_type = arch_float_type (m_gdbarch, -1, "builtin_type_i387_ext",
                                    floatformats_i387_ext);
          return;
+
+       case TDESC_TYPE_BFLOAT16:
+         m_type = arch_float_type (m_gdbarch, -1, "builtin_type_bfloat16",
+                                   floatformats_bfloat16);
+         return;
        }
 
       internal_error (__FILE__, __LINE__,
index 6b2055daf3148fcd5b427709c3119262813c525b..9b150b656b2d1417a7729315904c1a6e55c840a0 100644 (file)
@@ -1,3 +1,10 @@
+2020-09-11  Moritz Riesterer  <moritz.riesterer@intel.com>
+           Felix Willgerodt  <Felix.Willgerodt@intel.com>
+
+       * x86-avx512bf16.c: New file.
+       * x86-avx512bf16.exp: Likewise.
+       * lib/gdb.exp (skip_avx512bf16_tests): New function.
+
 2020-09-11  Tom de Vries  <tdevries@suse.de>
 
        PR exp/26602
diff --git a/gdb/testsuite/gdb.arch/x86-avx512bf16.c b/gdb/testsuite/gdb.arch/x86-avx512bf16.c
new file mode 100644 (file)
index 0000000..615cd12
--- /dev/null
@@ -0,0 +1,164 @@
+/* Test program for bfloat16 of AVX 512 registers.
+
+   Copyright 2020 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+typedef struct
+{
+  float f[4];
+} v4sd_t;
+
+typedef struct
+{
+  float f[8];
+} v8sd_t;
+
+typedef struct
+{
+  float f[16];
+} v16sd_t;
+
+v4sd_t xmm_data[] =
+{
+  { {  0.0,  0.125,  0.25,  0.375 } },
+  { {  0.5,  0.625,  0.75,  0.875 } },
+  { {  1.0,  1.125,  1.25,  1.375 } },
+  { {  1.5,  1.625,  1.75,  1.875 } },
+  { {  2.0,  2.125,  2.25,  2.375 } },
+  { {  2.5,  2.625,  2.75,  2.875 } },
+  { {  3.0,  3.125,  3.25,  3.375 } },
+  { {  3.5,  3.625,  3.75,  3.875 } },
+};
+
+v8sd_t ymm_data[] =
+{
+  { {  8.0,  8.25,  8.5,  8.75,  9.0,  9.25,  9.5,  9.75 } },
+  { { 10.0, 10.25, 10.5, 10.75, 11.0, 11.25, 11.5, 11.75 } },
+  { { 12.0, 12.25, 12.5, 12.75, 13.0, 13.25, 13.5, 13.75 } },
+  { { 14.0, 14.25, 14.5, 14.75, 15.0, 15.25, 15.5, 15.75 } },
+  { { 16.0, 16.25, 16.5, 16.75, 17.0, 17.25, 17.5, 17.75 } },
+  { { 18.0, 18.25, 18.5, 18.75, 19.0, 19.25, 19.5, 19.75 } },
+  { { 20.0, 20.25, 20.5, 20.75, 21.0, 21.25, 21.5, 21.75 } },
+  { { 22.0, 22.25, 22.5, 22.75, 23.0, 23.25, 23.5, 23.75 } },
+};
+
+v16sd_t zmm_data[] =
+{
+  { { 20.0,  20.5,  21.0,  21.5,  22.0,  22.5,  23.0,  23.5,  24.0,  24.5,
+      25.0,  25.5,  26.0,  26.5,  27.0,  27.5 } },
+  { { 28.0,  28.5,  29.0,  29.5,  30.0,  30.5,  31.0,  31.5,  32.0,  32.5,
+      33.0,  33.5,  34.0,  34.5,  35.0,  35.5 } },
+  { { 36.0,  36.5,  37.0,  37.5,  38.0,  38.5,  39.0,  39.5,  40.0,  40.5,
+      41.0,  41.5,  42.0,  42.5,  43.0,  43.5 } },
+  { { 44.0,  44.5,  45.0,  45.5,  46.0,  46.5,  47.0,  47.5,  48.0,  48.5,
+      49.0,  49.5,  50.0,  50.5,  51.0,  51.5 } },
+  { { 52.0,  52.5,  53.0,  53.5,  54.0,  54.5,  55.0,  55.5,  56.0,  56.5,
+      57.0,  57.5,  58.0,  58.5,  59.0,  59.5 } },
+  { { 60.0,  60.5,  61.0,  61.5,  62.0,  62.5,  63.0,  63.5,  64.0,  64.5,
+      65.0,  65.5,  66.0,  66.5,  67.0,  67.5 } },
+  { { 68.0,  68.5,  69.0,  69.5,  70.0,  70.5,  71.0,  71.5,  72.0,  72.5,
+      73.0,  73.5,  74.0,  74.5,  75.0,  75.5 } },
+  { { 76.0,  76.5,  77.0,  77.5,  78.0,  78.5,  79.0,  79.5,  80.0,  80.5,
+      81.0,  81.5,  82.0,  82.5,  83.0,  83.5 } },
+};
+
+void
+move_data_to_xmm_reg (void)
+{
+  asm ("vmovups 0(%0), %%xmm0 \n\t"
+       "vmovups 16(%0), %%xmm1 \n\t"
+       "vmovups 32(%0), %%xmm2 \n\t"
+       "vmovups 48(%0), %%xmm3 \n\t"
+       "vmovups 64(%0), %%xmm4 \n\t"
+       "vmovups 80(%0), %%xmm5 \n\t"
+       "vmovups 96(%0), %%xmm6 \n\t"
+       "vmovups 112(%0), %%xmm7 \n\t"
+       : /* no output operands  */
+       : "r" (xmm_data));
+}
+
+void
+move_data_to_ymm_reg (void)
+{
+  asm ("vmovups 0(%0), %%ymm0 \n\t"
+       "vmovups 32(%0), %%ymm1 \n\t"
+       "vmovups 64(%0), %%ymm2 \n\t"
+       "vmovups 96(%0), %%ymm3 \n\t"
+       "vmovups 128(%0), %%ymm4 \n\t"
+       "vmovups 160(%0), %%ymm5 \n\t"
+       "vmovups 192(%0), %%ymm6 \n\t"
+       "vmovups 224(%0), %%ymm7 \n\t"
+       : /* no output operands  */
+       : "r" (ymm_data));
+}
+
+void
+move_data_to_zmm_reg (void)
+{
+  asm ("vmovups 0(%0), %%zmm0 \n\t"
+       "vmovups 64(%0), %%zmm1 \n\t"
+       "vmovups 128(%0), %%zmm2 \n\t"
+       "vmovups 192(%0), %%zmm3 \n\t"
+       "vmovups 256(%0), %%zmm4 \n\t"
+       "vmovups 320(%0), %%zmm5 \n\t"
+       "vmovups 384(%0), %%zmm6 \n\t"
+       "vmovups 448(%0), %%zmm7 \n\t"
+       : /* no output operands  */
+       : "r" (zmm_data));
+}
+
+void
+convert_xmm_from_float_to_bfloat16 (void)
+{
+  asm("vcvtne2ps2bf16 %xmm0, %xmm1, %xmm0");
+  asm("vcvtne2ps2bf16 %xmm6, %xmm7, %xmm6");
+}
+
+void
+convert_ymm_from_float_to_bfloat16 (void)
+{
+  asm("vcvtne2ps2bf16 %ymm0, %ymm1, %ymm0");
+  asm("vcvtne2ps2bf16 %ymm6, %ymm7, %ymm6");
+}
+
+void
+convert_zmm_from_float_to_bfloat16 (void)
+{
+  asm("vcvtne2ps2bf16 %zmm0, %zmm1, %zmm0");
+  asm("vcvtne2ps2bf16 %zmm6, %zmm7, %zmm6");
+}
+
+int
+main (int argc, char **argv)
+{
+  /* Move initial values from array to registers and read from XMM regs.  */
+  move_data_to_xmm_reg ();
+  convert_xmm_from_float_to_bfloat16 ();
+  asm ("nop"); /* first breakpoint here  */
+
+  /* Move initial values from array to registers and read from YMM regs.  */
+  move_data_to_ymm_reg ();
+  convert_ymm_from_float_to_bfloat16 ();
+  asm ("nop"); /* second breakpoint here  */
+
+  /* Move initial values from array to registers and read from ZMM regs.  */
+  move_data_to_zmm_reg ();
+  convert_zmm_from_float_to_bfloat16 ();
+  asm ("nop"); /* third breakpoint here  */
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/x86-avx512bf16.exp b/gdb/testsuite/gdb.arch/x86-avx512bf16.exp
new file mode 100644 (file)
index 0000000..5f90d8a
--- /dev/null
@@ -0,0 +1,74 @@
+# Copyright 2020 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# Test bfloat16 support in AVX512 registers
+
+if { [skip_avx512bf16_tests] } {
+    unsupported "target does not support AVX512BF16"
+    return -1
+}
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if { ![runto_main] } {
+    unsupported "could not run to main"
+    return -1
+}
+
+# Test xmm
+set line1 [gdb_get_line_number "first breakpoint here"]
+gdb_breakpoint $line1
+gdb_continue_to_breakpoint "line1" ".*$srcfile:$line1.*"
+
+gdb_test "print \$xmm0.v8_bfloat16" \
+    "= \\{0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875\\}"
+
+gdb_test "print \$xmm6.v8_bfloat16" \
+    "= \\{3, 3.125, 3.25, 3.375, 3.5, 3.625, 3.75, 3.875\\}"
+
+# Test ymm
+set line2 [gdb_get_line_number "second breakpoint here"]
+gdb_breakpoint $line2
+gdb_continue_to_breakpoint "line2" ".*$srcfile:$line2.*"
+
+gdb_test "print \$ymm0.v16_bfloat16\[1\]" "= 8.25"
+gdb_test "print \$ymm6.v16_bfloat16\[1\]" "= 20.25"
+
+# Test zmm
+set line3 [gdb_get_line_number "third breakpoint here"]
+gdb_breakpoint $line3
+gdb_continue_to_breakpoint "line3" ".*$srcfile:$line3.*"
+
+gdb_test "print \$zmm0.v32_bfloat16\[1\]" "= 20.5"
+gdb_test "print \$zmm6.v32_bfloat16\[1\]" "= 68.5"
+
+# Test setting of bfloat values
+gdb_test_no_output "set var \$xmm0.v8_bfloat16\[0\] = 32.25" \
+    "set %xmm0.v8_bfloat16\[0\]"
+gdb_test_no_output "set var \$ymm8.v16_bfloat16\[1\] = 33.5" \
+    "set %ymm8.v16_bfloat16\[1\]"
+gdb_test_no_output "set var \$zmm16.v32_bfloat16\[2\] = 22.75" \
+    "set %zmm16.v32_bfloat16\[2\]"
+
+gdb_test "p \$xmm0.v8_bfloat16\[0\]" "= 32.25"
+gdb_test "p \$ymm8.v16_bfloat16\[1\]" "= 33.5"
+gdb_test "p \$zmm16.v32_bfloat16\[2\]" "= 22.75"
index 8ff2025b6af0c809d90ebbacc7b1f9ae24526c71..653f145c1ce96843ebcc7d9661c16216c2946f82 100644 (file)
@@ -3061,6 +3061,57 @@ gdb_caching_proc skip_tsx_tests {
     return $skip_tsx_tests
 }
 
+# Run a test on the target to see if it supports avx512bf16.  Return 0 if so,
+# 1 if it does not.  Based on 'check_vmx_hw_available' from the GCC testsuite.
+
+gdb_caching_proc skip_avx512bf16_tests {
+    global srcdir subdir gdb_prompt inferior_exited_re
+
+    set me "skip_avx512bf16_tests"
+    if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
+        verbose "$me:  target does not support avx512bf16, returning 1" 2
+        return 1
+    }
+
+    # Compile a test program.
+    set src {
+        int main() {
+            asm volatile ("vcvtne2ps2bf16 %xmm0, %xmm1, %xmm0");
+            return 0;
+        }
+    }
+    if {![gdb_simple_compile $me $src executable]} {
+        return 1
+    }
+
+    # No error message, compilation succeeded so now run it via gdb.
+
+    gdb_exit
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_load "$obj"
+    gdb_run_cmd
+    gdb_expect {
+        -re ".*Illegal instruction.*${gdb_prompt} $" {
+            verbose -log "$me:  avx512bf16 hardware not detected."
+            set skip_avx512bf16_tests 1
+        }
+        -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
+            verbose -log "$me:  avx512bf16 hardware detected."
+            set skip_avx512bf16_tests 0
+        }
+        default {
+            warning "\n$me:  default case taken."
+            set skip_avx512bf16_tests 1
+        }
+    }
+    gdb_exit
+    remote_file build delete $obj
+
+    verbose "$me:  returning $skip_avx512bf16_tests" 2
+    return $skip_avx512bf16_tests
+}
+
 # Run a test on the target to see if it supports btrace hardware.  Return 0 if so,
 # 1 if it does not.  Based on 'check_vmx_hw_available' from the GCC testsuite.
 
index 624588b6563b53e22e4920536ec693dff9948293..c2a3af700e3caa8315faaec6e49081c79eb6bc49 100644 (file)
@@ -54,7 +54,8 @@ static tdesc_type_builtin tdesc_predefined_types[] =
   { "ieee_single", TDESC_TYPE_IEEE_SINGLE },
   { "ieee_double", TDESC_TYPE_IEEE_DOUBLE },
   { "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT },
-  { "i387_ext", TDESC_TYPE_I387_EXT }
+  { "i387_ext", TDESC_TYPE_I387_EXT },
+  { "bfloat16", TDESC_TYPE_BFLOAT16 }
 };
 
 void tdesc_feature::accept (tdesc_element_visitor &v) const
index fdc2a6a370884b1c35bf7dfa10571329ff74d0ac..14b5b5fc9b399dbcaf531959522ec269a6105f62 100644 (file)
@@ -173,6 +173,7 @@ enum tdesc_type_kind
   TDESC_TYPE_IEEE_DOUBLE,
   TDESC_TYPE_ARM_FPA_EXT,
   TDESC_TYPE_I387_EXT,
+  TDESC_TYPE_BFLOAT16,
 
   /* Types defined by a target feature.  */
   TDESC_TYPE_VECTOR,