Commit | Line | Data |
---|---|---|
a3ad4421 MW |
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 | ||
dc2adc88 MW |
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 | ||
a3ad4421 MW |
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 | |
a90d420c | 56 | mov edx, [SP + 4] |
9e9c27da MW |
57 | push ebx |
58 | stalloc 24 | |
a3ad4421 MW |
59 | #endif |
60 | #if CPUFAM_AMD64 && ABI_SYSV | |
61 | stalloc 8 | |
a3ad4421 MW |
62 | #endif |
63 | #if CPUFAM_AMD64 && ABI_WIN | |
64 | stalloc 40 | |
a3ad4421 MW |
65 | #endif |
66 | endprologue | |
67 | ||
68 | // Try to fetch a random number. | |
69 | mov COUNT, 16 | |
a90d420c | 70 | 0: rdrand AX |
a3ad4421 MW |
71 | jc 1f |
72 | dec COUNT | |
73 | jnz 0b | |
74 | ||
75 | // Failed. | |
76 | mov eax, -1 | |
77 | jmp 9f | |
6c0946ef MW |
78 | ENDFUNC |
79 | ||
80 | FUNC(rand_quick_x86ish_rdseed) | |
81 | // Enter with a pointer to the random context in the first argument. | |
82 | // Return zero on success, or -1 on error. | |
83 | ||
84 | #if CPUFAM_X86 | |
85 | mov edx, [SP + 4] | |
9e9c27da MW |
86 | push ebx |
87 | stalloc 24 | |
6c0946ef MW |
88 | #endif |
89 | #if CPUFAM_AMD64 && ABI_SYSV | |
90 | stalloc 8 | |
91 | #endif | |
92 | #if CPUFAM_AMD64 && ABI_WIN | |
93 | stalloc 40 | |
94 | #endif | |
95 | endprologue | |
96 | ||
97 | // Try to fetch a random number. | |
98 | mov COUNT, 16 | |
99 | 0: rdseed AX | |
100 | jc 1f | |
101 | dec COUNT | |
102 | jnz 0b | |
103 | ||
104 | // Failed. | |
105 | mov eax, -1 | |
106 | jmp 9f | |
a3ad4421 MW |
107 | |
108 | // Success. | |
109 | 1: | |
110 | #if CPUFAM_X86 | |
9e9c27da | 111 | ldgot ebx |
a90d420c MW |
112 | mov [SP + 16], AX |
113 | lea ecx, [SP + 16] | |
114 | mov dword ptr [SP + 12], 32 | |
115 | mov dword ptr [SP + 8], 4 | |
116 | mov [SP + 4], ecx | |
117 | mov [SP + 0], edx | |
a3ad4421 MW |
118 | #endif |
119 | #if CPUFAM_AMD64 && ABI_SYSV | |
a90d420c MW |
120 | mov [SP + 0], AX |
121 | mov rsi, SP | |
a3ad4421 MW |
122 | mov edx, 8 |
123 | mov ecx, 64 | |
124 | #endif | |
125 | #if CPUFAM_AMD64 && ABI_WIN | |
a90d420c MW |
126 | mov [SP + 32], AX |
127 | lea rdx, [SP + 32] | |
a3ad4421 MW |
128 | mov r8d, 8 |
129 | mov r9d, 64 | |
130 | #endif | |
131 | callext F(rand_add) | |
132 | xor eax, eax | |
133 | ||
134 | // Done. | |
135 | 9: | |
136 | #if CPUFAM_X86 | |
9e9c27da MW |
137 | stfree 24 |
138 | pop ebx | |
a3ad4421 MW |
139 | #endif |
140 | #if CPUFAM_AMD64 && ABI_SYSV | |
141 | stfree 8 | |
142 | #endif | |
143 | #if CPUFAM_AMD64 && ABI_WIN | |
144 | stfree 40 | |
145 | #endif | |
146 | ret | |
dc2adc88 | 147 | ENDFUNC |
89dbb5fd MW |
148 | |
149 | #undef COUNT | |
150 | ||
a3ad4421 | 151 | ///----- That's all, folks -------------------------------------------------- |