Current version

v1.10.4 (stable)


Main page
Archived news
Plugin SDK
Knowledge base
Contact info
Other projects


Blog Archive

x87/MMX code on x64 applications in Windows

There seems to be some confusion about whether legacy x87/MMX registers and instructions can be used in 64-bit code that runs on the x64 Edition of Windows. Part of the reason for this confusion is due to some early x64 ABI documentation that was published in the Windows Driver Development Kit (DDK):

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.

This statement led many to believe (including me) that x87/MMX code could not be used at all in x64 applications, despite it being supported by the CPU in long mode, and even on other operating systems, i.e. Linux. This didn't make sense, given that FXSAVE and FXRSTOR push those registers along with the SSE registers. Empirical testing, however, confirmed that the registers are saved and restored in user mode, and using them seemed to incur no ill effects. Fortunately, this was later cleared up by the SWConventions.doc file in recent Platform SDKs, and finally made official in the x64 calling conventions documentation that shipped with Visual Studio 2005:

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.

At this point, I believe there is no harm in using x87 or MMX code on x64. It is annoying to do so, since the compiler neither supports inline assembly nor MMX intrinsics, and so you have to use ML64 and explicit assembly, but it will work. Now, whether you should is a different question. There are some constructs that don't necessarily translate well from MMX to SSE2, and I don't see it as a given that code will run faster when rewritten to use the latter, at least without major redesign. Adapting legacy code is also not trivial since you have to rewrite it for 64-bit pointers and to have the correct function prologues and epilogues. At least, though, it does seem that you have a choice.


This blog was originally open for comments when this entry was first posted, but was later closed and then removed due to spam and after a migration away from the original blog software. Unfortunately, it would have been a lot of work to reformat the comments to republish them. The author thanks everyone who posted comments and added to the discussion.