Add half support for AVX512 register view.
authorFelix Willgerodt <felix.willgerodt@intel.com>
Fri, 11 Sep 2020 13:43:54 +0000 (15:43 +0200)
committerFelix Willgerodt <felix.willgerodt@intel.com>
Fri, 3 Sep 2021 13:18:31 +0000 (15:18 +0200)
This adds support for the half datatype, FP16, to the AVX512 register printing.

gdb/ChangeLog:
2020-07-21  Felix Willgerodt  <Felix.Willgerodt@intel.com>

* i386-tdep.c (i386_zmm_type) <v32_half>: New field.
(i386_ymm_type) <v16_half>: New field.
(i386_gdbarch_init): Add set_gdbarch_half_format.
* features/i386/64bit-avx512.xml: Add half type.
* features/i386/64bit-avx512.c: Regenerated.
* features/i386/64bit-sse.xml: Add half type.
* features/i386/64bit-sse.c: Regenerated.

gdb/testsuite/ChangeLog:
2021-07-21  Felix Willgerodt  <Felix.Willgerodt@intel.com>

* gdb.arch/x86-avx512fp16.c: New file.
* gdb.arch/x86-avx512fp16.exp: New file.
* lib/gdb.exp (skip_avx512fp16_tests): New function.

gdb/features/i386/32bit-sse.c
gdb/features/i386/32bit-sse.xml
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/i386-tdep.c
gdb/testsuite/gdb.arch/x86-avx512fp16.c [new file with mode: 0644]
gdb/testsuite/gdb.arch/x86-avx512fp16.exp [new file with mode: 0644]
gdb/testsuite/lib/gdb.exp

index b6d5fbaf0fcaa9d6ea5722c1bd704bdd8d804082..adc7fe06276048f04161b217d1187ed38aba3861 100644 (file)
@@ -13,6 +13,9 @@ create_feature_i386_32bit_sse (struct target_desc *result, long regnum)
   element_type = tdesc_named_type (feature, "bfloat16");
   tdesc_create_vector (feature, "v8bf16", element_type, 8);
 
+  element_type = tdesc_named_type (feature, "ieee_half");
+  tdesc_create_vector (feature, "v8h", element_type, 8);
+
   element_type = tdesc_named_type (feature, "ieee_single");
   tdesc_create_vector (feature, "v4f", element_type, 4);
 
@@ -36,6 +39,8 @@ create_feature_i386_32bit_sse (struct target_desc *result, long regnum)
   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, "v8h");
+  tdesc_add_field (type_with_fields, "v8_half", 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 8710622e9446e8220d652b19f947ae8794dd1d14..f7d1a75e754655f9075cc17760f2d78c1b13e26d 100644 (file)
@@ -8,6 +8,7 @@
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
 <feature name="org.gnu.gdb.i386.sse">
   <vector id="v8bf16" type="bfloat16" count="8"/>
+  <vector id="v8h" type="ieee_half" 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"/>
@@ -16,6 +17,7 @@
   <vector id="v2i64" type="int64" count="2"/>
   <union id="vec128">
     <field name="v8_bfloat16" type="v8bf16"/>
+    <field name="v8_half" type="v8h"/>
     <field name="v4_float" type="v4f"/>
     <field name="v2_double" type="v2d"/>
     <field name="v16_int8" type="v16i8"/>
index 1bd49dcd9d5a27705de5c61755fe8322ec981ff2..9ceadd89cda90d6d4efa7c6a9fae795b343da841 100644 (file)
@@ -13,6 +13,9 @@ create_feature_i386_64bit_avx512 (struct target_desc *result, long regnum)
   element_type = tdesc_named_type (feature, "bfloat16");
   tdesc_create_vector (feature, "v8bf16", element_type, 8);
 
+  element_type = tdesc_named_type (feature, "ieee_half");
+  tdesc_create_vector (feature, "v8h", element_type, 8);
+
   element_type = tdesc_named_type (feature, "ieee_single");
   tdesc_create_vector (feature, "v4f", element_type, 4);
 
@@ -36,6 +39,8 @@ create_feature_i386_64bit_avx512 (struct target_desc *result, long regnum)
   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, "v8h");
