This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Sparc `long long' incorrect code generation
- To: egcs at cygnus dot com
- Subject: Sparc `long long' incorrect code generation
- From: Zack Weinberg <zack at rabi dot phys dot columbia dot edu>
- Date: Mon, 20 Oct 1997 22:21:52 -0400
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