1 // REQUIRES: x86-registered-target
2 // RUN: %clang_cc1 %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - | FileCheck %s
3 
4 void t1() {
5 // CHECK: @t1
6 // CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
7 // CHECK: ret void
8   __asm {}
9 }
10 
11 void t2() {
12 // CHECK: @t2
13 // CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"()
14 // CHECK: ret void
15   __asm nop
16   __asm nop
17   __asm nop
18 }
19 
20 void t3() {
21 // CHECK: @t3
22 // CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"()
23 // CHECK: ret void
24   __asm nop __asm nop __asm nop
25 }
26 
27 void t4(void) {
28 // CHECK: @t4
29 // CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"()
30 // CHECK: ret void
31   __asm mov ebx, eax
32   __asm mov ecx, ebx
33 }
34 
35 void t5(void) {
36 // CHECK: @t5
37 // CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"()
38 // CHECK: ret void
39   __asm mov ebx, eax __asm mov ecx, ebx
40 }
41 
42 void t6(void) {
43   __asm int 0x2c
44 // CHECK: t6
45 // CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
46 }
47 
48 void t7() {
49   __asm {
50     int 0x2c ; } asm comments are fun! }{
51   }
52   __asm {
53     {
54       int 0x2c ; } asm comments are fun! }{
55     }
56   }
57   __asm {}
58 // CHECK: t7
59 // CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
60 // CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
61 }
62 
63 int t8() {
64   __asm int 4 ; } comments for single-line asm
65   __asm {}
66   __asm int 4
67   return 10;
68 // CHECK: t8
69 // CHECK: call void asm sideeffect inteldialect "int $$4\0A\09int $$4", "~{dirflag},~{fpsr},~{flags}"()
70 // CHECK: ret i32 10
71 }
72 
73 void t9() {
74   __asm {
75     push ebx
76     { mov ebx, 0x07 }
77     __asm { pop ebx }
78   }
79 // CHECK: t9
80 // CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
81 }
82 
83 unsigned t10(void) {
84   unsigned i = 1, j;
85   __asm {
86     mov eax, i
87     mov j, eax
88   }
89   return j;
90 // CHECK: t10
91 // CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4
92 // CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4
93 // CHECK: store i32 1, i32* [[I]], align 4
94 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}})
95 // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4
96 // CHECK: ret i32 [[RET]]
97 }
98 
99 void t11(void) {
100   __asm mov eax, 1
101 // CHECK: t11
102 // CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
103 }
104 
105 unsigned t12(void) {
106   unsigned i = 1, j, l = 1, m;
107   __asm {
108     mov eax, i
109     mov j, eax
110     mov eax, l
111     mov m, eax
112   }
113   return j + m;
114 // CHECK: t12
115 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $2\0A\09mov dword ptr $0, eax\0A\09mov eax, dword ptr $3\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
116 }
117 
118 void t13() {
119   char i = 1;
120   short j = 2;
121   __asm movzx eax, i
122   __asm movzx eax, j
123 // CHECK: t13
124 // CHECK: call void asm sideeffect inteldialect "movzx eax, byte ptr $0\0A\09movzx eax, word ptr $1", "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j)
125 }
126 
127 void t14() {
128   unsigned i = 1, j = 2;
129   __asm {
130     .if 1
131     { mov eax, i }
132     .else
133     mov ebx, j
134     .endif
135   }
136 // CHECK: t14
137 // CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, dword ptr $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
138 }
139 
140 int gvar = 10;
141 void t15() {
142 // CHECK: t15
143   int lvar = 10;
144   __asm mov eax, lvar        ; eax = 10
145 // CHECK: mov eax, dword ptr $0
146   __asm mov eax, offset lvar ; eax = address of lvar
147 // CHECK: mov eax, $1
148   __asm mov eax, offset gvar ; eax = address of gvar
149 // CHECK: mov eax, $2
150 // CHECK: "*m,r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* @{{.*}})
151 }
152 
153 void t16() {
154   int var = 10;
155   __asm mov [eax], offset var
156 // CHECK: t16
157 // CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
158 }
159 
160 void t17() {
161 // CHECK: t17
162   __asm _emit 0x4A
163 // CHECK: .byte 0x4A
164   __asm _emit 0x43
165 // CHECK: .byte 0x43
166   __asm _emit 0x4B
167 // CHECK: .byte 0x4B
168   __asm _EMIT 0x4B
169 // CHECK: .byte 0x4B
170 // CHECK:  "~{dirflag},~{fpsr},~{flags}"()
171 }
172 
173 void t20() {
174 // CHECK: t20
175   char bar;
176   int foo;
177   char _bar[2];
178   int _foo[4];
179 
180   __asm mov eax, LENGTH foo
181 // CHECK: mov eax, $$1
182   __asm mov eax, LENGTH bar
183 // CHECK: mov eax, $$1
184   __asm mov eax, LENGTH _foo
185 // CHECK: mov eax, $$4
186   __asm mov eax, LENGTH _bar
187 // CHECK: mov eax, $$2
188 
189   __asm mov eax, TYPE foo
190 // CHECK: mov eax, $$4
191   __asm mov eax, TYPE bar
192 // CHECK: mov eax, $$1
193   __asm mov eax, TYPE _foo
194 // CHECK: mov eax, $$4
195   __asm mov eax, TYPE _bar
196 // CHECK: mov eax, $$1
197 
198   __asm mov eax, SIZE foo
199 // CHECK: mov eax, $$4
200   __asm mov eax, SIZE bar
201 // CHECK: mov eax, $$1
202   __asm mov eax, SIZE _foo
203 // CHECK: mov eax, $$16
204   __asm mov eax, SIZE _bar
205 // CHECK: mov eax, $$2
206 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
207 }
208 
209 void t21() {
210   __asm {
211     __asm push ebx
212     __asm mov ebx, 0x07
213     __asm pop ebx
214   }
215 // CHECK: t21
216 // CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
217 }
218 
219 extern void t22_helper(int x);
220 void t22() {
221   int x = 0;
222   __asm {
223     __asm push ebx
224     __asm mov ebx, esp
225   }
226   t22_helper(x);
227   __asm {
228     __asm mov esp, ebx
229     __asm pop ebx
230   }
231 // CHECK: t22
232 // CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
233 // CHECK: call void @t22_helper
234 // CHECK: call void asm sideeffect inteldialect "mov esp, ebx\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
235 }
236 
237 void t23() {
238   __asm {
239   the_label:
240   }
241 // CHECK: t23
242 // CHECK: call void asm sideeffect inteldialect "the_label:", "~{dirflag},~{fpsr},~{flags}"()
243 }
244 
245 void t24_helper(void) {}
246 void t24() {
247   __asm call t24_helper
248 // CHECK: t24
249 // CHECK: call void asm sideeffect inteldialect "call dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper)
250 }
251 
252 void t25() {
253 // CHECK: t25
254   __asm mov eax, 0ffffffffh
255 // CHECK: mov eax, $$4294967295
256   __asm mov eax, 0fh
257 // CHECK: mov eax, $$15
258   __asm mov eax, 0a2h
259 // CHECK: mov eax, $$162
260   __asm mov eax, 0xa2h
261 // CHECK: mov eax, $$0xa2h
262   __asm mov eax, 0xa2
263 // CHECK: mov eax, $$0xa2
264 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
265 }
266 
267 void t26() {
268 // CHECK: t26
269   __asm pushad
270 // CHECK: pushad
271   __asm mov eax, 0
272 // CHECK: mov eax, $$0
273   __asm __emit 0fh
274 // CHECK: .byte 0fh
275   __asm __emit 0a2h
276 // CHECK: .byte 0a2h
277   __asm __EMIT 0a2h
278 // CHECK: .byte 0a2h
279   __asm popad
280 // CHECK: popad
281 // CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
282 }
283 
284 void t27() {
285   __asm mov eax, fs:[0h]
286 // CHECK: t27
287 // CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
288 }
289 
290 void t28() {
291 // CHECK: t28
292   __asm align 8
293 // CHECK: .align 3
294   __asm align 16;
295 // CHECK: .align 4
296   __asm align 128;
297 // CHECK: .align 7
298   __asm ALIGN 256;
299 // CHECK: .align 8
300 // CHECK: "~{dirflag},~{fpsr},~{flags}"()
301 }
302 
303 void t29() {
304 // CHECK: t29
305   int arr[2] = {0, 0};
306   int olen = 0, osize = 0, otype = 0;
307   __asm mov olen, LENGTH arr
308 // CHECK: mov dword ptr $0, $$2
309   __asm mov osize, SIZE arr
310 // CHECK: mov dword ptr $1, $$8
311   __asm mov otype, TYPE arr
312 // CHECK: mov dword ptr $2, $$4
313 // CHECK: "=*m,=*m,=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
314 }
315 
316 int results[2] = {13, 37};
317 int *t30()
318 // CHECK: t30
319 {
320   int *res;
321   __asm lea edi, results
322 // CHECK: lea edi, dword ptr $1
323   __asm mov res, edi
324 // CHECK: mov dword ptr $0, edi
325   return res;
326 // CHECK: "=*m,*m,~{edi},~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}, [2 x i32]* @{{.*}})
327 }
328 
329 void t31() {
330 // CHECK: t31
331   __asm pushad
332 // CHECK: pushad
333   __asm popad
334 // CHECK: popad
335 // CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
336 }
337 
338 void t32() {
339 // CHECK: t32
340   int i;
341   __asm mov eax, i
342 // CHECK: mov eax, dword ptr $0
343   __asm mov eax, dword ptr i
344 // CHECK: mov eax, dword ptr $1
345   __asm mov ax, word ptr i
346 // CHECK: mov ax, word ptr $2
347   __asm mov al, byte ptr i
348 // CHECK: mov al, byte ptr $3
349 // CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
350 }
351 
352 void t33() {
353 // CHECK: t33
354   int i;
355   __asm mov eax, [i]
356 // CHECK: mov eax, dword ptr $0
357   __asm mov eax, dword ptr [i]
358 // CHECK: mov eax, dword ptr $1
359   __asm mov ax, word ptr [i]
360 // CHECK: mov ax, word ptr $2
361   __asm mov al, byte ptr [i]
362 // CHECK: mov al, byte ptr $3
363 // CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
364 }
365 
366 void t34() {
367 // CHECK: t34
368   __asm prefetchnta 64[eax]
369 // CHECK: prefetchnta $$64[eax]
370   __asm mov eax, dword ptr 4[eax]
371 // CHECK: mov eax, dword ptr $$4[eax]
372 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
373 }
374 
375 void t35() {
376 // CHECK: t35
377   __asm prefetchnta [eax + (200*64)]
378 // CHECK: prefetchnta [eax + ($$200*$$64)]
379   __asm mov eax, dword ptr [eax + (200*64)]
380 // CHECK: mov eax, dword ptr [eax + ($$200*$$64)]
381 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
382 }
383 
384 void t36() {
385 // CHECK: t36
386   int arr[4];
387   // Work around PR20368: These should be single line blocks
388   __asm { mov eax, 4[arr] }
389 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
390   __asm { mov eax, 4[arr + 4] }
391 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
392   __asm { mov eax, 8[arr + 4 + 32*2 - 4] }
393 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
394   __asm { mov eax, 12[4 + arr] }
395 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
396   __asm { mov eax, 4[4 + arr + 4] }
397 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
398   __asm { mov eax, 4[64 + arr + (2*32)] }
399 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
400   __asm { mov eax, 4[64 + arr - 2*32] }
401 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
402   __asm { mov eax, [arr + 4] }
403 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
404   __asm { mov eax, [arr + 4 + 32*2 - 4] }
405 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
406   __asm { mov eax, [4 + arr] }
407 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
408   __asm { mov eax, [4 + arr + 4] }
409 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
410   __asm { mov eax, [64 + arr + (2*32)] }
411 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
412   __asm { mov eax, [64 + arr - 2*32] }
413 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
414 }
415 
416 void t37() {
417 // CHECK: t37
418   __asm mov eax, 4 + 8
419 // CHECK: mov eax, $$12
420   __asm mov eax, 4 + 8 * 16
421 // CHECK: mov eax, $$132
422   __asm mov eax, -4 + 8 * 16
423 // CHECK: mov eax, $$124
424   __asm mov eax, (4 + 4) * 16
425 // CHECK: mov eax, $$128
426   __asm mov eax, 4 + 8 * -16
427 // CHECK: mov eax, $$4294967172
428   __asm mov eax, 4 + 16 / -8
429 // CHECK: mov eax, $$2
430   __asm mov eax, (16 + 16) / -8
431 // CHECK: mov eax, $$4294967292
432   __asm mov eax, ~15
433 // CHECK: mov eax, $$4294967280
434 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
435 }
436 
437 void t38() {
438 // CHECK: t38
439   int arr[4];
440   // Work around PR20368: These should be single line blocks
441   __asm { mov eax, 4+4[arr] }
442 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
443   __asm { mov eax, (4+4)[arr + 4] }
444 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
445   __asm { mov eax, 8*2[arr + 4 + 32*2 - 4] }
446 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$80$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
447   __asm { mov eax, 12+20[4 + arr] }
448 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$36$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
449   __asm { mov eax, 4*16+4[4 + arr + 4] }
450 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$76$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
451   __asm { mov eax, 4*4[64 + arr + (2*32)] }
452 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$144$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
453   __asm { mov eax, 4*(4-2)[64 + arr - 2*32] }
454 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
455   __asm { mov eax, 32*(4-2)[arr - 2*32] }
456 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
457 }
458 
459 void cpuid() {
460   __asm cpuid
461 // CHECK-LABEL: define void @cpuid
462 // CHECK: call void asm sideeffect inteldialect "cpuid", "~{eax},~{ebx},~{ecx},~{edx},~{dirflag},~{fpsr},~{flags}"()
463 }
464 
465 typedef struct {
466   int a;
467   int b;
468 } A;
469 
470 void t39() {
471 // CHECK-LABEL: define void @t39
472   __asm mov eax, [eax].A.b
473 // CHECK: mov eax, [eax].4
474   __asm mov eax, [eax] A.b
475 // CHECK: mov eax, [eax] .4
476   __asm mov eax, fs:[0] A.b
477 // CHECK: mov eax, fs:[$$0] .4
478 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
479 }
480 
481 void t40(float a) {
482 // CHECK-LABEL: define void @t40
483   int i;
484   __asm fld a
485 // CHECK: fld dword ptr $1
486   __asm fistp i
487 // CHECK: fistp dword ptr $0
488 // CHECK: "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, float* %{{.*}})
489 }
490 
491 void t41(unsigned short a) {
492 // CHECK-LABEL: define void @t41(i16 zeroext %a)
493   __asm mov cs, a;
494 // CHECK: mov cs, word ptr $0
495   __asm mov ds, a;
496 // CHECK: mov ds, word ptr $1
497   __asm mov es, a;
498 // CHECK: mov es, word ptr $2
499   __asm mov fs, a;
500 // CHECK: mov fs, word ptr $3
501   __asm mov gs, a;
502 // CHECK: mov gs, word ptr $4
503   __asm mov ss, a;
504 // CHECK: mov ss, word ptr $5
505 // CHECK: "*m,*m,*m,*m,*m,*m,~{dirflag},~{fpsr},~{flags}"(i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}})
506 }
507 
508 void call_clobber() {
509   __asm call t41
510   // CHECK-LABEL: define void @call_clobber
511   // CHECK: call void asm sideeffect inteldialect "call dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(void (i16)* @t41)
512 }
513