fixes to PPC version of cas(), from David Kirkman <dkirkman@gmail.com>
authorSimon Marlow <simonmar@microsoft.com>
Mon, 21 Aug 2006 15:31:36 +0000 (15:31 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Mon, 21 Aug 2006 15:31:36 +0000 (15:31 +0000)
From David's email:
The problem is that the inline assembler code was placing the result
of an operation in a register that is used as input later in the code.
At the bottom of this message I've extracted a short short code
fragment that you can run through gcc (on a powerpc machine) to see
the generated assembly output.

The changes to fix the problem are fairly simple.  The first adds an
ampersand to the output list of the assembly fragment ("=r" (result)
--> "=&r" (result)) The ampersand just tells gcc that result can not
be placed in a register used for any of the input parameters (o, n, or
p).  Otherwise, it feels free to place output parameters in the same
registers used by the inputs -- but because of the flow of control
here we need everything in a distinct register.  This change fixes the
TVar program above.

The second change adds a clobber list (the :"cc", "memory").  This
tells gcc that the condition code (due to the compare) and memory (due
to the store) might be changed during the asm execution.  The lack of
a clobber list did not seem to be causing any trouble, but without it
gcc is free to assume that no state is changed during the execution.

includes/SMP.h

index 68f1690..515516a 100644 (file)
@@ -76,8 +76,9 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
         "       stwcx.    %2, 0, %3\n"
         "       bne-      1b\n"
         "2:"
-        :"=r" (result)
+        :"=&r" (result)
         :"r" (o), "r" (n), "r" (p)
+        :"cc", "memory"
     );
     return result;
 #else