I'm trying to use Intel's RDRAND instruction. According to the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2 (page 4-298), RDRAND produces 32-bit random values by default, even on 64-bit machines:
In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.B permits access to additional registers (R8-R15).
I'm trying to force the 64-bit generation using rdrandq, but its producing an error (/tmp/ccLxwW6S.s is due to the use of inline assembly):
$ g++ -Wall rdrand.cxx -o rdrand.exe
/tmp/ccLxwW6S.s: Assembler messages:
/tmp/ccLxwW6S.s:5141: Error: invalid instruction suffix for `rdrand'
How do I force the 64-bit version of the RDRAND instruction under GCC? How do I set the REX prefix when using RDRAND under GCC?
Thanks in advance.
In the code below, output is a byte[] with a length of size. safety is a failsafe. The two different word sizes handle the X86, X32, and X64 platforms.
#if BOOL_X86
    word32 val;
#else // X32 and X64
    word64 val;
#endif    
    while (size && safety)
    {
        char rc;    
        __asm__ volatile(
#if BOOL_X86
          "rdrandl %0 ; setc %1"
#else
          "rdrandq %0 ; setc %1"
#endif                  
          : "=rm" (val), "=qm" (rc)
          :
          : "cc"
        );
        if (rc)
        {
            size_t count = (size < sizeof(val) ? size : sizeof(val));
            memcpy(output, &val, count);
            size =- count;
        }
        else
        {
            safety--;
        }
    }
If I remove the explicit operand size from RDRAND (i.e., use rdrand rather than rdrandl or rdrandq), then I get an error when attempting to use the word64:
/tmp/ccbeXOvM.s: Assembler messages:
/tmp/ccbeXOvM.s:5167: Error: operand size mismatch for `rdrand'