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