Workaround WSL misconfiguring the x87 FPU

This commit is contained in:
Justine Tunney 2022-11-02 02:17:14 -07:00
parent f44d88707e
commit d6ff4c754e
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
2 changed files with 26 additions and 19 deletions

View file

@ -44,6 +44,32 @@ cosmo: push %rbp
mov %eax,%r12d
#endif /* SYSDEBUG */
// Windows always initializes FPU to douuble precision.
// WSL breaks Linux ABI by initializing FPU to double precision.
// This code makes long double long again.
//
// @see System V Application Binary Interface NexGen32e Architecture
// Processor Supplement, Version 1.0, December 5th, 2018
// Section 3.4.1: Initial Stack and Register State
fldcw 1f(%rip)
.rodata
.align 2
// 8087 FPU Control Word
// IM: Invalid Operation
// DM: Denormal Operand
// ZM: Zero Divide
// OM: Overflow
// UM: Underflow
// PM: Precision
// PC: Precision Control
// {float,,double,long double}
// RC: Rounding Control
// {even, -, +, 0}
//
// drr
1: .short 0b00000000000000000001101111111
.previous
#ifdef __FAST_MATH__
push %rax
stmxcsr (%rsp)

View file

@ -76,24 +76,6 @@ static const short kConsoleModes[3] = {
kNtEnableVirtualTerminalProcessing,
};
forceinline void MakeLongDoubleLongAgain(void) {
/* 8087 FPU Control Word
IM: Invalid Operation
DM: Denormal Operand
ZM: Zero Divide
OM: Overflow
UM: Underflow
PM: Precision
PC: Precision Control
{float,,double,long double}
RC: Rounding Control
{even, -, +, 0}
drr*/
int x87cw = 0b0000000000000000001101111111;
asm volatile("fldcw\t%0" : /* no outputs */ : "m"(x87cw));
}
// https://nullprogram.com/blog/2022/02/18/
static inline char16_t *MyCommandLine(void) {
void *cmd;
@ -259,7 +241,6 @@ __msabi textwindows int64_t WinMain(int64_t hInstance, int64_t hPrevInstance,
if (__strstr16(cmdline, u"--strace")) ++__strace;
#endif
NTTRACE("WinMain()");
MakeLongDoubleLongAgain();
if (_weaken(WinSockInit)) _weaken(WinSockInit)();
if (_weaken(WinMainForked)) _weaken(WinMainForked)();
WinMainNew(cmdline);