xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.arch/amd64-init-x87-values.exp (revision a45db23f655e22f0c2354600d3b3c2cb98abf2dc)
1# Copyright 2018-2020 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16# This file is part of the gdb testsuite.
17
18# Test initial values of x87 control registers, before any x87
19# instructions have been executed in the inferior.
20
21if ![is_amd64_regs_target] then {
22    return
23}
24
25standard_testfile .S
26
27set options [list debug \
28		 additional_flags=-static \
29		 additional_flags=-nostartfiles]
30if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} $options] } {
31    return -1
32}
33
34# Start the test file, and check the x87 control registers (and
35# mxcsr), we expect the default values in all registers.
36#
37# Step forward until the x87 unit is enabled, recheck the register
38# values; they should still have the default values.
39#
40# Finally, step forward until the x87 state has changed, and then
41# recheck the register state to view the changes.
42proc_with_prefix check_x87_regs_around_init {} {
43    global binfile
44
45    clean_restart ${binfile}
46
47    # Get things started.
48    if ![runto_main] then {
49	fail "can't run to main"
50	return 0
51    }
52
53    # Check initial values of x87 control registers.  The MXCSR isn't part
54    # of the x87 set, it belongs with SSE/AVX, however we test it here
55    # too, it should have its default value in both cases.
56    foreach {regname regvalue} { "fctrl" "0x37f" \
57				 "fstat" "0x0" \
58				 "ftag" "0xffff" \
59				 "fiseg" "0x0" \
60				 "fioff" "0x0" \
61				 "foseg" "0x0" \
62				 "fooff" "0x0" \
63				 "fop" "0x0" \
64				 "mxcsr" "0x1f80"} {
65	gdb_test "p/x \$${regname}" " = ${regvalue}"  "check initial value of \$${regname}"
66    }
67
68    # No x87 instructions have been executed yet.  Step up to FWAIT
69    # instruction.  Executing this instruction will enable the x87 unit,
70    # causing the kernel to place the default values into all registers.
71    # After this GDB will no longer supply the default values itself but
72    # will instread read the values out of the xsave buffer.
73    gdb_test "stepi" "fwait" "step to FWAIT instruction"
74    gdb_test "stepi" "nop" "step past FWAIT instruction"
75
76    # The x87 unit is now enabled, but the register values should be
77    # unchanged.
78    foreach {regname regvalue} { "fctrl" "0x37f" \
79				 "fstat" "0x0" \
80				 "ftag" "0xffff" \
81				 "fiseg" "0x0" \
82				 "fioff" "0x0" \
83				 "foseg" "0x0" \
84				 "fooff" "0x0" \
85				 "fop" "0x0" \
86				 "mxcsr" "0x1f80"} {
87	gdb_test "p/x \$${regname}" " = ${regvalue}"  "check post FWAIT value of \$${regname}"
88    }
89
90    # Now step to an x87 instruction that modifies some state.
91    gdb_test "stepi" "fld1" "step to FLD1 instruction"
92
93    # Grab the address of this instruction, it will appear in later
94    # results.
95    set addr [get_hexadecimal_valueof "\$pc" "0"]
96
97    # Step past the FLD1 instruction.
98    gdb_test "stepi" "nop" "step past FLD1 instruction"
99
100    # Check new values of x87 control registers (and MXCSR).
101    foreach {regname regvalue} [list "fctrl" "0x37f" \
102				     "fstat" "0x3800" \
103				     "ftag" "0x3fff" \
104				     "fiseg" "0x0" \
105				     "fioff" $addr \
106				     "foseg" "0x0" \
107				     "fooff" "0x0" \
108				     "fop" "0x0" \
109				     "mxcsr" "0x1f80" ] {
110	gdb_test "p/x \$${regname}" " = ${regvalue}"  "check post FLD1 value of \$${regname}"
111    }
112}
113
114# Start the test file, all FP features will be disabled.  Set a new
115# value into the MXCSR register, then step forward one instruction (a
116# nop that does not enable any FP features).  Finally check that the
117# mxcsr register still has the value we set.
118proc_with_prefix check_setting_mxcsr_before_enable {} {
119    global binfile gdb_prompt
120
121    clean_restart ${binfile}
122
123    if ![runto_main] then {
124	fail "can't run to main"
125	return 0
126    }
127
128    gdb_test_no_output "set \$mxcsr=0x9f80" "set a new value for MXCSR"
129    gdb_test "stepi" "fwait" "step forward one instruction for mxcsr test"
130
131    set test "check new value of MXCSR is still in place"
132    set pass_pattern " = 0x9f80"
133    # Pre-4.14 kernels have a bug (fixed by commit 0852b374173b "x86/fpu:
134    # Add FPU state copying quirk to handle XRSTOR failure on Intel Skylake
135    # CPUs") that causes mxcsr not to be copied, in which case we get 0 instead of
136    # the just saved value.
137    set xfail_pattern " = 0x0"
138    gdb_test_multiple "p/x \$mxcsr" $test {
139	-re "\[\r\n\]*(?:$pass_pattern)\[\r\n\]+$gdb_prompt $" {
140	    pass $test
141	}
142	-re "\[\r\n\]*(?:$xfail_pattern)\[\r\n\]+$gdb_prompt $" {
143	    xfail $test
144	}
145    }
146}
147
148# Start the test file, all FP features will be disabled.  Set new
149# values into the x87 control-registers, then step forward one
150# instruction (a nop that does not enable any FP features).  Finally
151# check that all the x87 control-registers still have the values we
152# set.
153proc_with_prefix check_setting_x87_regs_before_enable {} {
154    global binfile
155
156    clean_restart ${binfile}
157
158    if ![runto_main] then {
159	fail "can't run to main"
160	return 0
161    }
162
163    foreach {regname regvalue} [list "fctrl" "0x37f" \
164				    "fstat" "0x3800" \
165				    "ftag" "0x7777" \
166				    "fiseg" "0x12" \
167				    "fioff" "0x2418" \
168				    "foseg" "0x24" \
169				    "fooff" "0x36" \
170				    "fop" "0x100" ] {
171	gdb_test_no_output "set \$$regname=$regvalue" "set a new value for $regname"
172    }
173
174    gdb_test "stepi" "fwait" "step forward one instruction for x87 test"
175
176    foreach {regname regvalue} [list "fctrl" "0x37f" \
177				    "fstat" "0x3800" \
178				    "ftag" "0x7777" \
179				    "fiseg" "0x12" \
180				    "fioff" "0x2418" \
181				    "foseg" "0x24" \
182				    "fooff" "0x36" \
183				    "fop" "0x100" ] {
184	gdb_test "p/x \$$regname" "= $regvalue" "check new value of $regname"
185    }
186}
187
188check_x87_regs_around_init
189check_setting_mxcsr_before_enable
190check_setting_x87_regs_before_enable
191