svn commit: r289332 - head/tools/regression/lib/msun

Bruce Evans brde at optusnet.com.au
Sat Oct 17 17:42:16 UTC 2015


On Sat, 17 Oct 2015, Konstantin Belousov wrote:

> On Thu, Oct 15, 2015 at 10:12:03PM +1100, Bruce Evans wrote:
>> On Thu, 15 Oct 2015, Konstantin Belousov wrote:
>>
>>> On Wed, Oct 14, 2015 at 08:22:12PM +0000, Garrett Cooper wrote:
>>>> Author: ngie
>>>> Date: Wed Oct 14 20:22:12 2015
>>>> New Revision: 289332
>>>> URL: https://svnweb.freebsd.org/changeset/base/289332
>>>>
>>>> Log:
>>>>   Fix test-fenv:test_dfl_env when run on some amd64 CPUs
>>>>
>>>>   Compare the fields that the AMD [1] and Intel [2] specs say will be
>>>>   set once fnstenv returns.
>>>>
>>>>   Not all amd64 capable processors zero out the env.__x87.__other field
>>>>   (example: AMD Opteron 6308). The AMD64/x64 specs aren't explicit on what the
>>>>   env.__x87.__other field will contain after fnstenv is executed, so the values
>>>>   in env.__x87.__other could be filled with arbitrary data depending on how the
>>>>   CPU-specific implementation of fnstenv.
>>> No Intel or AMD CPU write to __other field at all.
>>
>> No, they all do.
>>
>> Test on old i386 on old A64:
>> ...
> No, I did not thought about fegetenv() as executing FXSAVE instruction.
> I did knew that fegetenv() is a wrapper around FNSAVE, and I was completely
> sure that FNSAVE in the long mode, when executed by a 64bit program,
> never writes anything into the %eip/data offset portion of the FNSAVE
> area.  I suspect that this was motivated by unavoidable 32-bitness of
> the store format.

fegetenv() is actually a wrapper around FNSTENV, and FNSTENV is a subset
of FNSAVE.

> I was unable to find a reference in either Intel SDM or in AMD APM which
> would support my statement.  The closest thing is the claim that the FOP
> field is not filled, in the SDM.  Still, I wonder how things are really
> arranged by hardware for FNSAVE in 64bit mode.

Let's check FOP below.

> Are your experiments below were done for the 32bit programs, or for 64bit ?
> Both FXSAVE and XSAVE area formats and rules would be irrelevant for the
> FreeBSD ABI.

For amd64, I used the freefall default which I think is long mode, but
there is some magic for the pointer size (small model?)

BTW, -m32 has been broken on freefall for years.  At least libgcc.a is
incompatible or not installed.

>> ...
>> Modified state for fegetenv():
>> X 0000005C  7F 12 00 00 00 00 80 1F FF FF FF FF 63 82 04 08
>>              --cw- -mxhi --sw- -mxlo --tw- -pad- ----fip----
>>  					  -----------------
>> X 0000006C  1F 00 1D 05 A0 92 04 08 2F 00 FF FF
>>              -fcs- -opc- ----foff--- -fds- -pad-
>>  	    ----other[16]----------------------

FOP (opc) is clearly filled on i386 (32-bit mode).

>> ...
>> Test on -current amd64 on Xeon (freefall):
>> ...
>> Later fegetenv():
>> X 00000060  7f 03 ff ff 00 00 ff ff  ff ff ff ff 75 08 40 00
>> X 00000070  43 00 1c 05 20 62 60 00  3b 00 ff ff 80 1f 00 00

FOP is filled to 1c 05 on freefall and to 1D 05 on my old i386.  But the
instruction is the same (fstpl).  The difference is a different encoding
of the direct address mode.

Futher testing:

Only small model seems to be supported.  I got relocation errors with
messages about R_X86_64_32S for an array of size 4G.

malloc() works to allocate arrays larger than 4G.  Writing to addresses
above 4G in such arrays or on the stack never gave 64-bit offsets.
It truncated the offsets to 32 bits and still printed the segment
register.

Bruce


More information about the svn-src-head mailing list