This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Sparc `long long' incorrect code generation



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]