xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.reverse/insn-reverse-x86.c (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1 /* This testcase is part of GDB, the GNU debugger.
2 
3    Copyright 2017-2020 Free Software Foundation, Inc.
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 
21 /* 0 if the CPU supports rdrand and non-zero otherwise.  */
22 static unsigned int supports_rdrand;
23 
24 /* 0 if the CPU supports rdseed and non-zero otherwise.  */
25 static unsigned int supports_rdseed;
26 
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)
32 {
33   unsigned int rdrand_mask = (1 << 30);
34   unsigned int rdseed_mask = (1 << 18);
35   unsigned int eax, ebx, ecx, edx;
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);
45 
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     }
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 
168   if (!supports_rdseed)
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.  */
271   check_supported_features ();
272 }
273 
274 /* Functions testing instruction decodings.  GDB will test all of these.  */
275 static testcase_ftype testcases[] =
276 {
277   rdrand,
278   rdseed
279 };
280