+  tdesc_add_field (type_with_fields, "v8_half", 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 a4c7f02d6d8f4da61834f820fac85a70fbe9a521..b7fe4d5015b1dd6e9d425402fe41272ea6a13395 100644 (file)
@@ -8,6 +8,7 @@
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
 <feature name="org.gnu.gdb.i386.avx512">
   <vector id="v8bf16" type="bfloat16" count="8"/>
+  <vector id="v8h" type="ieee_half" 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"/>
@@ -16,6 +17,7 @@
   <vector id="v2i64" type="int64" count="2"/>
   <union id="vec128">
     <field name="v8_bfloat16" type="v8bf16"/>
+    <field name="v8_half" type="v8h"/>
     <field name="v4_float" type="v4f"/>
     <field name="v2_double" type="v2d"/>
     <field name="v16_int8" type="v16i8"/>
index 645e31413376539f6f81f61a6b038f524c502a6c..ffb7a45ec1acd7384b9f87c92cebf1e3c1f80cfd 100644 (file)
@@ -13,6 +13,9 @@ create_feature_i386_64bit_sse (struct target_desc *result, long regnum)
   element_type = tdesc_named_type (feature, "bfloat16");
   tdesc_create_vector (feature, "v8bf16", element_type, 8);
 
+  element_type = tdesc_named_type (feature, "ieee_half");
+  tdesc_create_vector (feature, "v8h", element_type, 8);
+
   element_type = tdesc_named_type (feature, "ieee_single");
   tdesc_create_vector (feature, "v4f", element_type, 4);
 
@@ -36,6 +39,8 @@ create_feature_i386_64bit_sse (struct target_desc *result, long regnum)
   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, "v8h");
+  tdesc_add_field (type_with_fields, "v8_half", 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 f23d4d5cb4e4dd6fdc7f895af4efab291203d37c..9ae2310af3372da9cad263c75f8025b60db6b2b3 100644 (file)
@@ -8,6 +8,7 @@
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
 <feature name="org.gnu.gdb.i386.sse">
   <vector id="v8bf16" type="bfloat16" count="8"/>
+  <vector id="v8h" type="ieee_half" 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"/>
@@ -16,6 +17,7 @@
   <vector id="v2i64" type="int64" count="2"/>
   <union id="vec128">
     <field name="v8_bfloat16" type="v8bf16"/>
+    <field name="v8_half" type="v8h"/>
     <field name="v4_float" type="v4f"/>
     <field name="v2_double" type="v2d"/>
     <field name="v16_int8" type="v16i8"/>
index e436437c6832f9f8c2196d066e06b1877a17e36d..c2835a2458d11882e75d03622b8a84270b5abc82 100644 (file)
@@ -3117,6 +3117,7 @@ i386_zmm_type (struct gdbarch *gdbarch)
        int8_t v64_int8[64];
        double v8_double[8];
        float v16_float[16];
+       float16_t v32_half[32];
        bfloat16_t v32_bfloat16[32];
       };
 #endif
@@ -3127,6 +3128,8 @@ i386_zmm_type (struct gdbarch *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, "v32_half",
+                                  init_vector_type (bt->builtin_half, 32));
       append_composite_type_field (t, "v16_float",
                                   init_vector_type (bt->builtin_float, 16));
       append_composite_type_field (t, "v8_double",
@@ -3173,6 +3176,7 @@ i386_ymm_type (struct gdbarch *gdbarch)
        int8_t v32_int8[32];
        double v4_double[4];
        float v8_float[8];
+       float16_t v16_half[16];
        bfloat16_t v16_bfloat16[16];
       };
 #endif
