https://git.reactos.org/?p=reactos.git;a=commitdiff;h=faedd8ff756f41cc2bf7edbee1be17d1532dcce9

commit faedd8ff756f41cc2bf7edbee1be17d1532dcce9
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Sun Oct 13 10:56:28 2024 +0300
Commit:     Timo Kreuzer <[email protected]>
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;
 

Reply via email to