Daniel Jacobowitz wrote:
On Wed, Mar 26, 2008 at 09:25:05AM -0700, Till Straumann wrote:
Is my inline assembly wrong or is this a gcc bug ?
Your inline assembly seems wrong.
I'm not yet convinced about that...
/* Powerpc I/O barrier instruction */
#define EIEIO(pmem) do { asm volatile("eieio":"=m"(*pmem):"m"(*pmem)); }
while (0)
An output memory doesn't mean what you think.
How do I tell gcc that the asm modifies a certain area of memory
w/o adding all memory to the clobber list? I thought the output
memory operand did just that.
I suspect GCC gave you
an input memory operand as "%r0(%r9)"
Hmm you mean it gave me 0(%r9) in %r0 ? That would still be wrong
because I asked for *reg_p which would be 16(%r9). Plus, I thought
gcc would do that if the constraint was "r" not "m".
and an output memory operand as
"%r9",
In any case, bad code is also produced by gcc-4.3.0 if I omit the
memory output operand and use an example that comes pretty
close to what is in the gcc info page (example illustrating
a memory input in the 'extended asm' section):
******************
C-Code
******************
#define IEVENT_REG 0x010
#define IEVENT_GRSC (1<<8)
void
test(volatile unsigned *base)
{
volatile unsigned *reg_p = base + IEVENT_REG/sizeof(*base);
unsigned val;
/* tell gcc that the asm needs/looks at *reg_p */
asm volatile ("lwz %0, 16(%1)":"=r"(val):"b"(base),"m"(*reg_p));
while ( ! (val & IEVENT_GRSC) )
val = *reg_p;
;
}
*******************
assembly produced by gcc-4.3.0
*******************
.file "tst.c"
.gnu_attribute 4, 1
.gnu_attribute 8, 1
.section ".text"
.align 2
.globl test
.type test, @function
test:
mr 9,3
# 13 "b.c" 1
lwz 3, 16(3)
# 0 "" 2
andi. 0,3,256
bnelr- 0
.L5:
lwz 0,0(9) /* BAD: R0 = *base instead of R0 = *reg_p */
andi. 11,0,256
beq+ 0,.L5
blr
.size test, .-test
.ident "GCC: (GNU) 4.3.0"
********************
assembly produced by gcc-4.2.3
********************
.file "tst.c"
.section ".text"
.align 2
.globl test
.type test, @function
test:
addi 9,3,16
lwz 3, 16(3)
andi. 0,3,256
bnelr- 0
.L5:
lwz 0,0(9) /* GOOD R0 = *reg_p */
andi. 11,0,256
beq+ 0,.L5
blr
.size test, .-test
.ident "GCC: (GNU) 4.2.3"
and expected the asm to do what it said it would do with its
operands.
Which doesn't make much sense... but there you go.
Try clobbering it instead, but you don't even need to since the
pointer is already volatile. asm volatile ("eieio") should work fine.
Yes but there still seems to be a problem (see example in
this message)
-- Till.