Sparc `long long' incorrect code generation
Zack Weinberg
zack@rabi.phys.columbia.edu
Mon Oct 20 19:22:00 GMT 1997
Solaris has a special trap to read the `high resolution timer' which
is useful for timing inner loops. It's exposed as a library call,
gethrtime(), the disassembly of which is:
gethrvtime:
ta 0x24
retl
nop
The trap returns a 64 bit value in o0:o1 (hi:lo). You can write a
version of this with gcc's inline asms:
unsigned long long
timer(void)
{
register unsigned long long val asm("%o0");
asm("ta 0x24" : "=r" (val));
return val;
}
gcc 2.7.2 translates this to
timer:
save %sp,-112,%sp
ta 0x24
mov %o0,%i0
mov %o1,%i1
ret
restore
which is correct, although it should be optimized to a leaf. egcs
971016, on the other hand, generates:
timer:
save %sp,-112,%sp
ta 0x24
ret
restore
which, if I understand Sparc register windows correctly, is wrong:
the results of the trap will be shifted away and the caller will not
see them.
Interestingly, if you make this an inline function and refer to it
elsewhere, say like so:
extern void foo(unsigned long long);
int
main(void)
{
foo(timer());
return 0;
}
both compilers generate the same code:
main:
save %sp,-112,%sp
ta 0x24
call foo,0
mov 0,%i0
ret
restore
which is correct and optimal.
Also, it would be nice if the docs said that you could allocate a
32-bit register pair to a 64-bit integer by putting the high register
in the asm("reg") phrase. I found that out by trial and error.
zw
More information about the Gcc
mailing list