https://git.reactos.org/?p=reactos.git;a=commitdiff;h=faedd8ff756f41cc2bf7e…
commit faedd8ff756f41cc2bf7edbee1be17d1532dcce9
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sun Oct 13 10:56:28 2024 +0300
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Thu Jan 16 14:18:53 2025 +0200
[UCRT] Use GCC inline assembler
Clang requires the asm to be split, otherwise it complains that it doesn't have
enough registers.
---
sdk/include/ucrt/fenv.h | 4 +++
sdk/lib/ucrt/inc/corecrt_internal_big_integer.h | 18 ++++++++++++-
sdk/lib/ucrt/misc/invalid_parameter.cpp | 34 ++++++++++++++++++++++++-
3 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/sdk/include/ucrt/fenv.h b/sdk/include/ucrt/fenv.h
index d5ac594ebd9..6384e4697b5 100644
--- a/sdk/include/ucrt/fenv.h
+++ b/sdk/include/ucrt/fenv.h
@@ -130,7 +130,11 @@ _ACRTIMP int __cdecl fesetround(_In_ int _Round);
// next floating point instruction. If we're using /arch:IA32,
// force the exception to be raised immediately:
#if defined _M_IX86 && _M_IX86_FP == 0 && !defined
_M_HYBRID_X86_ARM64
+ #ifdef _MSC_VER
__asm fwait;
+ #else
+ __asm__ __volatile__("fwait");
+ #endif
#endif
}
}
diff --git a/sdk/lib/ucrt/inc/corecrt_internal_big_integer.h
b/sdk/lib/ucrt/inc/corecrt_internal_big_integer.h
index 817eae6ea11..e97db5cfbbd 100644
--- a/sdk/lib/ucrt/inc/corecrt_internal_big_integer.h
+++ b/sdk/lib/ucrt/inc/corecrt_internal_big_integer.h
@@ -686,6 +686,7 @@ __forceinline uint32_t __cdecl count_sequential_high_zeroes(uint32_t
const u) th
uint32_t const multiplier
) throw()
{
+ #ifdef _MSC_VER
__asm
{
mov eax, dword ptr [multiplicand + 4]
@@ -698,6 +699,21 @@ __forceinline uint32_t __cdecl count_sequential_high_zeroes(uint32_t
const u) th
add edx, ecx
}
+ #else // ^^^ _MSC_VER ^^^ // vvv !_MSC_VER vvv //
+ uint64_t retval;
+ __asm__(
+ "mull %[multiplier]\n"
+ "movl %%eax, %%ecx\n"
+ "movl %[multiplicand_lo], %%eax\n"
+ "mull %[multiplier]\n"
+ "addl %%ecx, %%edx\n"
+ : "=A" (retval)
+ : [multiplicand_hi] "a" ((uint32_t)((multiplicand >> 32)
& 0xFFFFFFFF)),
+ [multiplicand_lo] "rm" ((uint32_t)((multiplicand >> 0)
& 0xFFFFFFFF)),
+ [multiplier] "rm" (multiplier)
+ : "ecx" );
+ return retval;
+ #endif // !_MSC_VER
}
#else
__forceinline uint64_t __cdecl multiply_64_32(
@@ -869,7 +885,7 @@ inline uint64_t __cdecl divide(
}
// Multiply and subtract. Note that uu_quo may be one too large. If
- // we have a borrow at the end, we'll add the denominator back on and
+ // we have a borrow at the end, we'll add the denominator back on and
// decrement uu_quo.
if (uu_quo > 0)
{
diff --git a/sdk/lib/ucrt/misc/invalid_parameter.cpp
b/sdk/lib/ucrt/misc/invalid_parameter.cpp
index accd35f348a..7865ca156db 100644
--- a/sdk/lib/ucrt/misc/invalid_parameter.cpp
+++ b/sdk/lib/ucrt/misc/invalid_parameter.cpp
@@ -166,7 +166,38 @@ extern "C" __declspec(noreturn) void __cdecl
_invalid_parameter_noinfo_noreturn(
EXCEPTION_POINTERS ExceptionPointers = {&ExceptionRecord,
&ContextRecord};
#ifdef _M_IX86
-
+ #if defined(__GNUC__) || defined(__clang__)
+ __asm__ __volatile__(
+ "movl %%eax, %[CxEax]\n\t"
+ "movl %%ecx, %[CxEcx]\n\t"
+ "movl %%edx, %[CxEdx]\n\t"
+ "movl %%ebx, %[CxEbx]\n\t"
+ "movl %%esi, %[CxEsi]\n\t"
+ "movl %%edi, %[CxEdi]\n\t"
+ : [CxEax] "=m" (ContextRecord.Eax),
+ [CxEcx] "=m" (ContextRecord.Ecx),
+ [CxEdx] "=m" (ContextRecord.Edx),
+ [CxEbx] "=m" (ContextRecord.Ebx),
+ [CxEsi] "=m" (ContextRecord.Esi),
+ [CxEdi] "=m" (ContextRecord.Edi));
+ __asm__ __volatile__(
+ "movw %%ss, %[CxSegSs]\n\t"
+ "movw %%cs, %[CxSegCs]\n\t"
+ "movw %%ds, %[CxSegDs]\n\t"
+ "movw %%es, %[CxSegEs]\n\t"
+ "movw %%fs, %[CxSegFs]\n\t"
+ "movw %%gs, %[CxSegGs]\n\t"
+ : [CxSegSs] "=m" (ContextRecord.SegSs),
+ [CxSegCs] "=m" (ContextRecord.SegCs),
+ [CxSegDs] "=m" (ContextRecord.SegDs),
+ [CxSegEs] "=m" (ContextRecord.SegEs),
+ [CxSegFs] "=m" (ContextRecord.SegFs),
+ [CxSegGs] "=m" (ContextRecord.SegGs));
+ __asm__ __volatile__(
+ "pushfl\n\t"
+ "popl %[CxEFlags]\n\t"
+ : [CxEFlags] "=m" (ContextRecord.EFlags));
+ #else // ^^^ __GNUC__ ^^^ // vvv !__GNUC__ vvv //
__asm
{
mov dword ptr [ContextRecord.Eax ], eax
@@ -184,6 +215,7 @@ extern "C" __declspec(noreturn) void __cdecl
_invalid_parameter_noinfo_noreturn(
pushfd
pop [ContextRecord.EFlags]
}
+ #endif // !__GNUC__
ContextRecord.ContextFlags = CONTEXT_CONTROL;