chiark / gitweb /
b91a9373bfc0abd2d9f75ff4317329e50397c59a
[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 ENDFUNC
78
79 FUNC(rand_quick_x86ish_rdseed)
80         // Enter with a pointer to the random context in the first argument.
81         // Return zero on success, or -1 on error.
82
83 #if CPUFAM_X86
84         mov     edx, [SP + 4]
85         stalloc 28
86 #endif
87 #if CPUFAM_AMD64 && ABI_SYSV
88         stalloc 8
89 #endif
90 #if CPUFAM_AMD64 && ABI_WIN
91         stalloc 40
92 #endif
93   endprologue
94
95         // Try to fetch a random number.
96         mov     COUNT, 16
97 0:      rdseed  AX
98         jc      1f
99         dec     COUNT
100         jnz     0b
101
102         // Failed.
103         mov     eax, -1
104         jmp     9f
105
106         // Success.
107 1:
108 #if CPUFAM_X86
109         mov     [SP + 16], AX
110         lea     ecx, [SP + 16]
111         mov     dword ptr [SP + 12], 32
112         mov     dword ptr [SP + 8], 4
113         mov     [SP + 4], ecx
114         mov     [SP + 0], edx
115 #endif
116 #if CPUFAM_AMD64 && ABI_SYSV
117         mov     [SP + 0], AX
118         mov     rsi, SP
119         mov     edx, 8
120         mov     ecx, 64
121 #endif
122 #if CPUFAM_AMD64 && ABI_WIN
123         mov     [SP + 32], AX
124         lea     rdx, [SP + 32]
125         mov     r8d, 8
126         mov     r9d, 64
127 #endif
128         callext F(rand_add)
129         xor     eax, eax
130
131         // Done.
132 9:
133 #if CPUFAM_X86
134         stfree  28
135 #endif
136 #if CPUFAM_AMD64 && ABI_SYSV
137         stfree  8
138 #endif
139 #if CPUFAM_AMD64 && ABI_WIN
140         stfree  40
141 #endif
142         ret
143 ENDFUNC
144
145 #undef COUNT
146
147 ///----- That's all, folks --------------------------------------------------