example-greenthreads
example-greenthreads copied to clipboard
Saving x87 and SSE control words
According to the x86-64 System V ABI, the x87 control word and the SSE2 control and status word are also callee-saved, yet the switch
function doesn't save and restore them. I seem to remember that an older version of this book did this. Is that an intentional omission to keep the code simpler?
It's intentional (well, at least I considered them non-essential for a correct implementation). When checking my work I did compare it with other similar implementations, for example the context swap used in boost.org's implementation. It seems they only store/restore that information when compiled with BOOST_USE_TSX
, and further research led me to this explanation. I also got the chance later on to look into Crystals fiber implementation, which omits them as well.
However, I've yet to find one authoritative source on the requirements for a correct context switch, so if you have any additional information and/or can point me to some information I'm always open to reconsider.
I don't think an earlier version had it, but the Windows context switch does indeed store/restore a lot more information, so it might be that one you remembered?
[edit: accidentally posted with wrong account]
It seems they only store/restore that information when compiled with
BOOST_USE_TSX
I think you're mistaken: They save/restore it when compiled without TSX support: #if !defined(BOOST_USE_TSX) ...
As for Crystal, maybe they control code generation to a degree that they know their code won't modify those two control words.
For what it's worth, Rust/LLVM doesn't seem to save/restore the MXCSR
register, even when it's modified using intrinsics; playground link:
playground::test_1:
push rax
mov dword ptr [rsp + 4], 65535
ldmxcsr dword ptr [rsp + 4]
call qword ptr [rip + test_2@GOTPCREL]
mov dword ptr [rsp], 0
stmxcsr dword ptr [rsp]
mov eax, dword ptr [rsp]
pop rcx
ret
However, I don't know whether that's intentional or a bug.
My uneducated guess is that omitting the save/restore will probably work fine, except for that one-in-a-million case where an externally compiled math library calls the green thread yield()
function :wink: Or until LLVM starts setting and using the SSE2 rounding modes, for whatever reason...
I think you're mistaken: They save/restore it when compiled without TSX support: #if !defined(BOOST_USE_TSX) ...
Aha, so that makes sense, I have missed that "!" twice now (both when first researching and when I checked yesterday). I now appreciate Rust's verbose #[cfg(not(...))]
a bit more than before. Thanks for pointing that out.
However, I don't know whether that's intentional or a bug.
😂 Well, my guess is as good as yours on that one. I've seen several examples of stack swaps (just haven't got all the links easily at hand) omitting these registers, but I don't know if that's intentional or not either.
My uneducated guess is that omitting the save/restore will probably work fine, except for that one-in-a-million case where an externally compiled math library calls the green thread yield() function 😉 Or until LLVM starts setting and using the SSE2 rounding modes, for whatever reason...
Well, the right thing is probably to save/restore them anyway, it's not a big additional cost, and it can prevent hard to find bugs later on. It's not critical though so I feel it's OK to save that for when I have time to make a revision to the book.
Do you have the link to where in the system v abi documentation the x87 control word and SSE2 control and status word is covered? It's nice to have since I have to update the book on the part with callee saved registers and would like to point to some resource.
Well, the right thing is probably to save/restore them anyway, it's not a big additional cost, and it can prevent hard to find bugs later on. It's not critical though so I feel it's OK to save that for when I have time to make a revision to the book.
Agreed on both points.
Link to the rendered ABI docs, just search for MXCSR
in the newest version. The Intel 64 and IA-32 Architectures Software Developer’s Manual, volume 1, chapter 10.2.3 "MXCSR Control and Status Register" has more detailed info; same goes for the x87 control word.
Great, thanks 👍