m68k: volatile pointer ref generates bad code

Mark Powell medp@primag.co.uk
Mon Jan 11 10:06:00 GMT 1999


I couldn't see this reported before so here goes....

The following bug was observed in egcs-1.1b and egcs-1.1.1 configured
for m68k-coff.

Assignment operations through a pointer variable declared volatile
produce multiple accesses. This can cause incorrect behaviour when the
destination of the write is a register in a peripheral device and the
device expects a series of values to be written to the same address.

The bug is triggered when compiling with no optimisation. Optimisation
levels of -O1 and above do not exhibit the bug.


The following code snippet demonstrates the bug. The manner of declaring
the volatile pointer is not significant, the same bad code is generated
whether the pointer is a local variable, global variable or structure
element.

    void write_device(unsigned char *addr, int val)
    {
        volatile unsigned char *ptr = addr;

        *ptr = val;
    }

Compile with:
  m68k-coff-gcc -S volatile-bug.c

The resulting assembler is:
     .text
             .even
     .globl write_device
     write_device:
             link.w %a6,#-4
             move.l 8(%a6),-4(%a6)
             move.l -4(%a6),%a0
             move.b 15(%a6),(%a0)
             move.b (%a0),(%a0)
     .L1:
             unlk %a6
             rts

Note the spurious extra "move.b (%a0),(%a0)" instruction.

-- 
Mark Powell, Senior Software Engineer, Primagraphics Limited
New Cambridge House, Litlington, nr.Royston, Herts, SG8 0SS, UK
Tel. +44 1763 852222, Fax. 853324, medp@primag.co.uk, http://www.primag.co.uk




More information about the Gcc-bugs mailing list