example-greenthreads icon indicating copy to clipboard operation
example-greenthreads copied to clipboard

Saving x87 and SSE control words

Open adrianwn opened this issue 2 years ago • 5 comments

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?

adrianwn avatar Feb 12 '22 06:02 adrianwn

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?

cfsamson avatar Feb 13 '22 00:02 cfsamson

[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...

adrianwn avatar Feb 13 '22 06:02 adrianwn

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.

cfsamson avatar Feb 13 '22 12:02 cfsamson

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.

adrianwn avatar Feb 13 '22 19:02 adrianwn

Great, thanks 👍

cfsamson avatar Feb 13 '22 22:02 cfsamson