Pierre-André LAURENT via RT wrote:
> There is a lovely potential register mismatch issue, which can be reproduced 
> easily with the following setup
>
> using gcc 3.3.3 (SuSe linux)
> When compiled with gcc –O0 to gcc –O2, register eax is used
> When compiled with gcc –O3 and higher, register edx is used
>
>        asm volatile("rdtsc":"=A" (tsc));                                      
>    //<--- BUG HERE

http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints 
   "A" - The a and d registers, as a pair (for instructions that return 
half the result in one and half in the other).


I'm surprised by the difference -O3 makes, I'd have thought for 
something like this would not change behavior.  Might be worth building 
a few simple test cases and trying on a few versions of GCC to 
if/what/when it changed then throwing the results at the GCC list for 
feedback.

If you've no time to do this please advise and maybe I can find a moment to.



> The potential fix is probably one of these
> - to declare tsc as "unsigned long long" (enforce a 64 bit value),
> - to remove the ambiguous register usage after rdtsc, as follows   asm 
> volatile("rdtsc":"=ra" (tsc)::”edx”);   (keep tsc as a 32 bit value)

FWIW When I have used RDTSC, I have been using the syntax (below). I'm 
not sure that "=ra" is exactly equivalent to "=a", so if "=a" works then 
might as well shut the door on future GCC ambiguities with register 
selection due to superfluous use of "=r" which has another meaning and 
an unwanted behavior in this situation:

u_int32_t eax, edx;
#ifdef __GNUC__
__asm__ __volatile__("rdtsc" : "=a" ((eax)), "=d" ((edx)) : );
#endif


Darryl


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to