This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

atomic asms and GCC 3.4.0


I'm trying to get some code of ours to work with GCC 3.4.0, and I'm
running into some problems with some asms we use for atomic
operations.  (These were originally taken from a header originally
written by Doug Rabson, for what it's worth.)

The macros originally said:

#define MPLOCKED        "lock ; "

/*
 * The assembly is volatilized to demark potential before-and-after side
 * effects if an interrupt or SMP collision were to occur.
 */
#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V)             \
static inline __attribute__((__always_inline__)) void   \
atomic_##NAME##_##TYPE(volatile unsigned TYPE *p, unsigned TYPE v)\
{                                                       \
        __asm __volatile(MPLOCKED OP                    \
                         : "+m" (*p)                    \
                         : CONS (V));                   \
}

ATOMIC_ASM(set,      long,  "orl %1,%0",   "ir",  v);
ATOMIC_ASM(clear,    long,  "andl %1,%0",  "ir", ~v);
ATOMIC_ASM(add,      long,  "addl %1,%0",  "ir",  v);
ATOMIC_ASM(subtract, long,  "subl %1,%0",  "ir",  v);


With GCC 3.4.0, I got a complaint about a read-write operation whose
constraint doesn't allow a non-register.  (I don't have the exact
error message written down, though I can regenerate it easily enough
if that would be helpful.)  

I've never written asm expressions myself, so I'm swimming in the dark
here to some extent, but looking at the info pages made it seem like
the "+m" was the problem, and the following alternative (which I also
found in a web search) seemed reasonable:


#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V)             \
static inline __attribute__((__always_inline__)) void   \
atomic_##NAME##_##TYPE(volatile unsigned TYPE *p, unsigned TYPE v)\
{                                                       \
        __asm __volatile(MPLOCKED OP                    \
                         : "=m" (*p)                    \
                         : "0" (*p), CONS (V));         \
}

ATOMIC_ASM(set,      long,  "orl %2,%0",   "ir",  v);
ATOMIC_ASM(clear,    long,  "andl %2,%0",  "ir", ~v);
ATOMIC_ASM(add,      long,  "addl %2,%0",  "ir",  v);
ATOMIC_ASM(subtract, long,  "subl %2,%0",  "ir",  v);


In other words, I split the "+m" into two separate operands, with the
second refering to the first via "0", and changed the %1's into %2's:
so what used to be

  __asm __volatile( "lock; addl %1,%0" : "+m" (*p) : "ir" (v) );

becomes

  __asm __volatile( "lock; addl %2,%0" : "=m" (*p) : "0" (*p), "ir" (v) );

This time, however, I get the following message:

Atomic.h:112: warning: matching constraint does not allow a register
Atomic.h:112: warning: matching constraint does not allow a register
Atomic.h:112: error: inconsistent operand constraints in an `asm'

(Where line 112 is the ATOMIC_ASM(add) line.)

So obviously I did something wrong, but I'm not sure what, and I can't
really make head or tails of that error message.  Can anbody more
familiar with GCC 3.4 and asms help me?

I don't subscribe to gcc-help, so please Cc: me on any answers.

Thanks,
David Carlton
carlton@kealia.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]