This is the mail archive of the gcc@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]

Re: gcc-4.3.0/ppc32 inline assembly produces bad code


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.


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