From d6ff4c754e22f151a4c3b0a2550ad641f32e03f5 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Wed, 2 Nov 2022 02:17:14 -0700 Subject: [PATCH] Workaround WSL misconfiguring the x87 FPU --- libc/runtime/cosmo.S | 26 ++++++++++++++++++++++++++ libc/runtime/winmain.greg.c | 19 ------------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/libc/runtime/cosmo.S b/libc/runtime/cosmo.S index 1b6f67739..8d8459bf7 100644 --- a/libc/runtime/cosmo.S +++ b/libc/runtime/cosmo.S @@ -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) diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index bb3dfdd0c..91df13ba1 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -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; @@ -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);