Changeset View
Changeset View
Standalone View
Standalone View
src/random.cpp
Show First 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* Must only be called when RdRand is supported. | * Must only be called when RdRand is supported. | ||||
*/ | */ | ||||
static uint64_t GetRdRand() noexcept { | static uint64_t GetRdRand() noexcept { | ||||
// RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce | // RdRand may very rarely fail. Invoke it up to 10 times in a loop to reduce | ||||
// this risk. | // this risk. | ||||
#ifdef __i386__ | #ifdef __i386__ | ||||
uint8_t ok; | uint8_t ok; | ||||
uint32_t r1, r2; | // Initialize to 0 to silence a compiler warning that r1 or r2 may be used | ||||
// uninitialized. Even if rdrand fails (!ok) it will set the output to 0, | |||||
// but there is no way that the compiler could know that. | |||||
uint32_t r1 = 0, r2 = 0; | |||||
for (int i = 0; i < 10; ++i) { | for (int i = 0; i < 10; ++i) { | ||||
// rdrand %eax | // rdrand %eax | ||||
__asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1" | __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1" | ||||
: "=a"(r1), "=q"(ok)::"cc"); | : "=a"(r1), "=q"(ok)::"cc"); | ||||
if (ok) { | if (ok) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
for (int i = 0; i < 10; ++i) { | for (int i = 0; i < 10; ++i) { | ||||
// rdrand %eax | // rdrand %eax | ||||
__asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1" | __asm__ volatile(".byte 0x0f, 0xc7, 0xf0; setc %1" | ||||
: "=a"(r2), "=q"(ok)::"cc"); | : "=a"(r2), "=q"(ok)::"cc"); | ||||
if (ok) { | if (ok) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
return (uint64_t(r2) << 32) | r1; | return (uint64_t(r2) << 32) | r1; | ||||
#elif defined(__x86_64__) || defined(__amd64__) | #elif defined(__x86_64__) || defined(__amd64__) | ||||
uint8_t ok; | uint8_t ok; | ||||
uint64_t r1; | uint64_t r1 = 0; // See above why we initialize to 0. | ||||
for (int i = 0; i < 10; ++i) { | for (int i = 0; i < 10; ++i) { | ||||
// rdrand %rax | // rdrand %rax | ||||
__asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1" | __asm__ volatile(".byte 0x48, 0x0f, 0xc7, 0xf0; setc %1" | ||||
: "=a"(r1), "=q"(ok)::"cc"); | : "=a"(r1), "=q"(ok)::"cc"); | ||||
if (ok) { | if (ok) { | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 631 Lines • Show Last 20 Lines |