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