In my defense, it was the documents of AMD, Intel, and Microsoft that lead me astray.Dann Corbit wrote:Apparently, my information was dated. Here is the latest from Anger Fogg's assembly reference:rbarreira wrote:Again, that doesn't refer to context switching. It refers to keeping full-precision when not requested by the source code, which may give different results from stricter code generation which rounds and writes to memory (to a data type with less precision) at every assignment operator in the source code.Dann Corbit wrote:Imagine this bit in all caps:Dann Corbit wrote:"Improves the consistency of floating-point tests for equality and inequality by disabling optimizations that could change the precision of floating-point calculations, which is required for strict ANSI conformance. By default, the compiler uses the coprocessor's 80-bit registers to hold the intermediate results of floating-point calculations. This increases program speed and decreases program size. Because the calculation involves floating-point data types that are represented in memory by less than 80 bits, however, carrying the extra bits of precision (80 bits minus the number of bits in a smaller floating-point type) through a lengthy calculation can produce inconsistent results."rbarreira wrote:In memory, probably using these instructions or similar, which as mentioned in the link save and restore "the entire floating-point unit state".Dann Corbit wrote: And if an intermediate calculation for the product of 2 8 byte floats is stored in an 80 bit register and an IRQ fires, the data is stored where?
I read it. It doesn't talk about IRQs or context switches at all, only about code generation, just as every compiler documentation I've seen about floating point optimization options.Dann Corbit wrote:Why not read this:
http://msdn.microsoft.com/en-us/library/e7s85ffb.aspx
And specifically where they talk about 80 bit operations and loss of precision
Because the calculation involves floating-point data types that are represented in memory by less than 80 bits, however, carrying the extra bits of precision (80 bits minus the number of bits in a smaller floating-point type) through a lengthy calculation can produce inconsistent results.
Until you find even a single authoritative source which talks about loss of fp precision on context switching in, say, Windows or Linux, I'm going to ignore further posts in this thread...6.1 Can floating point registers be used in 64-bit Windows?
There has been widespread confusion about whether 64-bit Windows allows the use of the
floating point registers ST(0)-ST(7) and the MM0 - MM7 registers that are aliased upon
these. One early technical document found at Microsoft’s website says "x87/MMX registers
are unavailable to Native Windows64 applications" (Rich Brunner: Technical Details Of
Microsoft® Windows® For The AMD64 Platform, Dec. 2003). An AMD document says: "64-
bit Microsoft Windows does not strongly support MMX and 3Dnow! instruction sets in the
64-bit native mode" (Porting and Optimizing Multimedia Codecs for AMD64 architecture on
Microsoft® Windows®, July 21, 2004). A document in Microsoft’s MSDN says: "A caller
must also handle the following issues when calling a callee: [...] Legacy Floating-Point
Support: The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are volatile. That
is, these legacy floating-point stack registers do not have their state preserved across
context switches" (MSDN: Kernel-Mode Driver Architecture: Windows DDK: Other Calling
Convention Process Issues. Preliminary, June 14, 2004; February 18, 2005). This
description is nonsense because it confuses saving registers across function calls and
saving registers across context switches. Some versions of the Microsoft assembler ml64
(e.g. v. 8.00.40310) gives the following message when attempts are made to use floating
point registers in 64 bit mode: "error A2222: x87 and MMX instructions disallowed; legacy
FP state not saved in Win64".
However, a public discussion forum quotes the following answers from Microsoft engineers
regarding this issue: "From: Program Manager in Visual C++ Group, Sent: Thursday, May
26, 2005 10:38 AM. It does preserve the state. It’s the DDK page that has stale information,
which I’ve requested it to be changed. Let them know that the OS does preserve state of
x87 and MMX registers on context switches." and "From: Software Engineer in Windows
Kernel Group, Sent: Thursday, May 26, 2005 11:06 AM. For user threads the state of legacy
floating point is preserved at context switch. But it is not true for kernel threads. Kernel
mode drivers can not use legacy floating point instructions."
(www.planetamd64.com/index.php?showtopic=3458&st=100).
The issue has finally been resolved with the long overdue publication of a more detailed ABI
for x64 Windows in the form of a document entitled "x64 Software Conventions", well hidden
in the bin directory (not the help directory) of some compiler packages. This document says:
"The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved across
context switches. There is no explicit calling convention for these registers. The use of
these registers is strictly prohibited in kernel mode code." The same text has later appeared
at the Microsoft website (msdn2.microsoft.com/en-us/library/a32tsf7t(VS.80).aspx).
My tests indicate that these registers are saved correctly during task switches and thread
switches in 64-bit mode, even in an early beta version of x64 Windows.
The Microsoft C++ compiler version 14.0 never uses these registers in 64-bit mode, and
doesn’t support long double precision. The Intel C++ compiler for x64 Windows supports
long double precision and __m64 in version 9.0 and later, while earlier versions do not.
The conclusion is that it is safe to use floating point registers and MMX registers in 64-bit
Windows, except in kernel mode drivers.
See also:
http://www.rhinocerus.net/forum/lang-as ... ister.html