@@ -3183,6 +3187,8 @@ i386_ymm_type (struct gdbarch *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, "v16_half",
+                                  init_vector_type (bt->builtin_half, 16));
       append_composite_type_field (t, "v8_float",
                                   init_vector_type (bt->builtin_float, 8));
       append_composite_type_field (t, "v4_double",
diff --git a/gdb/testsuite/gdb.arch/x86-avx512fp16.c b/gdb/testsuite/gdb.arch/x86-avx512fp16.c
new file mode 100644 (file)
index 0000000..ebc7295
--- /dev/null
@@ -0,0 +1,164 @@
+/* Test program for bfloat16 of AVX 512 registers.
+
+   Copyright 2021 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_half (void)
+{
+  asm("vcvtps2phx %xmm1, %xmm0");
+  asm("vcvtps2phx %xmm7, %xmm6");
+}
+
+void
+convert_ymm_from_float_to_half (void)
+{
+  asm("vcvtps2phx %ymm1, %xmm0");
+  asm("vcvtps2phx %ymm7, %xmm6");
+}
+
+void
+convert_zmm_from_float_to_half (void)
+{
+  asm("vcvtps2phx %zmm1, %ymm0");
+  asm("vcvtps2phx %zmm7, %ymm6");
+}
+
+int
+main ()
+{
+  /* Move initial values from array to registers and read from XMM regs.  */
+  move_data_to_xmm_reg ();
+  convert_xmm_from_float_to_half ();
+  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_half ();
+  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_half ();
+  asm ("nop"); /* third breakpoint here  */
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/x86-avx512fp16.exp b/gdb/testsuite/gdb.arch/x86-avx512fp16.exp
new file mode 100644 (file)
index 0000000..22575cc
--- /dev/null
@@ -0,0 +1,68 @@
+# Copyright 2021 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/>.
+
+# Test fp16 support in AVX512 registers.
+
+if { [skip_avx512fp16_tests] } {
+    unsupported "target does not support AVX512fp16"
+    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_half" \
+    "= \\{0.5, 0.625, 0.75, 0.875, 0, 0, 0, 0\\}"
+
+gdb_test "print \$xmm6.v8_half" \
+    "= \\{3.5, 3.625, 3.75, 3.875, 0, 0, 0, 0\\}"
+
+# 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_half\[1\]" "= 10.25"
+gdb_test "print \$ymm6.v16_half\[1\]" "= 22.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_half\[1\]" "= 28.5"
+gdb_test "print \$zmm6.v32_half\[1\]" "= 76.5"
+
+# Test setting of half values.
+gdb_test_no_output "set var \$xmm0.v8_half\[0\] = 32.25"
+gdb_test_no_output "set var \$ymm3.v16_half\[1\] = 33.5"
+gdb_test_no_output "set var \$zmm7.v32_half\[2\] = 22.75"
+
+gdb_test "p \$xmm0.v8_half\[0\]" "= 32.25"
+gdb_test "p \$ymm3.v16_half\[1\]" "= 33.5"
+gdb_test "p \$zmm7.v32_half\[2\]" "= 22.75"
index 3aea7baaab097cc8c6823da358edde1d3b7a17ca..ca9864b9007f647396391b3334ec72e070e64f3d 100644 (file)
@@ -3384,6 +3384,57 @@ gdb_caching_proc skip_avx512bf16_tests {
     return $skip_avx512bf16_tests
 }
 
+# Run a test on the target to see if it supports avx512fp16.  Return 0 if so,
+# 1 if it does not.  Based on 'check_vmx_hw_available' from the GCC testsuite.
+
+gdb_caching_proc skip_avx512fp16_tests {
+    global srcdir subdir gdb_prompt inferior_exited_re
+
+    set me "skip_avx512fp16_tests"
+    if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } {
+        verbose "$me:  target does not support avx512fp16, returning 1" 2
+        return 1
+    }
+
+    # Compile a test program.
+    set src {
+        int main() {
+            asm volatile ("vcvtps2phx %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:  avx512fp16 hardware not detected."
+            set skip_avx512fp16_tests 1
+        }
+        -re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
+            verbose -log "$me:  avx512fp16 hardware detected."
+            set skip_avx512fp16_tests 0
+        }
+        default {
+            warning "\n$me:  default case taken."
+            set skip_avx512fp16_tests 1
+        }
+    }
+    gdb_exit
+    remote_file build delete $obj
+
+    verbose "$me:  returning $skip_avx512fp16_tests" 2
+    return $skip_avx512fp16_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.