math/mpx-mul4-*.S: Use more portable type syntax for ambiguous instructions.
[catacomb] / rand / rand-x86ish.S
index 3617625..399ccb1 100644 (file)
 ///--------------------------------------------------------------------------
 /// Quick random generation.
 
+// Common register allocation.
+#if CPUFAM_X86
+#  define COUNT ecx
+#endif
+#if CPUFAM_AMD64 && ABI_SYSV
+#  define COUNT ecx
+#endif
+#if CPUFAM_AMD64 && ABI_WIN
+#  define COUNT r8d
+#endif
+
 FUNC(rand_quick_x86ish_rdrand)
        // Enter with a pointer to the random context in the first argument.
        // Return zero on success, or -1 on error.
 
 #if CPUFAM_X86
        mov     edx, [SP + 4]
-       stalloc 28
-#  define COUNT ecx
+       push    ebx
+       stalloc 24
 #endif
 #if CPUFAM_AMD64 && ABI_SYSV
        stalloc 8
-#  define COUNT ecx
 #endif
 #if CPUFAM_AMD64 && ABI_WIN
        stalloc 40
-#  define COUNT r8d
 #endif
   endprologue
 
@@ -66,10 +75,40 @@ FUNC(rand_quick_x86ish_rdrand)
        // Failed.
        mov     eax, -1
        jmp     9f
+ENDFUNC
+
+FUNC(rand_quick_x86ish_rdseed)
+       // Enter with a pointer to the random context in the first argument.
+       // Return zero on success, or -1 on error.
+
+#if CPUFAM_X86
+       mov     edx, [SP + 4]
+       push    ebx
+       stalloc 24
+#endif
+#if CPUFAM_AMD64 && ABI_SYSV
+       stalloc 8
+#endif
+#if CPUFAM_AMD64 && ABI_WIN
+       stalloc 40
+#endif
+  endprologue
+
+       // Try to fetch a random number.
+       mov     COUNT, 16
+0:     rdseed  AX
+       jc      1f
+       dec     COUNT
+       jnz     0b
+
+       // Failed.
+       mov     eax, -1
+       jmp     9f
 
        // Success.
 1:
 #if CPUFAM_X86
+       ldgot   ebx
        mov     [SP + 16], AX
        lea     ecx, [SP + 16]
        mov     dword ptr [SP + 12], 32
@@ -95,7 +134,8 @@ FUNC(rand_quick_x86ish_rdrand)
        // Done.
 9:
 #if CPUFAM_X86
-       stfree  28
+       stfree  24
+       pop     ebx
 #endif
 #if CPUFAM_AMD64 && ABI_SYSV
        stfree  8
@@ -104,9 +144,8 @@ FUNC(rand_quick_x86ish_rdrand)
        stfree  40
 #endif
        ret
+ENDFUNC
 
 #undef COUNT
 
-ENDFUNC
-
 ///----- That's all, folks --------------------------------------------------