This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
atomic asms and GCC 3.4.0
- From: David Carlton <carlton at kealia dot com>
- To: gcc-help <gcc-help at gcc dot gnu dot org>
- Date: Thu, 22 Apr 2004 10:57:58 -0700
- Subject: 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