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]