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