gcc-4.3.0/ppc32 inline assembly produces bad code
Till Straumann
strauman at slac.stanford.edu
Wed Mar 26 19:37:19 UTC 2008
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.
More information about the users
mailing list