1 #include "tests/asm.h"
2 #include <stdio.h>
3 
4 /* This test only checks register/register cmpxchg */
5 
6 typedef unsigned long long int ULong;
7 typedef unsigned int UInt;
8 
9 ULong m64;
10 
11 ULong rax;
12 ULong rbx;
13 ULong rcx;
14 ULong rdx;
15 ULong rax_out;
16 ULong rbx_out;
17 ULong rcx_out;
18 
main(void)19 int 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