On Tue, 2010-02-09 at 14:44 -0800, Mostyn Lewis wrote:
> The old opal_atomic_cmpset_32 worked:
> 
> static inline int opal_atomic_cmpset_32( volatile int32_t *addr,
>     unsigned char ret;
>     __asm__ __volatile__ (
>                         SMPLOCK "cmpxchgl %1,%2   \n\t"
>                                 "sete     %0      \n\t"
>                         : "=qm" (ret)
>                         : "q"(newval), "m"(*addr), "a"(oldval)
>                         : "memory");
> 
>     return (int)ret; 
> }
> 
> The new opal_atomic_cmpset_32 fails:
> 
> static inline int opal_atomic_cmpset_32( volatile int32_t *addr,
>                                          int32_t oldval, int32_t newval)
> {
>     unsigned char ret;
>     __asm__ __volatile__ (
>                         SMPLOCK "cmpxchgl %3,%4   \n\t"
>                                 "sete     %0      \n\t"
>                         : "=qm" (ret), "=a" (oldval), "=m" (*addr)
>                         : "q"(newval), "m"(*addr), "1"(oldval)
>     return (int)ret;
> }
> 
> **However** if you put back the "clobber" for memory line (3rd :), it works:
> 
> static inline int opal_atomic_cmpset_32( volatile int32_t *addr,
>                                          int32_t oldval, int32_t newval)
> {
>     unsigned char ret;
>     __asm__ __volatile__ (
>                         SMPLOCK "cmpxchgl %3,%4   \n\t"
>                                 "sete     %0      \n\t"
>                         : "=qm" (ret), "=a" (oldval), "=m" (*addr)
>                         : "q"(newval), "m"(*addr), "1"(oldval)
>                         : "memory");
> 
>     return (int)ret;
> }
> 
> This works in a test case for pathcc, gcc, icc, pgcc, SUN studio cc and 
> open64 (pathscale
> lineage - which also fails with 1.4.1).
> Also the SMPLOCK above is defined as "lock; " - the ";" is a GNU as statement 
> delimter - is
> that right? Seems to work with/without the ";".
> 
> 
> Also, a question - I see you generate via perl another "lock" asm file which 
> you put into
> opal/asm/generated/<whatever, e.g. atomic-amd64-linux.s> and stick into 
> libasm - what you
> generate there for whatever usage hasn't changed 1.4->1.4.1->svn trunk?

According to people who knows asm statements fairly well (compiler
developers), it should be
static inline int opal_atomic_cmpset_32( volatile int32_t *addr,
                                         int32_t oldval, int32_t newval)
{
    unsigned char ret;
    __asm__ __volatile__ (
                        SMPLOCK "cmpxchgl %3,%2   \n\t"
                                "sete     %0      \n\t"
                        : "=qm" (ret), "=a" (oldval), "=m" (*addr)
                        : "q"(newval), "2"(*addr), "1"(oldval)
                        : "memory", "cc");

    return (int)ret;
}

-- 
Ake Sandgren, HPC2N, Umea University, S-90187 Umea, Sweden
Internet: a...@hpc2n.umu.se   Phone: +46 90 7866134 Fax: +46 90 7866126
Mobile: +46 70 7716134 WWW: http://www.hpc2n.umu.se

Reply via email to