DEADSOFTWARE

Fix compilation errors when building Windows EXE for amd64 target
authorDmitry D. Chernov <blackdoomer@yandex.ru>
Mon, 20 Sep 2021 03:27:16 +0000 (13:27 +1000)
committerDmitry D. Chernov <blackdoomer@yandex.ru>
Mon, 20 Sep 2021 03:27:16 +0000 (13:27 +1000)
On Windows for amd64 (64-bit, x64), the x87 FPU had been forbidden in kernel-mode for ABI reasons and declared as deprecated in user-mode:
https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-floating-point-or-mmx-in-a-wdm-driver
https://docs.microsoft.com/en-us/windows/win32/dxtecharts/sixty-four-bit-programming-for-game-developers#porting-applications-to-64-bit-platforms

Nevertheless, currently it can still be used (just like in Linux for amd64), and this will remain as long as Windows thread scheduler preserves x87 internal machine state across context switches. That's the reason why FPC doesn't support it by default but only when built with FPC_SUPPORT_X87_TYPES_ON_WIN64 defined. So the only proper and correct way is to use FPC_HAS_TYPE_EXTENDED to determine if standard 'Extended' type is available.

It's also worth noting that FPC_SOFT_FPUX80 and FPC_SOFTFLOAT_FLOATX80 (other FPC compilation switches) seem to be irrelevant in this case - they're intended to make the compiler able to perform cross-compilation for x86 on non-x86 systems:
https://gitlab.com/freepascal.org/fpc/source/-/issues/9262
https://forum.lazarus.freepascal.org/index.php?topic=29678.0
https://lists.freepascal.org/fpc-devel/2020-September/043174.html

Some other links I found useful when investigating this case:
https://lists.freepascal.org/fpc-pascal/2017-August/052158.html (and subsequent mails in this thread)
https://www.virtualdub.org/blog2/entry_107.html
http://www.asmcommunity.net/forums/topic/?id=30178
https://forum.lazarus.freepascal.org/index.php/topic,43878.msg307985.html#msg307985
https://forum.lazarus.freepascal.org/index.php?topic=49890.0
https://stackoverflow.com/questions/4064189/floating-point-support-in-64-bit-compiler
https://stackoverflow.com/questions/15176290/what-is-long-double-on-x86-64
https://stackoverflow.com/questions/3206101/extended-80-bit-double-floating-point-in-x87-not-sse2-we-dont-miss-it
https://retrocomputing.stackexchange.com/questions/9751/did-any-compiler-fully-use-intel-x87-80-bit-floating-point

Although this commit fixes the compilation, the 64-bit builds are still unusable because we're lacking 64-bit libraries in d2df-binlib at the moment, thus making such EXE complaining on existing DLLs with INVALID_IMAGE_FORMAT (0xC000007B) at startup.

src/shared/utils.pas

index 26150aa3f2e4627706b19df003439de4c7d4a045..c0ba824a9615188a05e25f4b0ac835f22bef2ffd 100644 (file)
@@ -207,7 +207,7 @@ function nmin (a, b: Int64): Int64; inline; overload;
 function nmin (a, b: UInt64): UInt64; inline; overload;
 function nmin (a, b: Single): Single; inline; overload;
 function nmin (a, b: Double): Double; inline; overload;
-{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
+{$IFDEF FPC_HAS_TYPE_EXTENDED}
 function nmin (a, b: Extended): Extended; inline; overload;
 {$ENDIF}
 
@@ -221,7 +221,7 @@ function nmax (a, b: Int64): Int64; inline; overload;
 function nmax (a, b: UInt64): UInt64; inline; overload;
 function nmax (a, b: Single): Single; inline; overload;
 function nmax (a, b: Double): Double; inline; overload;
-{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
+{$IFDEF FPC_HAS_TYPE_EXTENDED}
 function nmax (a, b: Extended): Extended; inline; overload;
 {$ENDIF}
 function nclamp (v, a, b: Byte): Byte; inline; overload;
@@ -234,7 +234,7 @@ function nclamp (v, a, b: Int64): Int64; inline; overload;
 function nclamp (v, a, b: UInt64): UInt64; inline; overload;
 function nclamp (v, a, b: Single): Single; inline; overload;
 function nclamp (v, a, b: Double): Double; inline; overload;
-{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
+{$IFDEF FPC_HAS_TYPE_EXTENDED}
 function nclamp (v, a, b: Extended): Extended; inline; overload;
 {$ENDIF}
 
@@ -1547,7 +1547,7 @@ function nmin (a, b: Int64): Int64; inline; overload; begin if (a < b) then resu
 function nmin (a, b: UInt64): UInt64; inline; overload; begin if (a < b) then result := a else result := b; end;
 function nmin (a, b: Single): Single; inline; overload; begin if (a < b) then result := a else result := b; end;
 function nmin (a, b: Double): Double; inline; overload; begin if (a < b) then result := a else result := b; end;
-{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
+{$IFDEF FPC_HAS_TYPE_EXTENDED}
 function nmin (a, b: Extended): Extended; inline; overload; begin if (a < b) then result := a else result := b; end;
 {$ENDIF}
 
@@ -1561,7 +1561,7 @@ function nmax (a, b: Int64): Int64; inline; overload; begin if (a > b) then resu
 function nmax (a, b: UInt64): UInt64; inline; overload; begin if (a > b) then result := a else result := b; end;
 function nmax (a, b: Single): Single; inline; overload; begin if (a > b) then result := a else result := b; end;
 function nmax (a, b: Double): Double; inline; overload; begin if (a > b) then result := a else result := b; end;
-{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
+{$IFDEF FPC_HAS_TYPE_EXTENDED}
 function nmax (a, b: Extended): Extended; inline; overload; begin if (a > b) then result := a else result := b; end;
 {$ENDIF}
 
@@ -1575,7 +1575,7 @@ function nclamp (v, a, b: Int64): Int64; inline; overload; begin if (v < a) then
 function nclamp (v, a, b: UInt64): UInt64; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
 function nclamp (v, a, b: Single): Single; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
 function nclamp (v, a, b: Double): Double; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
-{$IF DEFINED(CPU386) OR DEFINED(CPUAMD64)}
+{$IFDEF FPC_HAS_TYPE_EXTENDED}
 function nclamp (v, a, b: Extended): Extended; inline; overload; begin if (v < a) then result := a else if (v > b) then result := b else result := v; end;
 {$ENDIF}