Commit | Line | Data |
---|---|---|
20b477a7 LM |
1 | /* This testcase is part of GDB, the GNU debugger. |
2 | ||
b811d2c2 | 3 | Copyright 2017-2020 Free Software Foundation, Inc. |
20b477a7 LM |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 3 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17 | ||
18 | #include <cpuid.h> | |
19 | #include <stdint.h> | |
20 | ||
17cd4947 | 21 | /* 0 if the CPU supports rdrand and non-zero otherwise. */ |
20b477a7 LM |
22 | static unsigned int supports_rdrand; |
23 | ||
17cd4947 LM |
24 | /* 0 if the CPU supports rdseed and non-zero otherwise. */ |
25 | static unsigned int supports_rdseed; | |
20b477a7 | 26 | |
17cd4947 LM |
27 | /* Check supported features and set globals accordingly. The globals |
28 | can be used to prevent unsupported tests from running. */ | |
29 | ||
30 | static void | |
31 | check_supported_features (void) | |
20b477a7 LM |
32 | { |
33 | unsigned int rdrand_mask = (1 << 30); | |
17cd4947 | 34 | unsigned int rdseed_mask = (1 << 18); |
20b477a7 | 35 | unsigned int eax, ebx, ecx, edx; |
17cd4947 LM |
36 | unsigned int vendor; |
37 | unsigned int max_level; | |
38 | ||
39 | max_level = __get_cpuid_max (0, &vendor); | |
40 | ||
41 | if (max_level < 1) | |
42 | return; | |
43 | ||
44 | __cpuid (1, eax, ebx, ecx, edx); | |
20b477a7 | 45 | |
17cd4947 LM |
46 | supports_rdrand = ((ecx & rdrand_mask) == rdrand_mask); |
47 | ||
48 | if (max_level >= 7) | |
49 | { | |
50 | __cpuid_count (7, 0, eax, ebx, ecx, edx); | |
51 | supports_rdseed = ((ebx & rdseed_mask) == rdseed_mask); | |
52 | } | |
20b477a7 LM |
53 | } |
54 | ||
55 | /* Test rdrand support for various output registers. */ | |
56 | ||
57 | void | |
58 | rdrand (void) | |
59 | { | |
60 | /* Get a random number from the rdrand assembly instruction. */ | |
61 | register uint64_t number; | |
62 | ||
63 | if (!supports_rdrand) | |
64 | return; | |
65 | ||
66 | /* 16-bit random numbers. */ | |
67 | __asm__ volatile ("rdrand %%ax;" : "=r" (number)); | |
68 | __asm__ volatile ("rdrand %%bx;" : "=r" (number)); | |
69 | __asm__ volatile ("rdrand %%cx;" : "=r" (number)); | |
70 | __asm__ volatile ("rdrand %%dx;" : "=r" (number)); | |
71 | ||
72 | __asm__ volatile ("mov %%di, %%ax;" : "=r" (number)); | |
73 | __asm__ volatile ("rdrand %%di;" : "=r" (number)); | |
74 | __asm__ volatile ("mov %%ax, %%di;" : "=r" (number)); | |
75 | ||
76 | __asm__ volatile ("mov %%si, %%ax;" : "=r" (number)); | |
77 | __asm__ volatile ("rdrand %%si;" : "=r" (number)); | |
78 | __asm__ volatile ("mov %%ax, %%si;" : "=r" (number)); | |
79 | ||
80 | __asm__ volatile ("mov %%bp, %%ax;" : "=r" (number)); | |
81 | __asm__ volatile ("rdrand %%bp;" : "=r" (number)); | |
82 | __asm__ volatile ("mov %%ax, %%bp;" : "=r" (number)); | |
83 | ||
84 | __asm__ volatile ("mov %%sp, %%ax;" : "=r" (number)); | |
85 | __asm__ volatile ("rdrand %%sp;" : "=r" (number)); | |
86 | __asm__ volatile ("mov %%ax, %%sp;" : "=r" (number)); | |
87 | ||
88 | __asm__ volatile ("rdrand %%r8w;" : "=r" (number)); | |
89 | __asm__ volatile ("rdrand %%r9w;" : "=r" (number)); | |
90 | __asm__ volatile ("rdrand %%r10w;" : "=r" (number)); | |
91 | __asm__ volatile ("rdrand %%r11w;" : "=r" (number)); | |
92 | __asm__ volatile ("rdrand %%r12w;" : "=r" (number)); | |
93 | __asm__ volatile ("rdrand %%r13w;" : "=r" (number)); | |
94 | __asm__ volatile ("rdrand %%r14w;" : "=r" (number)); | |
95 | __asm__ volatile ("rdrand %%r15w;" : "=r" (number)); | |
96 | ||
97 | /* 32-bit random numbers. */ | |
98 | __asm__ volatile ("rdrand %%eax;" : "=r" (number)); | |
99 | __asm__ volatile ("rdrand %%ebx;" : "=r" (number)); | |
100 | __asm__ volatile ("rdrand %%ecx;" : "=r" (number)); | |
101 | __asm__ volatile ("rdrand %%edx;" : "=r" (number)); | |
102 | ||
103 | __asm__ volatile ("mov %%rdi, %%rax;" : "=r" (number)); | |
104 | __asm__ volatile ("rdrand %%edi;" : "=r" (number)); | |
105 | __asm__ volatile ("mov %%rax, %%rdi;" : "=r" (number)); | |
106 | ||
107 | __asm__ volatile ("mov %%rsi, %%rax;" : "=r" (number)); | |
108 | __asm__ volatile ("rdrand %%esi;" : "=r" (number)); | |
109 | __asm__ volatile ("mov %%rax, %%rsi;" : "=r" (number)); | |
110 | ||
111 | __asm__ volatile ("mov %%rbp, %%rax;" : "=r" (number)); | |
112 | __asm__ volatile ("rdrand %%ebp;" : "=r" (number)); | |
113 | __asm__ volatile ("mov %%rax, %%rbp;" : "=r" (number)); | |
114 | ||
115 | __asm__ volatile ("mov %%rsp, %%rax;" : "=r" (number)); | |
116 | __asm__ volatile ("rdrand %%esp;" : "=r" (number)); | |
117 | __asm__ volatile ("mov %%rax, %%rsp;" : "=r" (number)); | |
118 | ||
119 | __asm__ volatile ("rdrand %%r8d;" : "=r" (number)); | |
120 | __asm__ volatile ("rdrand %%r9d;" : "=r" (number)); | |
121 | __asm__ volatile ("rdrand %%r10d;" : "=r" (number)); | |
122 | __asm__ volatile ("rdrand %%r11d;" : "=r" (number)); | |
123 | __asm__ volatile ("rdrand %%r12d;" : "=r" (number)); | |
124 | __asm__ volatile ("rdrand %%r13d;" : "=r" (number)); | |
125 | __asm__ volatile ("rdrand %%r14d;" : "=r" (number)); | |
126 | __asm__ volatile ("rdrand %%r15d;" : "=r" (number)); | |
127 | ||
128 | /* 64-bit random numbers. */ | |
129 | __asm__ volatile ("rdrand %%rax;" : "=r" (number)); | |
130 | __asm__ volatile ("rdrand %%rbx;" : "=r" (number)); | |
131 | __asm__ volatile ("rdrand %%rcx;" : "=r" (number)); | |
132 | __asm__ volatile ("rdrand %%rdx;" : "=r" (number)); | |
133 | ||
134 | __asm__ volatile ("mov %%rdi, %%rax;" : "=r" (number)); | |
135 | __asm__ volatile ("rdrand %%rdi;" : "=r" (number)); | |
136 | __asm__ volatile ("mov %%rax, %%rdi;" : "=r" (number)); | |
137 | ||
138 | __asm__ volatile ("mov %%rsi, %%rax;" : "=r" (number)); | |
139 | __asm__ volatile ("rdrand %%rsi;" : "=r" (number)); | |
140 | __asm__ volatile ("mov %%rax, %%rsi;" : "=r" (number)); | |
141 | ||
142 | __asm__ volatile ("mov %%rbp, %%rax;" : "=r" (number)); | |
143 | __asm__ volatile ("rdrand %%rbp;" : "=r" (number)); | |
144 | __asm__ volatile ("mov %%rax, %%rbp;" : "=r" (number)); | |
145 | ||
146 | __asm__ volatile ("mov %%rsp, %%rax;" : "=r" (number)); | |
147 | __asm__ volatile ("rdrand %%rsp;" : "=r" (number)); | |
148 | __asm__ volatile ("mov %%rax, %%rsp;" : "=r" (number)); | |
149 | ||
150 | __asm__ volatile ("rdrand %%r8;" : "=r" (number)); | |
151 | __asm__ volatile ("rdrand %%r9;" : "=r" (number)); | |
152 | __asm__ volatile ("rdrand %%r10;" : "=r" (number)); | |
153 | __asm__ volatile ("rdrand %%r11;" : "=r" (number)); | |
154 | __asm__ volatile ("rdrand %%r12;" : "=r" (number)); | |
155 | __asm__ volatile ("rdrand %%r13;" : "=r" (number)); | |
156 | __asm__ volatile ("rdrand %%r14;" : "=r" (number)); | |
157 | __asm__ volatile ("rdrand %%r15;" : "=r" (number)); | |
158 | } | |
159 | ||
160 | /* Test rdseed support for various output registers. */ | |
161 | ||
162 | void | |
163 | rdseed (void) | |
164 | { | |
165 | /* Get a random seed from the rdseed assembly instruction. */ | |
166 | register long seed; | |
167 | ||
17cd4947 | 168 | if (!supports_rdseed) |
20b477a7 LM |
169 | return; |
170 | ||
171 | /* 16-bit random seeds. */ | |
172 | __asm__ volatile ("rdseed %%ax;" : "=r" (seed)); | |
173 | __asm__ volatile ("rdseed %%bx;" : "=r" (seed)); | |
174 | __asm__ volatile ("rdseed %%cx;" : "=r" (seed)); | |
175 | __asm__ volatile ("rdseed %%dx;" : "=r" (seed)); | |
176 | ||
177 | __asm__ volatile ("mov %%di, %%ax;" : "=r" (seed)); | |
178 | __asm__ volatile ("rdseed %%di;" : "=r" (seed)); | |
179 | __asm__ volatile ("mov %%ax, %%di;" : "=r" (seed)); | |
180 | ||
181 | __asm__ volatile ("mov %%si, %%ax;" : "=r" (seed)); | |
182 | __asm__ volatile ("rdseed %%si;" : "=r" (seed)); | |
183 | __asm__ volatile ("mov %%ax, %%si;" : "=r" (seed)); | |
184 | ||
185 | __asm__ volatile ("mov %%bp, %%ax;" : "=r" (seed)); | |
186 | __asm__ volatile ("rdseed %%bp;" : "=r" (seed)); | |
187 | __asm__ volatile ("mov %%ax, %%bp;" : "=r" (seed)); | |
188 | ||
189 | __asm__ volatile ("mov %%sp, %%ax;" : "=r" (seed)); | |
190 | __asm__ volatile ("rdseed %%sp;" : "=r" (seed)); | |
191 | __asm__ volatile ("mov %%ax, %%sp;" : "=r" (seed)); | |
192 | ||
193 | __asm__ volatile ("rdseed %%r8w;" : "=r" (seed)); | |
194 | __asm__ volatile ("rdseed %%r9w;" : "=r" (seed)); | |
195 | __asm__ volatile ("rdseed %%r10w;" : "=r" (seed)); | |
196 | __asm__ volatile ("rdseed %%r11w;" : "=r" (seed)); | |
197 | __asm__ volatile ("rdseed %%r12w;" : "=r" (seed)); | |
198 | __asm__ volatile ("rdseed %%r13w;" : "=r" (seed)); | |
199 | __asm__ volatile ("rdseed %%r14w;" : "=r" (seed)); | |
200 | __asm__ volatile ("rdseed %%r15w;" : "=r" (seed)); | |
201 | ||
202 | /* 32-bit random seeds. */ | |
203 | __asm__ volatile ("rdseed %%eax;" : "=r" (seed)); | |
204 | __asm__ volatile ("rdseed %%ebx;" : "=r" (seed)); | |
205 | __asm__ volatile ("rdseed %%ecx;" : "=r" (seed)); | |
206 | __asm__ volatile ("rdseed %%edx;" : "=r" (seed)); | |
207 | ||
208 | __asm__ volatile ("mov %%rdi, %%rax;" : "=r" (seed)); | |
209 | __asm__ volatile ("rdseed %%edi;" : "=r" (seed)); | |
210 | __asm__ volatile ("mov %%rax, %%rdi;" : "=r" (seed)); | |
211 | ||
212 | __asm__ volatile ("mov %%rsi, %%rax;" : "=r" (seed)); | |
213 | __asm__ volatile ("rdseed %%esi;" : "=r" (seed)); | |
214 | __asm__ volatile ("mov %%rax, %%rsi;" : "=r" (seed)); | |
215 | ||
216 | __asm__ volatile ("mov %%rbp, %%rax;" : "=r" (seed)); | |
217 | __asm__ volatile ("rdseed %%ebp;" : "=r" (seed)); | |
218 | __asm__ volatile ("mov %%rax, %%rbp;" : "=r" (seed)); | |
219 | ||
220 | __asm__ volatile ("mov %%rsp, %%rax;" : "=r" (seed)); | |
221 | __asm__ volatile ("rdseed %%esp;" : "=r" (seed)); | |
222 | __asm__ volatile ("mov %%rax, %%rsp;" : "=r" (seed)); | |
223 | ||
224 | __asm__ volatile ("rdseed %%r8d;" : "=r" (seed)); | |
225 | __asm__ volatile ("rdseed %%r9d;" : "=r" (seed)); | |
226 | __asm__ volatile ("rdseed %%r10d;" : "=r" (seed)); | |
227 | __asm__ volatile ("rdseed %%r11d;" : "=r" (seed)); | |
228 | __asm__ volatile ("rdseed %%r12d;" : "=r" (seed)); | |
229 | __asm__ volatile ("rdseed %%r13d;" : "=r" (seed)); | |
230 | __asm__ volatile ("rdseed %%r14d;" : "=r" (seed)); | |
231 | __asm__ volatile ("rdseed %%r15d;" : "=r" (seed)); | |
232 | ||
233 | /* 64-bit random seeds. */ | |
234 | __asm__ volatile ("rdseed %%rax;" : "=r" (seed)); | |
235 | __asm__ volatile ("rdseed %%rbx;" : "=r" (seed)); | |
236 | __asm__ volatile ("rdseed %%rcx;" : "=r" (seed)); | |
237 | __asm__ volatile ("rdseed %%rdx;" : "=r" (seed)); | |
238 | ||
239 | __asm__ volatile ("mov %%rdi, %%rax;" : "=r" (seed)); | |
240 | __asm__ volatile ("rdseed %%rdi;" : "=r" (seed)); | |
241 | __asm__ volatile ("mov %%rax, %%rdi;" : "=r" (seed)); | |
242 | ||
243 | __asm__ volatile ("mov %%rsi, %%rax;" : "=r" (seed)); | |
244 | __asm__ volatile ("rdseed %%rsi;" : "=r" (seed)); | |
245 | __asm__ volatile ("mov %%rax, %%rsi;" : "=r" (seed)); | |
246 | ||
247 | __asm__ volatile ("mov %%rbp, %%rax;" : "=r" (seed)); | |
248 | __asm__ volatile ("rdseed %%rbp;" : "=r" (seed)); | |
249 | __asm__ volatile ("mov %%rax, %%rbp;" : "=r" (seed)); | |
250 | ||
251 | __asm__ volatile ("mov %%rsp, %%rax;" : "=r" (seed)); | |
252 | __asm__ volatile ("rdseed %%rsp;" : "=r" (seed)); | |
253 | __asm__ volatile ("mov %%rax, %%rsp;" : "=r" (seed)); | |
254 | ||
255 | __asm__ volatile ("rdseed %%r8;" : "=r" (seed)); | |
256 | __asm__ volatile ("rdseed %%r9;" : "=r" (seed)); | |
257 | __asm__ volatile ("rdseed %%r10;" : "=r" (seed)); | |
258 | __asm__ volatile ("rdseed %%r11;" : "=r" (seed)); | |
259 | __asm__ volatile ("rdseed %%r12;" : "=r" (seed)); | |
260 | __asm__ volatile ("rdseed %%r13;" : "=r" (seed)); | |
261 | __asm__ volatile ("rdseed %%r14;" : "=r" (seed)); | |
262 | __asm__ volatile ("rdseed %%r15;" : "=r" (seed)); | |
263 | } | |
264 | ||
265 | /* Initialize arch-specific bits. */ | |
266 | ||
267 | static void | |
268 | initialize (void) | |
269 | { | |
270 | /* Initialize supported features. */ | |
17cd4947 | 271 | check_supported_features (); |
20b477a7 LM |
272 | } |
273 | ||
274 | /* Functions testing instruction decodings. GDB will test all of these. */ | |
275 | static testcase_ftype testcases[] = | |
276 | { | |
277 | rdrand, | |
278 | rdseed | |
279 | }; |