70907feb8b3d7b8616998ec63dbf4a8fe5798b1c
[catacomb] / rand / rand-x86ish.S
1 /// -*- mode: asm; asm-comment-char: ?/ -*-
2 ///
3 /// Random-number support for x86
4 ///
5 /// (c) 2019 Straylight/Edgeware
6 ///
7
8 ///----- Licensing notice ---------------------------------------------------
9 ///
10 /// This file is part of Catacomb.
11 ///
12 /// Catacomb is free software: you can redistribute it and/or modify it
13 /// under the terms of the GNU Library General Public License as published
14 /// by the Free Software Foundation; either version 2 of the License, or
15 /// (at your option) any later version.
16 ///
17 /// Catacomb is distributed in the hope that it will be useful, but
18 /// WITHOUT ANY WARRANTY; without even the implied warranty of
19 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 /// Library General Public License for more details.
21 ///
22 /// You should have received a copy of the GNU Library General Public
23 /// License along with Catacomb. If not, write to the Free Software
24 /// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 /// USA.
26
27 ///--------------------------------------------------------------------------
28 /// Preliminaries.
29
30 #include "config.h"
31 #include "asm-common.h"
32
33 .extern F(rand_add)
34
35 .text
36
37 ///--------------------------------------------------------------------------
38 /// Quick random generation.
39
40 // Common register allocation.
41 #if CPUFAM_X86
42 # define COUNT ecx
43 #endif
44 #if CPUFAM_AMD64 && ABI_SYSV
45 # define COUNT ecx
46 #endif
47 #if CPUFAM_AMD64 && ABI_WIN
48 # define COUNT r8d
49 #endif
50
51 FUNC(rand_quick_x86ish_rdrand)
52 // Enter with a pointer to the random context in the first argument.
53 // Return zero on success, or -1 on error.
54
55 #if CPUFAM_X86
56 mov edx, [SP + 4]
57 stalloc 28
58 #endif
59 #if CPUFAM_AMD64 && ABI_SYSV
60 stalloc 8
61 #endif
62 #if CPUFAM_AMD64 && ABI_WIN
63 stalloc 40
64 #endif
65 endprologue
66
67 // Try to fetch a random number.
68 mov COUNT, 16
69 0: rdrand AX
70 jc 1f
71 dec COUNT
72 jnz 0b
73
74 // Failed.
75 mov eax, -1
76 jmp 9f
77
78 // Success.
79 1:
80 #if CPUFAM_X86
81 mov [SP + 16], AX
82 lea ecx, [SP + 16]
83 mov dword ptr [SP + 12], 32
84 mov dword ptr [SP + 8], 4
85 mov [SP + 4], ecx
86 mov [SP + 0], edx
87 #endif
88 #if CPUFAM_AMD64 && ABI_SYSV
89 mov [SP + 0], AX
90 mov rsi, SP
91 mov edx, 8
92 mov ecx, 64
93 #endif
94 #if CPUFAM_AMD64 && ABI_WIN
95 mov [SP + 32], AX
96 lea rdx, [SP + 32]
97 mov r8d, 8
98 mov r9d, 64
99 #endif
100 callext F(rand_add)
101 xor eax, eax
102
103 // Done.
104 9:
105 #if CPUFAM_X86
106 stfree 28
107 #endif
108 #if CPUFAM_AMD64 && ABI_SYSV
109 stfree 8
110 #endif
111 #if CPUFAM_AMD64 && ABI_WIN
112 stfree 40
113 #endif
114 ret
115 ENDFUNC
116
117 #undef COUNT
118
119 ///----- That's all, folks --------------------------------------------------