Skip to content

Commit

Permalink
Workaround WSL misconfiguring the x87 FPU
Browse files Browse the repository at this point in the history
  • Loading branch information
jart committed Nov 2, 2022
1 parent f44d887 commit d6ff4c7
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 19 deletions.
26 changes: 26 additions & 0 deletions libc/runtime/cosmo.S
Original file line number Diff line number Diff line change
Expand Up @@ -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} │┌┤ ││││││
// ┌┤││ ││││││
// d││││rr││││││
1: .short 0b00000000000000000001101111111
.previous

#ifdef __FAST_MATH__
push %rax
stmxcsr (%rsp)
Expand Down
19 changes: 0 additions & 19 deletions libc/runtime/winmain.greg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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} │┌┤ ││││││
┌┤││ ││││││
d││││rr││││││*/
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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit d6ff4c7

Please sign in to comment.