1#include "tests/asm.h"
2#include <stdio.h>
3
4/* This test only checks register/register cmpxchg */
5
6typedef unsigned long long int ULong;
7typedef unsigned int UInt;
8
9ULong m64;
10
11ULong rax;
12ULong rbx;
13ULong rcx;
14ULong rdx;
15ULong rax_out;
16ULong rbx_out;
17ULong rcx_out;
18
19int main ( void )
20{
21
22   /* 8-bit */
23
24   rdx  = 0x11111111; rax = 0x22222222;
25   rcx  = 0x33333333; rbx = 0x44444444;
26
27   printf("cmpxchg %%bl,%%cl  (al=%llx bl=%llx cl=%llx)\n",
28	  rax&0xff,rbx&0xff,rcx&0xff);
29
30   asm("\n"
31    "\tpush %rax\n"
32    "\tpush %rbx\n"
33    "\tpush %rcx\n"
34    "\tpush %rdx\n"
35    "\txor %rax, %rax\n" // get eflags in a known state
36#ifndef VGP_amd64_darwin
37    "\tmov " VG_SYM(rax) ",%rax\n"
38    "\tmov " VG_SYM(rbx) ",%rbx\n"
39    "\tmov " VG_SYM(rcx) ",%rcx\n"
40    "\tmov " VG_SYM(rdx) ",%rdx\n"
41#else
42    "\tmov " VG_SYM(rax) "(%rip),%rax\n"
43    "\tmov " VG_SYM(rbx) "(%rip),%rbx\n"
44    "\tmov " VG_SYM(rcx) "(%rip),%rcx\n"
45    "\tmov " VG_SYM(rdx) "(%rip),%rdx\n"
46#endif
47    "\tcmpxchg %bl,%cl \n"
48#ifndef VGP_amd64_darwin
49    "\tmov %rax," VG_SYM(rax_out) "\n"
50    "\tmov %rbx," VG_SYM(rbx_out) "\n"
51    "\tmov %rcx," VG_SYM(rcx_out) "\n"
52#else
53    "\tmov %rax," VG_SYM(rax_out) "(%rip)\n"
54    "\tmov %rbx," VG_SYM(rbx_out) "(%rip)\n"
55    "\tmov %rcx," VG_SYM(rcx_out) "(%rip)\n"
56#endif
57    "\tpop %rdx\n"
58    "\tpop %rcx\n"
59    "\tpop %rbx\n"
60    "\tpop %rax\n"
61    );
62
63   printf("  al!=cl so al should equal cl (Result al=%llx bl=%llx cl=%llx)\n",
64	  rax_out&0xff,rbx_out&0xff,rcx_out&0xff);
65
66
67
68   rdx  = 0x99999999; rax = 0x77777777;
69   rcx  = 0x55555555; rbx = 0x55555555;
70
71   printf("cmpxchg %%bl,%%cl  (al=%llx bl=%llx cl=%llx)\n",
72	  rax&0xff,rbx&0xff,rcx&0xff);
73
74   asm("\n"
75    "\tpush %rax\n"
76    "\tpush %rbx\n"
77    "\tpush %rcx\n"
78    "\tpush %rdx\n"
79    "\txor %rax, %rax\n" // get eflags in a known state
80#ifndef VGP_amd64_darwin
81    "\tmov " VG_SYM(rax) ",%rax\n"
82    "\tmov " VG_SYM(rbx) ",%rbx\n"
83    "\tmov " VG_SYM(rcx) ",%rcx\n"
84    "\tmov " VG_SYM(rdx) ",%rdx\n"
85#else
86    "\tmov " VG_SYM(rax) "(%rip),%rax\n"
87    "\tmov " VG_SYM(rbx) "(%rip),%rbx\n"
88    "\tmov " VG_SYM(rcx) "(%rip),%rcx\n"
89    "\tmov " VG_SYM(rdx) "(%rip),%rdx\n"
90#endif
91    "\tcmpxchg %bl,%cl \n"
92#ifndef VGP_amd64_darwin
93    "\tmov %rax," VG_SYM(rax_out) "\n"
94    "\tmov %rbx," VG_SYM(rbx_out) "\n"
95    "\tmov %rcx," VG_SYM(rcx_out) "\n"
96#else
97    "\tmov %rax," VG_SYM(rax_out) "(%rip)\n"
98    "\tmov %rbx," VG_SYM(rbx_out) "(%rip)\n"
99    "\tmov %rcx," VG_SYM(rcx_out) "(%rip)\n"
100#endif
101    "\tpop %rdx\n"
102    "\tpop %rcx\n"
103    "\tpop %rbx\n"
104    "\tpop %rax\n"
105    );
106
107   printf("  al==cl so cl should equal bl (Result al=%llx bl=%llx cl=%llx)\n",
108	  rax_out&0xff,rbx_out&0xff,rcx_out&0xff);
109
110   /* 16-bit */
111
112   rdx  = 0x11111111; rax = 0x22222222;
113   rcx  = 0x33333333; rbx = 0x44444444;
114
115   printf("cmpxchg %%bx,%%cx  (ax=%llx bx=%llx cx=%llx)\n",
116	  rax&0xffff,rbx&0xffff,rcx&0xffff);
117
118   asm("\n"
119    "\tpush %rax\n"
120    "\tpush %rbx\n"
121    "\tpush %rcx\n"
122    "\tpush %rdx\n"
123    "\txor %rax, %rax\n" // get eflags in a known state
124#ifndef VGP_amd64_darwin
125    "\tmov " VG_SYM(rax) ",%rax\n"
126    "\tmov " VG_SYM(rbx) ",%rbx\n"
127    "\tmov " VG_SYM(rcx) ",%rcx\n"
128    "\tmov " VG_SYM(rdx) ",%rdx\n"
129#else
130    "\tmov " VG_SYM(rax) "(%rip),%rax\n"
131    "\tmov " VG_SYM(rbx) "(%rip),%rbx\n"
132    "\tmov " VG_SYM(rcx) "(%rip),%rcx\n"
133    "\tmov " VG_SYM(rdx) "(%rip),%rdx\n"
134#endif
135    "\tcmpxchg %bx,%cx \n"
136#ifndef VGP_amd64_darwin
137    "\tmov %rax," VG_SYM(rax_out) "\n"
138    "\tmov %rbx," VG_SYM(rbx_out) "\n"
139    "\tmov %rcx," VG_SYM(rcx_out) "\n"
140#else
141    "\tmov %rax," VG_SYM(rax_out) "(%rip)\n"
142    "\tmov %rbx," VG_SYM(rbx_out) "(%rip)\n"
143    "\tmov %rcx," VG_SYM(rcx_out) "(%rip)\n"
144#endif
145    "\tpop %rdx\n"
146    "\tpop %rcx\n"
147    "\tpop %rbx\n"
148    "\tpop %rax\n"
149    );
150
151   printf("  ax!=cx so ax should equal cx (Result ax=%llx bx=%llx cx=%llx)\n",
152	  rax_out&0xffff,rbx_out&0xffff,rcx_out&0xffff);
153
154
155
156   rdx  = 0x99999999; rax = 0x77777777;
157   rcx  = 0x55555555; rbx = 0x55555555;
158
159   printf("cmpxchg %%bx,%%cx  (ax=%llx bx=%llx cx=%llx)\n",
160	  rax&0xffff,rbx&0xffff,rcx&0xffff);
161
162   asm("\n"
163    "\tpush %rax\n"
164    "\tpush %rbx\n"
165    "\tpush %rcx\n"
166    "\tpush %rdx\n"
167    "\txor %rax, %rax\n" // get eflags in a known state
168#ifndef VGP_amd64_darwin
169    "\tmov " VG_SYM(rax) ",%rax\n"
170    "\tmov " VG_SYM(rbx) ",%rbx\n"
171    "\tmov " VG_SYM(rcx) ",%rcx\n"
172    "\tmov " VG_SYM(rdx) ",%rdx\n"
173#else
174    "\tmov " VG_SYM(rax) "(%rip),%rax\n"
175    "\tmov " VG_SYM(rbx) "(%rip),%rbx\n"
176    "\tmov " VG_SYM(rcx) "(%rip),%rcx\n"
177    "\tmov " VG_SYM(rdx) "(%rip),%rdx\n"
178#endif
179    "\tcmpxchg %bx,%cx \n"
180#ifndef VGP_amd64_darwin
181    "\tmov %rax," VG_SYM(rax_out) "\n"
182    "\tmov %rbx," VG_SYM(rbx_out) "\n"
183    "\tmov %rcx," VG_SYM(rcx_out) "\n"
184#else
185    "\tmov %rax," VG_SYM(rax_out) "(%rip)\n"
186    "\tmov %rbx," VG_SYM(rbx_out) "(%rip)\n"
187    "\tmov %rcx," VG_SYM(rcx_out) "(%rip)\n"
188#endif
189    "\tpop %rdx\n"
190    "\tpop %rcx\n"
191    "\tpop %rbx\n"
192    "\tpop %rax\n"
193    );
194
195   printf("  ax==cx so cx should equal bx (Result ax=%llx bx=%llx cx=%llx)\n",
196	  rax_out&0xffff,rbx_out&0xffff,rcx_out&0xffff);
197
198
199   /* 32-bit */
200
201   rdx  = 0x11111111; rax = 0x22222222;
202   rcx  = 0x33333333; rbx = 0x44444444;
203
204   printf("cmpxchg %%ebx,%%ecx  (eax=%llx ebx=%llx ecx=%llx)\n",
205	  rax&0xffffffff,rbx&0xffffffff,rcx&0xffffffff);
206
207   asm("\n"
208    "\tpush %rax\n"
209    "\tpush %rbx\n"
210    "\tpush %rcx\n"
211    "\tpush %rdx\n"
212    "\txor %rax, %rax\n" // get eflags in a known state
213#ifndef VGP_amd64_darwin
214    "\tmov " VG_SYM(rax) ",%rax\n"
215    "\tmov " VG_SYM(rbx) ",%rbx\n"
216    "\tmov " VG_SYM(rcx) ",%rcx\n"
217    "\tmov " VG_SYM(rdx) ",%rdx\n"
218#else
219    "\tmov " VG_SYM(rax) "(%rip),%rax\n"
220    "\tmov " VG_SYM(rbx) "(%rip),%rbx\n"
221    "\tmov " VG_SYM(rcx) "(%rip),%rcx\n"
222    "\tmov " VG_SYM(rdx) "(%rip),%rdx\n"
223#endif
224    "\tcmpxchg %ebx,%ecx \n"
225#ifndef VGP_amd64_darwin
226    "\tmov %rax," VG_SYM(rax_out) "\n"
227    "\tmov %rbx," VG_SYM(rbx_out) "\n"
228    "\tmov %rcx," VG_SYM(rcx_out) "\n"
229#else
230    "\tmov %rax," VG_SYM(rax_out) "(%rip)\n"
231    "\tmov %rbx," VG_SYM(rbx_out) "(%rip)\n"
232    "\tmov %rcx," VG_SYM(rcx_out) "(%rip)\n"
233#endif
234    "\tpop %rdx\n"
235    "\tpop %rcx\n"
236    "\tpop %rbx\n"
237    "\tpop %rax\n"
238    );
239
240   printf("  eax!=ecx so eax should equal ecx (Result eax=%llx ebx=%llx ecx=%llx)\n",
241	  rax_out&0xffffffff,rbx_out&0xffffffff,rcx_out&0xffffffff);
242
243
244
245   rdx  = 0x99999999; rax = 0x77777777;
246   rcx  = 0x55555555; rbx = 0x55555555;
247
248   printf("cmpxchg %%ebx,%%ecx  (eax=%llx ebx=%llx ecx=%llx)\n",
249	  rax&0xffffffff,rbx&0xffffffff,rcx&0xffffffff);
250
251   asm("\n"
252    "\tpush %rax\n"
253    "\tpush %rbx\n"
254    "\tpush %rcx\n"
255    "\tpush %rdx\n"
256    "\txor %rax, %rax\n" // get eflags in a known state
257#ifndef VGP_amd64_darwin
258    "\tmov " VG_SYM(rax) ",%rax\n"
259    "\tmov " VG_SYM(rbx) ",%rbx\n"
260    "\tmov " VG_SYM(rcx) ",%rcx\n"
261    "\tmov " VG_SYM(rdx) ",%rdx\n"
262#else
263    "\tmov " VG_SYM(rax) "(%rip),%rax\n"
264    "\tmov " VG_SYM(rbx) "(%rip),%rbx\n"
265    "\tmov " VG_SYM(rcx) "(%rip),%rcx\n"
266    "\tmov " VG_SYM(rdx) "(%rip),%rdx\n"
267#endif
268    "\tcmpxchg %ebx,%ecx \n"
269#ifndef VGP_amd64_darwin
270    "\tmov %rax," VG_SYM(rax_out) "\n"
271    "\tmov %rbx," VG_SYM(rbx_out) "\n"
272    "\tmov %rcx," VG_SYM(rcx_out) "\n"
273#else
274    "\tmov %rax," VG_SYM(rax_out) "(%rip)\n"
275    "\tmov %rbx," VG_SYM(rbx_out) "(%rip)\n"
276    "\tmov %rcx," VG_SYM(rcx_out) "(%rip)\n"
277#endif
278    "\tpop %rdx\n"
279    "\tpop %rcx\n"
280    "\tpop %rbx\n"
281    "\tpop %rax\n"
282    );
283
284   printf("  eax==ecx so ecx should equal ebx (Result eax=%llx ebx=%llx ecx=%llx)\n",
285	  rax_out&0xffffffff,rbx_out&0xffffffff,rcx_out&0xffffffff);
286
287
288   /* 64-bit */
289
290   rdx  = 0x111111111; rax = 0x222222222;
291   rcx  = 0x333333333; rbx = 0x444444444;
292
293   printf("cmpxchg %%rbx,%%rcx  (rax=%llx rbx=%llx rcx=%llx)\n",
294	  rax,rbx,rcx);
295
296   asm("\n"
297    "\tpush %rax\n"
298    "\tpush %rbx\n"
299    "\tpush %rcx\n"
300    "\tpush %rdx\n"
301    "\txor %rax, %rax\n" // get eflags in a known state
302#ifndef VGP_amd64_darwin
303    "\tmov " VG_SYM(rax) ",%rax\n"
304    "\tmov " VG_SYM(rbx) ",%rbx\n"
305    "\tmov " VG_SYM(rcx) ",%rcx\n"
306    "\tmov " VG_SYM(rdx) ",%rdx\n"
307#else
308    "\tmov " VG_SYM(rax) "(%rip),%rax\n"
309    "\tmov " VG_SYM(rbx) "(%rip),%rbx\n"
310    "\tmov " VG_SYM(rcx) "(%rip),%rcx\n"
311    "\tmov " VG_SYM(rdx) "(%rip),%rdx\n"
312#endif
313    "\tcmpxchg %rbx,%rcx \n"
314#ifndef VGP_amd64_darwin
315    "\tmov %rax," VG_SYM(rax_out) "\n"
316    "\tmov %rbx," VG_SYM(rbx_out) "\n"
317    "\tmov %rcx," VG_SYM(rcx_out) "\n"
318#else
319    "\tmov %rax," VG_SYM(rax_out) "(%rip)\n"
320    "\tmov %rbx," VG_SYM(rbx_out) "(%rip)\n"
321    "\tmov %rcx," VG_SYM(rcx_out) "(%rip)\n"
322#endif
323    "\tpop %rdx\n"
324    "\tpop %rcx\n"
325    "\tpop %rbx\n"
326    "\tpop %rax\n"
327    );
328
329   printf("  rax!=rcx so rax should equal rcx (Result rax=%llx rbx=%llx rcx=%llx)\n",
330	  rax_out,rbx_out,rcx_out);
331
332
333
334   rdx  = 0x999999999; rax = 0x777777777;
335   rcx  = 0x555555555; rbx = 0x555555555;
336
337   printf("cmpxchg %%rbx,%%rcx  (rax=%llx rbx=%llx rcx=%llx)\n",
338	  rax,rbx,rcx);
339
340   asm("\n"
341    "\tpush %rax\n"
342    "\tpush %rbx\n"
343    "\tpush %rcx\n"
344    "\tpush %rdx\n"
345    "\txor %rax, %rax\n" // get eflags in a known state
346#ifndef VGP_amd64_darwin
347    "\tmov " VG_SYM(rax) ",%rax\n"
348    "\tmov " VG_SYM(rbx) ",%rbx\n"
349    "\tmov " VG_SYM(rcx) ",%rcx\n"
350    "\tmov " VG_SYM(rdx) ",%rdx\n"
351#else
352    "\tmov " VG_SYM(rax) "(%rip),%rax\n"
353    "\tmov " VG_SYM(rbx) "(%rip),%rbx\n"
354    "\tmov " VG_SYM(rcx) "(%rip),%rcx\n"
355    "\tmov " VG_SYM(rdx) "(%rip),%rdx\n"
356#endif
357    "\tcmpxchg %rbx,%rcx \n"
358#ifndef VGP_amd64_darwin
359    "\tmov %rax," VG_SYM(rax_out) "\n"
360    "\tmov %rbx," VG_SYM(rbx_out) "\n"
361    "\tmov %rcx," VG_SYM(rcx_out) "\n"
362#else
363    "\tmov %rax," VG_SYM(rax_out) "(%rip)\n"
364    "\tmov %rbx," VG_SYM(rbx_out) "(%rip)\n"
365    "\tmov %rcx," VG_SYM(rcx_out) "(%rip)\n"
366#endif
367    "\tpop %rdx\n"
368    "\tpop %rcx\n"
369    "\tpop %rbx\n"
370    "\tpop %rax\n"
371    );
372
373   printf("  rax==rcx so ecx should equal rbx (Result rax=%llx rbx=%llx rcx=%llx)\n",
374	  rax_out,rbx_out,rcx_out);
375
376   return 0;
377}
378