01f9f808e2
This patch adds support for the Intel(R) Advanced Vector Extensions 512 (Intel(R) AVX-512) registers. Native and remote debugging are covered by this patch. Intel(R) AVX-512 is an extension to AVX to support 512-bit wide SIMD registers in 64-bit mode (XMM0-XMM31, YMM0-YMM31, ZMM0-ZMM31). The number of available registers in 32-bit mode is still 8 (XMM0-7, YMM0-7, ZMM0-7). The lower 256-bits of the ZMM registers are aliased to the respective 256-bit YMM registers. The lower 128-bits are aliased to the respective 128-bit XMM registers. There are also 8 new, dedicated mask registers (K0-K7) in both 32-bit mode and 64-bit mode. For more information please see Intel(R) Developer Zone: Intel(R) AVX http://software.intel.com/en-us/intel-isa-extensions#pid-16007-1495 Intel(R) Architecture Instruction Set Extensions Programming Reference: http://software.intel.com/en-us/file/319433-017pdf 2014-04-24 Michael Sturm <michael.sturm@mintel.com> Walfred Tedeschi <walfred.tedeschi@intel.com> * amd64-linux-nat.c (amd64_linux_gregset32_reg_offset): Add AVX512 registers. (amd64_linux_read_description): Add code to handle AVX512 xstate mask and return respective tdesc. * amd64-linux-tdep.c: Include features/i386/amd64-avx512-linux.c and features/i386/x32-avx512-linux.c. (amd64_linux_gregset_reg_offset): Add AVX512 registers. (amd64_linux_core_read_description): Add code to handle AVX512 xstate mask and return respective tdesc. (_initialize_amd64_linux_tdep): Initialize AVX512 tdesc. * amd64-linux-tdep.h (AMD64_LINUX_ORIG_RAX_REGNUM): Adjust regnum calculation. (AMD64_LINUX_NUM_REGS): Adjust to new number of registers. (tdesc_amd64_avx512_linux): New prototype. (tdesc_x32_avx512_linux): Likewise. * amd64-tdep.c: Include features/i386/amd64-avx512.c and features/i386/x32-avx512.c. (amd64_ymm_avx512_names): New register names for pseudo registers YMM16-31. (amd64_ymmh_avx512_names): New register names for raw registers YMMH16-31. (amd64_k_names): New register names for K registers. (amd64_zmmh_names): New register names for ZMM raw registers. (amd64_zmm_names): New registers names for ZMM pseudo registers. (amd64_xmm_avx512_names): New register names for XMM16-31 registers. (amd64_pseudo_register_name): Add code to return AVX512 pseudo registers. (amd64_init_abi): Add code to intitialize AVX512 tdep variables if feature is present. (_initialize_amd64_tdep): Call AVX512 tdesc initializers. * amd64-tdep.h (enum amd64_regnum): Add AVX512 registers. (AMD64_NUM_REGS): Adjust to new number of registers. * i386-linux-nat.c (GETXSTATEREGS_SUPPLIES): Extend range of registers supplied via XSTATE by AVX512 registers. (i386_linux_read_description): Add case for AVX512. * i386-linux-tdep.c: Include i386-avx512-linux.c. (i386_linux_gregset_reg_offset): Add AVX512 registers. (i386_linux_core_read_description): Add case for AVX512. (i386_linux_init_abi): Install supported register note section for AVX512. (_initialize_i386_linux_tdep): Add call to tdesc init function for AVX512. * i386-linux-tdep.h (I386_LINUX_NUM_REGS): Set number of registers to be number of zmm7h + 1. (tdesc_i386_avx512_linux): Add tdesc for AVX512 registers. * i386-tdep.c: Include features/i386/i386-avx512.c. (i386_zmm_names): Add ZMM pseudo register names array. (i386_zmmh_names): Add ZMM raw register names array. (i386_k_names): Add K raw register names array. (num_lower_zmm_regs): Add constant for the number of lower ZMM registers. AVX512 has 16 more ZMM registers than there are YMM registers. (i386_zmmh_regnum_p): Add function to look up register number of ZMM raw registers. (i386_zmm_regnum_p): Likewise for ZMM pseudo registers. (i386_k_regnum_p): Likewise for K raw registers. (i386_ymmh_avx512_regnum_p): Likewise for additional YMM raw registers added by AVX512. (i386_ymm_avx512_regnum_p): Likewise for additional YMM pseudo registers added by AVX512. (i386_xmm_avx512_regnum_p): Likewise for additional XMM registers added by AVX512. (i386_register_name): Add code to hide YMMH16-31 and ZMMH0-31. (i386_pseudo_register_name): Add ZMM pseudo registers. (i386_zmm_type): Construct and return vector registers type for ZMM registers. (i386_pseudo_register_type): Return appropriate type for YMM16-31, ZMM0-31 pseudo registers and K registers. (i386_pseudo_register_read_into_value): Add code to read K, ZMM and YMM16-31 registers from register cache. (i386_pseudo_register_write): Add code to write K, ZMM and YMM16-31 registers. (i386_register_reggroup_p): Add code to include/exclude AVX512 registers in/from respective register groups. (i386_validate_tdesc_p): Handle AVX512 feature, add AVX512 registers if feature is present in xcr0. (i386_gdbarch_init): Add code to initialize AVX512 feature variables in tdep structure, wire in pseudo registers and call initialize_tdesc_i386_avx512. * i386-tdep.h (struct gdbarch_tdep): Add AVX512 related variables. (i386_regnum): Add AVX512 registers. (I386_SSE_NUM_REGS): New define for number of SSE registers. (I386_AVX_NUM_REGS): Likewise for AVX registers. (I386_AVX512_NUM_REGS): Likewise for AVX512 registers. (I386_MAX_REGISTER_SIZE): Change to 64 bytes, ZMM registers are 512 bits wide. (i386_xmm_avx512_regnum_p): New prototype for register look up. (i386_ymm_avx512_regnum_p): Likewise. (i386_k_regnum_p): Likewise. (i386_zmm_regnum_p): Likewise. (i386_zmmh_regnum_p): Likewise. * i387-tdep.c : Update year in copyright notice. (xsave_ymm_avx512_offset): New table for YMM16-31 offsets in XSAVE buffer. (XSAVE_YMM_AVX512_ADDR): New macro. (xsave_xmm_avx512_offset): New table for XMM16-31 offsets in XSAVE buffer. (XSAVE_XMM_AVX512_ADDR): New macro. (xsave_avx512_k_offset): New table for K register offsets in XSAVE buffer. (XSAVE_AVX512_K_ADDR): New macro. (xsave_avx512_zmm_h_offset): New table for ZMM register offsets in XSAVE buffer. (XSAVE_AVX512_ZMM_H_ADDR): New macro. (i387_supply_xsave): Add code to supply AVX512 registers to XSAVE buffer. (i387_collect_xsave): Add code to collect AVX512 registers from XSAVE buffer. * i387-tdep.h (I387_NUM_XMM_AVX512_REGS): New define for number of XMM16-31 registers. (I387_NUM_K_REGS): New define for number of K registers. (I387_K0_REGNUM): New define for K0 register number. (I387_NUM_ZMMH_REGS): New define for number of ZMMH registers. (I387_ZMM0H_REGNUM): New define for ZMM0H register number. (I387_NUM_YMM_AVX512_REGS): New define for number of YMM16-31 registers. (I387_YMM16H_REGNUM): New define for YMM16H register number. (I387_XMM16_REGNUM): New define for XMM16 register number. (I387_YMM0_REGNUM): New define for YMM0 register number. (I387_KEND_REGNUM): New define for last K register number. (I387_ZMMENDH_REGNUM): New define for last ZMMH register number. (I387_YMMH_AVX512_END_REGNUM): New define for YMM31 register number. (I387_XMM_AVX512_END_REGNUM): New define for XMM31 register number. * common/i386-xstate.h: Add AVX 3.1 feature bits, mask and XSTATE size. * features/Makefile: Add AVX512 related files. * features/i386/32bit-avx512.xml: New file. * features/i386/64bit-avx512.xml: Likewise. * features/i386/amd64-avx512-linux.c: Likewise. * features/i386/amd64-avx512-linux.xml: Likewise. * features/i386/amd64-avx512.c: Likewise. * features/i386/amd64-avx512.xml: Likewise. * features/i386/i386-avx512-linux.c: Likewise. * features/i386/i386-avx512-linux.xml: Likewise. * features/i386/i386-avx512.c: Likewise. * features/i386/i386-avx512.xml: Likewise. * features/i386/x32-avx512-linux.c: Likewise. * features/i386/x32-avx512-linux.xml: Likewise. * features/i386/x32-avx512.c: Likewise. * features/i386/x32-avx512.xml: Likewise. * regformats/i386/amd64-avx512-linux.dat: New file. * regformats/i386/amd64-avx512.dat: Likewise. * regformats/i386/i386-avx512-linux.dat: Likewise. * regformats/i386/i386-avx512.dat: Likewise. * regformats/i386/x32-avx512-linux.dat: Likewise. * regformats/i386/x32-avx512.dat: Likewise. * NEWS: Add note about new support for AVX512. testsuite/ * Makefile.in (EXECUTABLES): Added i386-avx512. * gdb.arch/i386-avx512.c: New file. * gdb.arch/i386-avx512.exp: Likewise. gdbserver/ * Makefile.in: Added rules to handle new files i386-avx512.c i386-avx512-linux.c amd64-avx512.c amd64-avx512-linux.c x32-avx512.c x32-avx512-linux.c. * configure.srv (srv_i386_regobj): Add i386-avx512.o. (srv_i386_linux_regobj): Add i386-avx512-linux.o. (srv_amd64_regobj): Add amd64-avx512.o and x32-avx512.o. (srv_amd64_linux_regobj): Add amd64-avx512-linux.o and x32-avx512-linux.o. (srv_i386_32bit_xmlfiles): Add i386/32bit-avx512.xml. (srv_i386_64bit_xmlfiles): Add i386/64bit-avx512.xml. (srv_amd64_xmlfiles): Add i386/amd64-avx512.xml and i386/x32-avx512.xml. (srv_i386_linux_xmlfiles): Add i386/i386-avx512-linux.xml. (srv_amd64_linux_xmlfiles): Add i386/amd64-avx512-linux.xml and i386/x32-avx512-linux.xml. * i387-fp.c (num_avx512_k_registers): New constant for number of K registers. (num_avx512_zmmh_low_registers): New constant for number of lower ZMM registers (0-15). (num_avx512_zmmh_high_registers): New constant for number of higher ZMM registers (16-31). (num_avx512_ymmh_registers): New contant for number of higher YMM registers (ymm16-31 added by avx521 on x86_64). (num_avx512_xmm_registers): New constant for number of higher XMM registers (xmm16-31 added by AVX512 on x86_64). (struct i387_xsave): Add space for AVX512 registers. (i387_cache_to_xsave): Change raw buffer size to 64 characters. Add code to handle AVX512 registers. (i387_xsave_to_cache): Add code to handle AVX512 registers. * linux-x86-low.c (init_registers_amd64_avx512_linux): New prototypei from generated file. (tdesc_amd64_avx512_linux): Likewise. (init_registers_x32_avx512_linux): Likewise. (tdesc_x32_avx512_linux): Likewise. (init_registers_i386_avx512_linux): Likewise. (tdesc_i386_avx512_linux): Likewise. (x86_64_regmap): Add AVX512 registers. (x86_linux_read_description): Add code to handle AVX512 XSTATE mask. (initialize_low_arch): Add code to initialize AVX512 registers. doc/ * gdb.texinfo (i386 Features): Add description of AVX512 registers. Change-Id: Ifc4c08c76b85dbec18d02efdbe6182e851584438 Signed-off-by: Michael Sturm <michael.sturm@intel.com>
176 lines
6.5 KiB
Text
176 lines
6.5 KiB
Text
# Copyright 2014 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
|
|
|
|
# This file is part of the gdb testsuite.
|
|
|
|
|
|
if { ![istarget i?86-*-*] && ![istarget x86_64-*-* ] } {
|
|
verbose "Skipping x86 AVX512 tests."
|
|
return
|
|
}
|
|
|
|
standard_testfile
|
|
|
|
set comp_flags "-mavx512f -I${srcdir}/../common"
|
|
|
|
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
|
|
[list debug nowarnings additional_flags=${comp_flags}]] } {
|
|
return -1
|
|
}
|
|
|
|
if ![runto_main] {
|
|
untested "could not run to main"
|
|
return -1
|
|
}
|
|
|
|
set supports_avx512 0
|
|
|
|
set test "probe AVX512 support"
|
|
gdb_test_multiple "print have_avx512()" $test {
|
|
-re ".. = 1\r\n$gdb_prompt $" {
|
|
pass $test
|
|
set supports_avx512 1
|
|
}
|
|
-re ".. = 0\r\n$gdb_prompt $" {
|
|
pass $test
|
|
}
|
|
}
|
|
|
|
if { !$supports_avx512 } {
|
|
unsupported "processor does not support AVX512"
|
|
return
|
|
}
|
|
|
|
gdb_test "break [gdb_get_line_number "first breakpoint here"]" \
|
|
"Breakpoint .* at .*i386-avx512.c.*" \
|
|
"set first breakpoint in main"
|
|
gdb_continue_to_breakpoint "continue to first breakpoint in main"
|
|
|
|
set nr_regs 8
|
|
|
|
for { set r 1 } { $r < $nr_regs } { incr r } {
|
|
gdb_test "print/x \$k$r" \
|
|
".. = 0x[format %x $r]2[format %x $r]1" \
|
|
"check contents of %k$r"
|
|
}
|
|
|
|
for { set r 1 } { $r < $nr_regs } { incr r } {
|
|
gdb_test "set var \$k$r = 0x$r$r$r$r" "" "set %k$r"
|
|
}
|
|
|
|
gdb_test "break [gdb_get_line_number "second breakpoint here"]" \
|
|
"Breakpoint .* at .*i386-avx512.c.*" \
|
|
"set second breakpoint in main"
|
|
gdb_continue_to_breakpoint "continue to second breakpoint in main"
|
|
|
|
set nr_regs 7
|
|
|
|
for { set r 0 } { $r < $nr_regs } { incr r } {
|
|
set val [expr $r + 1]
|
|
gdb_test "print/x k_data\[$r\]" \
|
|
".. = 0x$val$val$val$val" \
|
|
"check contents of k_data\[$r\]"
|
|
}
|
|
|
|
gdb_test "break [gdb_get_line_number "third breakpoint here"]" \
|
|
"Breakpoint .* at .*i386-avx512.c.*" \
|
|
"set third breakpoint in main"
|
|
gdb_continue_to_breakpoint "continue to third breakpoint in main"
|
|
|
|
if [is_amd64_regs_target] {
|
|
set nr_regs 8
|
|
} else {
|
|
set nr_regs 32
|
|
}
|
|
|
|
for { set r 0 } { $r < $nr_regs } { incr r } {
|
|
gdb_test "print \$zmm$r.v8_double" \
|
|
".. = \\{$r, $r.125, $r.25, $r.375, $r.5, $r.625, $r.75, $r.875\\}.*" \
|
|
"check double contents of %zmm$r"
|
|
gdb_test "print \$zmm$r.v32_int16" \
|
|
".. = \\{(-?\[0-9\]+, ){31}-?\[0-9\]+\\}.*" \
|
|
"check int16 contents of %zmm$r"
|
|
gdb_test "print \$ymm$r.v4_double" \
|
|
".. = \\{$r, $r.125, $r.25, $r.375\\}.*" \
|
|
"check float contents of %ymm$r"
|
|
gdb_test "print \$ymm$r.v16_int16" \
|
|
".. = \\{(-?\[0-9\]+, ){15}-?\[0-9\]+\\}.*" \
|
|
"check int16 contents of %ymm$r"
|
|
gdb_test "print \$xmm$r.v2_double" \
|
|
".. = \\{$r, $r.125\\}.*" \
|
|
"check float contents of %xmm$r"
|
|
gdb_test "print \$xmm$r.v8_int16" \
|
|
".. = \\{(-?\[0-9\]+, ){7}-?\[0-9\]+\\}.*" \
|
|
"check int16 contents of %xmm$r"
|
|
}
|
|
|
|
for { set r 0 } { $r < $nr_regs } { incr r } {
|
|
gdb_test "set var \$zmm$r.v8_double\[0\] = $r + 10" "" "set %zmm$r.v8_double\[0\]"
|
|
gdb_test "set var \$zmm$r.v8_double\[1\] = $r + 10.125" "" "set %zmm$r.v8_double\[1\]"
|
|
gdb_test "set var \$zmm$r.v8_double\[2\] = $r + 10.25" "" "set %zmm$r.v8_double\[2\]"
|
|
gdb_test "set var \$zmm$r.v8_double\[3\] = $r + 10.375" "" "set %zmm$r.v8_double\[3\]"
|
|
gdb_test "set var \$zmm$r.v8_double\[4\] = $r + 10.5" "" "set %zmm$r.v8_double\[4\]"
|
|
gdb_test "set var \$zmm$r.v8_double\[5\] = $r + 10.625" "" "set %zmm$r.v8_double\[5\]"
|
|
gdb_test "set var \$zmm$r.v8_double\[6\] = $r + 10.75" "" "set %zmm$r.v8_double\[6\]"
|
|
gdb_test "set var \$zmm$r.v8_double\[7\] = $r + 10.875" "" "set %zmm$r.v8_double\[7\]"
|
|
}
|
|
|
|
gdb_test "break [gdb_get_line_number "fourth breakpoint here"]" \
|
|
"Breakpoint .* at .*i386-avx512.c.*" \
|
|
"set fourth breakpoint in main"
|
|
gdb_continue_to_breakpoint "continue to fourth breakpoint in main"
|
|
|
|
for { set r 0 } { $r < $nr_regs } { incr r } {
|
|
gdb_test "print zmm_data\[$r\]" \
|
|
".. = \\{f = \\{[expr $r + 10], [expr $r.125 + 10], [expr $r.25 + 10], [expr $r.375 + 10], [expr $r.5 + 10], [expr $r.625 + 10], [expr $r.75 + 10], [expr $r.875 + 10]\\}\\}.*" \
|
|
"check contents of zmm_data\[$r\] after writing ZMM regs"
|
|
}
|
|
|
|
for { set r 0 } { $r < $nr_regs } { incr r } {
|
|
gdb_test "set var \$ymm$r.v4_double\[0\] = $r + 20" "" "set %ymm$r.v4_double\[0\]"
|
|
gdb_test "set var \$ymm$r.v4_double\[1\] = $r + 20.125" "" "set %ymm$r.v4_double\[1\]"
|
|
gdb_test "set var \$ymm$r.v4_double\[2\] = $r + 20.25" "" "set %ymm$r.v4_double\[2\]"
|
|
gdb_test "set var \$ymm$r.v4_double\[3\] = $r + 20.375" "" "set %ymm$r.v4_double\[3\]"
|
|
}
|
|
|
|
gdb_test "break [gdb_get_line_number "fifth breakpoint here"]" \
|
|
"Breakpoint .* at .*i386-avx512.c.*" \
|
|
"set fifth breakpoint in main"
|
|
gdb_continue_to_breakpoint "continue to fifth breakpoint in main"
|
|
|
|
for { set r 0 } { $r < $nr_regs } { incr r } {
|
|
gdb_test "print zmm_data\[$r\]" \
|
|
".. = \\{f = \\{[expr $r + 20], [expr $r.125 + 20], [expr $r.25 + 20], [expr $r.375 + 20], [expr $r.5 + 10], [expr $r.625 + 10], [expr $r.75 + 10], [expr $r.875 + 10]\\}\\}.*" \
|
|
"check contents of zmm_data\[$r\] after writing YMM regs"
|
|
}
|
|
|
|
for { set r 0 } { $r < $nr_regs } { incr r } {
|
|
gdb_test "set var \$xmm$r.v2_double\[0\] = $r + 30" "" "set %xmm$r.v2_double\[0\]"
|
|
gdb_test "set var \$xmm$r.v2_double\[1\] = $r + 30.125" "" "set %xmm$r.v2_double\[1\]"
|
|
}
|
|
|
|
gdb_test "break [gdb_get_line_number "sixth breakpoint here"]" \
|
|
"Breakpoint .* at .*i386-avx512.c.*" \
|
|
"set sixth breakpoint in main"
|
|
gdb_continue_to_breakpoint "continue to sixth breakpoint in main"
|
|
|
|
for { set r 0 } { $r < $nr_regs } { incr r } {
|
|
gdb_test "print zmm_data\[$r\]" \
|
|
".. = \\{f = \\{[expr $r + 30], [expr $r.125 + 30], [expr $r.25 + 20], [expr $r.375 + 20], [expr $r.5 + 10], [expr $r.625 + 10], [expr $r.75 + 10], [expr $r.875 + 10]\\}\\}.*" \
|
|
"check contents of zmm_data\[$r\] after writing XMM regs"
|
|
}
|