gcc using clobbered register as input with inline assembly

Zack Weinberg zackw@stanford.edu
Mon Mar 26 10:20:00 GMT 2001


On Mon, Mar 26, 2001 at 11:41:13AM -0600, Timur Tabi wrote:
> egcs-2.91.66 on Red Hat Linux 6.2 (2.2.14 kernel)
> 
> I have this inline assembly code:
> 
> _inline void
> BeginCpuTick(
>     u64 * const pTime
> ){
>     ASSERT(pTime);
>     __asm__ __volatile__ (
>         "rdtsc \n\t"
>         "mov %%eax, (%1) \n\t"
>         "mov %%edx, 4(%1) \n\t"
>         : "=m" (*pTime)
>         : "r" (pTime)
>         : "eax", "edx"
>     );
> }
> 
> According to the documentation, because I specified eax and edx as
> clobbered registers, gcc should not be using them as inputs or outputs. 
> But that's exactly what's happening in my case.

Clobbers happen *after* the asm completes.  You have to do the moves
separately, or let the compiler do them for you, e.g:

inline void
BeginCpuTick(u64 *const pTime)
{
   register u64 xtime;
   asm volatile ("rdtsc" : "=A" (xtime));
   *pTime = xtime;
}

-- 3.0 -O2 -fomit-frame-pointer gives me

BeginCpuTick:
#APP
        rdtsc
#NO_APP
        movl    4(%esp), %ecx
        movl    %eax, (%ecx)
        movl    %edx, 4(%ecx)
        ret

2.95 unfortunately puts some extra moves in there.

zw



More information about the Gcc-bugs mailing list