/// -*- mode: asm; asm-comment-char: ?/ -*- /// /// Random-number support for x86 /// /// (c) 2019 Straylight/Edgeware /// ///----- Licensing notice --------------------------------------------------- /// /// This file is part of Catacomb. /// /// Catacomb is free software: you can redistribute it and/or modify it /// under the terms of the GNU Library General Public License as published /// by the Free Software Foundation; either version 2 of the License, or /// (at your option) any later version. /// /// Catacomb is distributed in the hope that it will be useful, but /// WITHOUT ANY WARRANTY; without even the implied warranty of /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /// Library General Public License for more details. /// /// You should have received a copy of the GNU Library General Public /// License along with Catacomb. If not, write to the Free Software /// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, /// USA. ///-------------------------------------------------------------------------- /// Preliminaries. #include "config.h" #include "asm-common.h" .extern F(rand_add) .text ///-------------------------------------------------------------------------- /// 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] 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: rdrand AX jc 1f dec COUNT jnz 0b // 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 mov dword ptr [SP + 8], 4 mov [SP + 4], ecx mov [SP + 0], edx #endif #if CPUFAM_AMD64 && ABI_SYSV mov [SP + 0], AX mov rsi, SP mov edx, 8 mov ecx, 64 #endif #if CPUFAM_AMD64 && ABI_WIN mov [SP + 32], AX lea rdx, [SP + 32] mov r8d, 8 mov r9d, 64 #endif callext F(rand_add) xor eax, eax // Done. 9: #if CPUFAM_X86 stfree 24 pop ebx #endif #if CPUFAM_AMD64 && ABI_SYSV stfree 8 #endif #if CPUFAM_AMD64 && ABI_WIN stfree 40 #endif ret ENDFUNC #undef COUNT ///----- That's all, folks --------------------------------------------------