[gnu.gcc.bug] asm volatility

raeburn@ATHENA.MIT.EDU (Ken Raeburn) (04/03/89)

Source file:

  extern void do_other_stuff ();

  void do_stuff () {
      static int s;
      s = ({ int __n;
	     __n = ({ int __val;
		      asm volatile ("mfpr %1,%0" : "=g" (__val) : "g" (0x12 ));
		      __val; });
	     ({ asm volatile ("mtpr %0,%1" :: "g" ( (0x1f)), "g" (0x12 ));
		0; });
	     __n; });
      do_other_stuff ();
      ({ asm ("mtpr %0,%1" :: "g" ( (s)), "g" (0x12 ));
	 0; });
  }

GCC compilation:

 % gcc -O -S quux.c -v 
gcc version 1.34
 /mit/gnu/vaxlib/gcc-cpp -v -undef -D__GNUC__ -Dvax -Dunix -D__vax__ -D__unix__ -D__OPTIMIZE__ quux.c /tmp/cc006384.cpp
GNU CPP version 1.34
 /mit/gnu/vaxlib/gcc-cc1 /tmp/cc006384.cpp -fcombine-regs -fstrength-reduce -quiet -dumpbase quux.c -O -version -o quux.s
GNU C version 1.34 (vax) compiled by GNU C version 1.34.

Output:

    #NO_APP
    gcc_compiled.:
    .lcomm _s.0,4
    .text
	    .align 1
    .globl _do_stuff
    _do_stuff:
	    .word 0x0
    #APP
	    mtpr $31,$18
	    mfpr $18,_s.0
    #NO_APP
	    calls $0,_do_other_stuff
    #APP
	    mtpr _s.0,$18
    #NO_APP
	    ret

Note that the `mfpr'/`mtpr' pair have been swapped, despite the facts
that the latter has no output operand (which should ensure that it not
be moved) and that both have the `volatile' attribute.  Assigning the
`volatile' qualifier to one of the intermediate variables involved
does provide a workaround for the problem.

-- Ken