I was looking through an Intel provided reference implementation of RDRAND
instruction. The page is Intel Digital Random Number Generator (DRNG) Software Implementation Guide, and the code came from Intel Digital Random Number Generator software code examples.
The following is the relevant portion from Intel. It reads a random value and places it in val
, and it sets the carry flag on success.
char rc;
unsigned int val;
__asm__ volatile(
"rdrand %0 ; setc %1"
: "=r" (val), "=qm" (rc)
);
// 1 = success, 0 = underflow
if(rc) {
// use val
...
}
Soory to have to ask. I don't think it was covered in GNU Extended Assembler, and searching for "=qm" is producing spurious hits.
What does the "=qm"
mean in the extended assembler?
setc
to create an integer that the compiler will thentest
to put back into flags to branch on, using a flag output constraint. (And memory output is a poor choice for older compilers, don't let the compiler shoot itself in the foot that way.). Or better, use the_rdrand32_step
intrinsic (RDRAND and RDSEED intrinsics GCC and Intel C++) and not inline asm at all. – Pollie"=m"
option from your intrinsics. Clang likes to pick memory when it has the choice even with no register pressure, and you definitely don't want that. It's only 2 register outputs total, and you're always reading the result right away afterward, so don't give the compiler the option of memory, you can be pretty sure it's not a helpful choice. (gcc is smart enough not to pick memory, but clang isn't.) – Pollie"=a" (*reinterpret_cast<word64*>(output))
(whereoutput
is memory). The byte codes gave us better coverage using older compilers. – Hydrodynamic