I have a function that needs to be as fast as possible, and it uses only integer operations. It runs on the AMD64 architecture, and I need to do a few push/pops in order to have enough registers to work with. Now I'm wondering, the x64 ABI states that the first four floating-point registers (XMM0, XMM1, XMM2, and XMM3) are volatile and do not need to be preserved across function calls.
So I figured I could store the 64-bit registers I need to preserve in the lower 64 bits of those registers (i.e. MM0, MM1, ...) via movq (MMX or SSE instruction set) instead of using the stack, saving myself a few memory load/stores. Furthermore I wouldn't need to store the FPU state using EMMS - which would defeat the purpose - since I am not actually manipulating the floating-point registers but only using them as storage (and anyway, the x87 unit is hardly used at all under x64, as it is essentially superseded by SSE)
I have done the modification and it works (no crashes, and an observable 4% increase in performance), but I am wondering, does this "hack" really work or would it introduce any particular side effects I might have missed (like FPU state corruption even though I don't use it, that sort of thing). And will load/storing to an FPU register always be faster than a memory load/store on any current architecture?
And, yes, this optimization is really needed. And to be fair, this isn't something that would severely degrade code maintenance cost, a one-line comment would be enough to explain the trick. So if I can get a couple less clocks per byte for free with no unintended consequences, I'll gladly take them :)
Thanks.