Care to explain?

If it can be optimized the wrong way -- use a pragma or fix the compiler.

I hate these kinds of patches. I think Timo would agree.

Best regards,
Alex Ionescu


On Fri, Sep 30, 2011 at 5:03 PM, <dgorbachev@svn.reactos.org> wrote:
Author: dgorbachev
Date: Fri Sep 30 21:03:29 2011
New Revision: 53907

URL: http://svn.reactos.org/svn/reactos?rev=53907&view=rev
Log:
[NTOSKRNL]
Use inline asm in KiIsNpxErrataPresent(). C code can be optimized in a wrong way.

Modified:
   trunk/reactos/ntoskrnl/ke/i386/cpu.c

Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev=53907&r1=53906&r2=53907&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] Fri Sep 30 21:03:29 2011
@@ -1254,9 +1254,9 @@
 INIT_FUNCTION
 KiIsNpxErrataPresent(VOID)
 {
-    BOOLEAN ErrataPresent;
+    static double Value1 = 4195835.0, Value2 = 3145727.0;
+    INT ErrataPresent;
    ULONG Cr0;
-    volatile double Value1, Value2;

    /* Disable interrupts */
    _disable();
@@ -1269,9 +1269,30 @@
    Ke386FnInit();

    /* Multiply the magic values and divide, we should get the result back */
-    Value1 = 4195835.0;
-    Value2 = 3145727.0;
-    ErrataPresent = (Value1 * Value2 / 3145727.0) != 4195835.0;
+#ifdef __GNUC__
+    __asm__ __volatile__
+    (
+        "fldl %1\n\t"
+        "fdivl %2\n\t"
+        "fmull %2\n\t"
+        "fldl %1\n\t"
+        "fsubp\n\t"
+        "fistpl %0\n\t"
+        : "=m" (ErrataPresent)
+        : "m" (Value1),
+          "m" (Value2)
+    );
+#else
+    __asm
+    {
+        fld Value1
+        fdiv Value2
+        fmul Value2
+        fld Value1
+        fsubp
+        fistp ErrataPresent
+    };
+#endif

    /* Restore CR0 */
    __writecr0(Cr0);
@@ -1280,7 +1301,7 @@
    _enable();

    /* Return if there's an errata */
-    return ErrataPresent;
+    return ErrataPresent != 0;
 }

 VOID