From mboxrd@z Thu Jan 1 00:00:00 1970 From: Zack Weinberg To: egcs@cygnus.com Subject: Sparc `long long' incorrect code generation Date: Mon, 20 Oct 1997 19:22:00 -0000 Message-id: <199710210221.WAA05773@rabi.phys.columbia.edu> X-SW-Source: 1997-10/msg00896.html 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