|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2007-02-06 16:34:48
Jerry Lawson wrote:
> The cas _asm_ instruction for the gcc/sparc environment has a slight
> flaw:
> it does not prevent the gcc compiler from generating assembly that
> contains
> a invalid register/offset. In other words, the existing _asm_ can
> cause gcc to generate something like:
>
> cas [%i0+80], %i1, %i2
>
> the relative offset is an illegal address mode for cas instruction.
>
> I'm not a sparc assembly guy, by any stretch of the imagination, but
> doing some reading at
> http://blogs.sun.com/wesolows/entry/gcc_inline_assembly_part_2 would
> seem to indicate that this code:
>
> inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_,
> int32_t swap_ )
> {
> __asm__ __volatile__( "cas %0, %2, %1"
>
> : "+m" (*dest_), "+r" (swap_)
> : "r" (compare_)
> : "memory" );
>
> return swap_;
> }
>
>
> is not exactly correct. When using -O3 optimization option to gcc, the
> aforementioned "bad" cas instruction is generated.
Sounds like a gcc bug. Which versions of gcc have you tried?
> I'm done some experimenting and with the following code, gcc seems to
> generate the proper code:
>
> inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_,
> int32_t swap_ )
> {
> __asm__ __volatile__( "cas [%2], %3, %0"
>
> : "=&r" (swap_)
> : "0" (swap_), "r" (dest_), "r" (compare_)
> : "memory" );
>
> return swap_;
> }
We might be able to use that as a fix if it works, but it's not correct in
principle. One case where it fails is on 64 bit machines that use 32 bit
pointers. This may not be a problem on SPARCs though.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk