rand/rand-x86ish.S: Establish GOT pointer before making an i386 PLT call.
[catacomb] / rand / rand-x86ish.S
CommitLineData
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
51FUNC(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 700: 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
78ENDFUNC
79
80FUNC(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
990: 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.
1091:
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.
1359:
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 147ENDFUNC
89dbb5fd
MW
148
149#undef COUNT
150
a3ad4421 151///----- That's all, folks --------------------------------------------------