As of gcc-4.3.0 one of my drivers stopped working.
I distilled the code down to a few lines (see below).

The output of

   gcc-4.3.0 -S -O2 -c tst.c

and

   gcc-4.2.3 -S -O2 -c tst.c

is attached. The code generated by gcc-4.2.3 is as expected.
However, gcc-4.3.0 does not produce a correct result.

Is my inline assembly wrong or is this a gcc bug ?

(If the memory input operand to the inline assembly
statement is omitted then everything is OK).

Please CC-me on any replies; I'm not subscribed to the gcc list.

WKR
-- Till

###########################################
Test case; C-code:
###########################################

/* Powerpc I/O barrier instruction */
#define EIEIO(pmem) do { asm volatile("eieio":"=m"(*pmem):"m"(*pmem)); } while (0)


/*
* Reset a bit in a register and poll for it to be set by the hardware
*/
void
test(volatile unsigned *base)
{
   volatile unsigned *reg_p = base + IEVENT_REG/sizeof(*base);
   unsigned           val;

   /* Clear bit in register by writing a one */
   *reg_p = IEVENT_GRSC;
   EIEIO( reg_p );

   /* Poll bit until set by hardware         */
   do {
       val = *reg_p;
       EIEIO( reg_p );
   } while ( ! (val & IEVENT_GRSC) );
}

#############################################
Assembly code 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:
   li 0,256
   mr 9,3
/*** ^^^^^^^^^ NOTE: base address copied into R9 ***/
   stw 0,16(3)
# 21 "c.c" 1
   eieio
# 0 "" 2
.L2:
   lwz 0,0(9)
/*** ^^^^^^^^^ BAD: R0 = *base instead of *reg_p ***/
# 26 "c.c" 1
   eieio
# 0 "" 2
   andi. 11,0,256
   beq+ 0,.L2
   blr
   .size   test, .-test

###########################################
Assembly code produced by gcc-4.2.3:
###########################################

   .file   "tst.c"
   .section    ".text"
   .align 2
   .globl test
   .type   test, @function
test:
   li 0,256
   addi 9,3,16
/*** NOTE: R9 = base + <IEVENT_REG offset> ***/
   stw 0,16(3)
   eieio
.L2:
   lwz 0,0(9)
/*** GOOD: R0 = *reg_p                     ***/
   eieio
   andi. 11,0,256
   beq+ 0,.L2
   blr
   .size   test, .-test
   .ident  "GCC: (GNU) 4.2.3"

Reply via email to