]>
Commit | Line | Data |
---|---|---|
1d506c26 | 1 | # Copyright 2018-2024 Free Software Foundation, Inc. |
8ee22052 AB |
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 | ||
9eeafef3 | 21 | require is_amd64_regs_target |
8ee22052 AB |
22 | |
23 | standard_testfile .S | |
24 | ||
25 | set options [list debug \ | |
26 | additional_flags=-static \ | |
27 | additional_flags=-nostartfiles] | |
98bf5c02 | 28 | if { [build_executable "failed to prepare" ${testfile} ${srcfile} $options] } { |
8ee22052 AB |
29 | return -1 |
30 | } | |
31 | ||
32 | # Start the test file, and check the x87 control registers (and | |
33 | # mxcsr), we expect the default values in all registers. | |
34 | # | |
35 | # Step forward until the x87 unit is enabled, recheck the register | |
36 | # values; they should still have the default values. | |
37 | # | |
38 | # Finally, step forward until the x87 state has changed, and then | |
39 | # recheck the register state to view the changes. | |
40 | proc_with_prefix check_x87_regs_around_init {} { | |
41 | global binfile | |
42 | ||
43 | clean_restart ${binfile} | |
44 | ||
45 | # Get things started. | |
75b6f386 | 46 | if {![runto_main]} { |
8ee22052 AB |
47 | return 0 |
48 | } | |
49 | ||
50 | # Check initial values of x87 control registers. The MXCSR isn't part | |
51 | # of the x87 set, it belongs with SSE/AVX, however we test it here | |
52 | # too, it should have its default value in both cases. | |
53 | foreach {regname regvalue} { "fctrl" "0x37f" \ | |
54 | "fstat" "0x0" \ | |
55 | "ftag" "0xffff" \ | |
56 | "fiseg" "0x0" \ | |
57 | "fioff" "0x0" \ | |
58 | "foseg" "0x0" \ | |
59 | "fooff" "0x0" \ | |
60 | "fop" "0x0" \ | |
61 | "mxcsr" "0x1f80"} { | |
62 | gdb_test "p/x \$${regname}" " = ${regvalue}" "check initial value of \$${regname}" | |
63 | } | |
64 | ||
65 | # No x87 instructions have been executed yet. Step up to FWAIT | |
66 | # instruction. Executing this instruction will enable the x87 unit, | |
67 | # causing the kernel to place the default values into all registers. | |
68 | # After this GDB will no longer supply the default values itself but | |
69 | # will instread read the values out of the xsave buffer. | |
70 | gdb_test "stepi" "fwait" "step to FWAIT instruction" | |
71 | gdb_test "stepi" "nop" "step past FWAIT instruction" | |
72 | ||
73 | # The x87 unit is now enabled, but the register values should be | |
74 | # unchanged. | |
75 | foreach {regname regvalue} { "fctrl" "0x37f" \ | |
76 | "fstat" "0x0" \ | |
77 | "ftag" "0xffff" \ | |
78 | "fiseg" "0x0" \ | |
79 | "fioff" "0x0" \ | |
80 | "foseg" "0x0" \ | |
81 | "fooff" "0x0" \ | |
82 | "fop" "0x0" \ | |
83 | "mxcsr" "0x1f80"} { | |
84 | gdb_test "p/x \$${regname}" " = ${regvalue}" "check post FWAIT value of \$${regname}" | |
85 | } | |
86 | ||
87 | # Now step to an x87 instruction that modifies some state. | |
88 | gdb_test "stepi" "fld1" "step to FLD1 instruction" | |
89 | ||
90 | # Grab the address of this instruction, it will appear in later | |
91 | # results. | |
92 | set addr [get_hexadecimal_valueof "\$pc" "0"] | |
93 | ||
94 | # Step past the FLD1 instruction. | |
95 | gdb_test "stepi" "nop" "step past FLD1 instruction" | |
96 | ||
97 | # Check new values of x87 control registers (and MXCSR). | |
98 | foreach {regname regvalue} [list "fctrl" "0x37f" \ | |
99 | "fstat" "0x3800" \ | |
100 | "ftag" "0x3fff" \ | |
101 | "fiseg" "0x0" \ | |
ebc76ef6 | 102 | "fioff" "($addr|0x0)" \ |
8ee22052 AB |
103 | "foseg" "0x0" \ |
104 | "fooff" "0x0" \ | |
105 | "fop" "0x0" \ | |
106 | "mxcsr" "0x1f80" ] { | |
107 | gdb_test "p/x \$${regname}" " = ${regvalue}" "check post FLD1 value of \$${regname}" | |
108 | } | |
109 | } | |
110 | ||
111 | # Start the test file, all FP features will be disabled. Set a new | |
112 | # value into the MXCSR register, then step forward one instruction (a | |
113 | # nop that does not enable any FP features). Finally check that the | |
114 | # mxcsr register still has the value we set. | |
115 | proc_with_prefix check_setting_mxcsr_before_enable {} { | |
3d435220 | 116 | global binfile gdb_prompt |
8ee22052 AB |
117 | |
118 | clean_restart ${binfile} | |
119 | ||
75b6f386 | 120 | if {![runto_main]} { |
8ee22052 AB |
121 | return 0 |
122 | } | |
123 | ||
124 | gdb_test_no_output "set \$mxcsr=0x9f80" "set a new value for MXCSR" | |
125 | gdb_test "stepi" "fwait" "step forward one instruction for mxcsr test" | |
3d435220 TV |
126 | |
127 | set test "check new value of MXCSR is still in place" | |
128 | set pass_pattern " = 0x9f80" | |
129 | # Pre-4.14 kernels have a bug (fixed by commit 0852b374173b "x86/fpu: | |
130 | # Add FPU state copying quirk to handle XRSTOR failure on Intel Skylake | |
131 | # CPUs") that causes mxcsr not to be copied, in which case we get 0 instead of | |
132 | # the just saved value. | |
133 | set xfail_pattern " = 0x0" | |
134 | gdb_test_multiple "p/x \$mxcsr" $test { | |
135 | -re "\[\r\n\]*(?:$pass_pattern)\[\r\n\]+$gdb_prompt $" { | |
136 | pass $test | |
137 | } | |
138 | -re "\[\r\n\]*(?:$xfail_pattern)\[\r\n\]+$gdb_prompt $" { | |
139 | xfail $test | |
140 | } | |
141 | } | |
8ee22052 AB |
142 | } |
143 | ||
144 | # Start the test file, all FP features will be disabled. Set new | |
145 | # values into the x87 control-registers, then step forward one | |
146 | # instruction (a nop that does not enable any FP features). Finally | |
147 | # check that all the x87 control-registers still have the values we | |
148 | # set. | |
149 | proc_with_prefix check_setting_x87_regs_before_enable {} { | |
150 | global binfile | |
151 | ||
152 | clean_restart ${binfile} | |
153 | ||
75b6f386 | 154 | if {![runto_main]} { |
8ee22052 AB |
155 | return 0 |
156 | } | |
157 | ||
158 | foreach {regname regvalue} [list "fctrl" "0x37f" \ | |
159 | "fstat" "0x3800" \ | |
160 | "ftag" "0x7777" \ | |
161 | "fiseg" "0x12" \ | |
162 | "fioff" "0x2418" \ | |
163 | "foseg" "0x24" \ | |
164 | "fooff" "0x36" \ | |
165 | "fop" "0x100" ] { | |
166 | gdb_test_no_output "set \$$regname=$regvalue" "set a new value for $regname" | |
167 | } | |
168 | ||
169 | gdb_test "stepi" "fwait" "step forward one instruction for x87 test" | |
170 | ||
171 | foreach {regname regvalue} [list "fctrl" "0x37f" \ | |
172 | "fstat" "0x3800" \ | |
173 | "ftag" "0x7777" \ | |
174 | "fiseg" "0x12" \ | |
175 | "fioff" "0x2418" \ | |
176 | "foseg" "0x24" \ | |
177 | "fooff" "0x36" \ | |
178 | "fop" "0x100" ] { | |
179 | gdb_test "p/x \$$regname" "= $regvalue" "check new value of $regname" | |
180 | } | |
181 | } | |
182 | ||
183 | check_x87_regs_around_init | |
184 | check_setting_mxcsr_before_enable | |
185 | check_setting_x87_regs_before_enable |