// Save the floating point and SIMD registers, and try to clobber
// xmm0.
+ lea DX, [SP + 160]
fxsave [SP]
- mov eax, [SP + 160]
- xor dword ptr [SP + 160], 0xaaaa5555
+ mov eax, [DX]
+ xor dword ptr [DX], 0xaaaa5555
fxrstor [SP]
// Save them again, and read back the low word of xmm0. Undo the
// clobbering and restore.
fxsave [SP]
- mov ecx, [SP + 160]
- mov [SP + 160], eax
+ mov ecx, [DX]
+ mov [DX], eax
fxrstor [SP]
// The register are live if we read different things.
/// Checking `rdrand'.
FUNC(dispatch_x86ish_rdrand)
- // Enter with one argument: a pointer X_OUT to a 32-bit word. Try to
- // generate a random word using `rdrand'. If successful, set *X_OUT
- // to the generated word, and return zero; otherwise, return -1.
+ // Enter with two arguments: a code OP requesting either `rdrand' (0)
+ // or `rdseed' (1), and a pointer X_OUT to a 32-bit word. Try to
+ // generate a random word using the requested instruction'. If
+ // successful, set *X_OUT to the generated word, and return zero;
+ // otherwise, return -1.
#if CPUFAM_X86
+# define OP eax
# define X_OUT edx
# define COUNT ecx
- mov X_OUT, [SP + 4]
+ mov OP, [SP + 4]
+ mov X_OUT, [SP + 8]
#endif
#if CPUFAM_AMD64 && ABI_SYSV
-# define X_OUT rdi
+# define OP edi
+# define X_OUT rsi
# define COUNT ecx
#endif
#if CPUFAM_AMD64 && ABI_WIN
-# define X_OUT rcx
-# define COUNT edx
+# define OP rcx
+# define X_OUT rdx
+# define COUNT r8d
#endif
endprologue
+ cmp OP, 0
mov COUNT, 16 // fairly persistent
+ jne 1f
+
0: rdrand eax
jc 9f
dec COUNT
jnz 0b
+ jmp 8f
+
+1: rdseed eax
+ jc 9f
+ dec COUNT
+ jnz 1b
+ jmp 8f
// Failed to come up with a random value.
- mov eax, -1
+8: mov eax, -1
ret
// Success.