Clang Project

clang_source_code/test/CodeGen/ms-inline-asm.c
1// REQUIRES: x86-registered-target
2// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - | FileCheck %s
3
4void t1() {
5// CHECK: @t1
6// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
7// CHECK: ret void
8  __asm {}
9}
10
11void 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
20void 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
27void 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
35void 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
42void t6(void) {
43  __asm int 0x2c
44// CHECK: t6
45// CHECK: call void asm sideeffect inteldialect "int $$44", "~{dirflag},~{fpsr},~{flags}"()
46}
47
48void t7() {
49  __asm {
50    int 0x2cU ; } asm comments are fun! }{
51  }
52  __asm {
53    {
54      int 0x2c ; } asm comments are fun! }{
55    }
56  }
57  __asm {}
58  __asm {
59    ;
60    ; label
61    mov eax, ebx
62  }
63// CHECK: t7
64// CHECK: call void asm sideeffect inteldialect "int $$44", "~{dirflag},~{fpsr},~{flags}"()
65// CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"()
66// CHECK: call void asm sideeffect inteldialect "mov eax, ebx", "~{eax},~{dirflag},~{fpsr},~{flags}"()
67}
68
69int t8() {
70  __asm int 4 ; } comments for single-line asm
71  __asm {}
72  __asm { int 5}
73  __asm int 6
74  __asm int 7
75  __asm { 
76    int 8
77  }
78  return 10;
79// CHECK: t8
80// CHECK: call i32 asm sideeffect inteldialect "int $$4", "={eax},~{dirflag},~{fpsr},~{flags}"()
81// CHECK: call i32 asm sideeffect inteldialect "", "={eax},~{dirflag},~{fpsr},~{flags}"()
82// CHECK: call i32 asm sideeffect inteldialect "int $$5", "={eax},~{dirflag},~{fpsr},~{flags}"()
83// CHECK: call i32 asm sideeffect inteldialect "int $$6\0A\09int $$7", "={eax},~{dirflag},~{fpsr},~{flags}"()
84// CHECK: call i32 asm sideeffect inteldialect "int $$8", "={eax},~{dirflag},~{fpsr},~{flags}"()
85// CHECK: ret i32 10
86}
87
88void t9() {
89  __asm {
90    push ebx
91    { mov ebx, 0x07 }
92    __asm { pop ebx }
93  }
94// CHECK: t9
95// CHECK: call void asm sideeffect inteldialect
96// CHECK-SAME: push ebx
97// CHECK-SAME: mov ebx, $$7
98// CHECK-SAME: pop ebx
99// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
100}
101
102unsigned t10(void) {
103  unsigned i = 1, j;
104  __asm {
105    mov eax, i
106    mov j, eax
107  }
108  return j;
109// CHECK: t10
110// CHECK: [[r:%[a-zA-Z0-9]+]] = alloca i32, align 4
111// CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4
112// CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4
113// CHECK: store i32 1, i32* [[I]], align 4
114// CHECK: call i32 asm sideeffect inteldialect
115// CHECK-SAME: mov eax, $2
116// CHECK-SAME: mov $0, eax
117// CHECK-SAME: "=*m,={eax},*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}})
118// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32, i32* [[J]], align 4
119// CHECK: ret i32 [[RET]]
120}
121
122void t11(void) {
123  __asm mov eax, 1
124// CHECK: t11
125// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
126}
127
128unsigned t12(void) {
129  unsigned i = 1, j, l = 1, m;
130  __asm {
131    mov eax, i
132    mov j, eax
133    mov eax, l
134    mov m, eax
135  }
136  return j + m;
137// CHECK: t12
138// CHECK: call i32 asm sideeffect inteldialect
139// CHECK-SAME: mov eax, $3
140// CHECK-SAME: mov $0, eax
141// CHECK-SAME: mov eax, $4
142// CHECK-SAME: mov $1, eax
143// CHECK-SAME: "=*m,=*m,={eax},*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
144}
145
146void t13() {
147  char i = 1;
148  short j = 2;
149  __asm movzx eax, i
150  __asm movzx eax, j
151// CHECK-LABEL: define void @t13()
152// CHECK: call void asm sideeffect inteldialect
153// CHECK-SAME: movzx eax, byte ptr $0
154// CHECK-SAME: movzx eax, word ptr $1
155// CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j)
156}
157
158void t13_brac() {
159  char i = 1;
160  short j = 2;
161  __asm movzx eax, [i]
162  __asm movzx eax, [j]
163// CHECK-LABEL: define void @t13_brac()
164// CHECK: call void asm sideeffect inteldialect
165// CHECK-SAME: movzx eax, byte ptr $0
166// CHECK-SAME: movzx eax, word ptr $1
167// CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j)
168}
169
170void t14() {
171  unsigned i = 1, j = 2;
172  __asm {
173    .if 1
174    { mov eax, i }
175    .else
176    mov ebx, j
177    .endif
178  }
179// CHECK: t14
180// CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
181}
182
183int gvar = 10;
184void t15() {
185// CHECK: t15
186  int lvar = 10;
187  __asm mov eax, lvar        ; eax = 10
188// CHECK: mov eax, $0
189  __asm mov eax, offset lvar ; eax = address of lvar
190// CHECK: mov eax, $1
191  __asm mov eax, offset gvar ; eax = address of gvar
192// CHECK: mov eax, $2
193// CHECK: "*m,r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* @{{.*}})
194}
195
196void t16() {
197  int var = 10;
198  __asm mov [eax], offset var
199// CHECK: t16
200// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
201}
202
203void t17() {
204// CHECK: t17
205  __asm _emit 0x4A
206// CHECK: .byte 0x4A
207  __asm _emit 0x43L
208// CHECK: .byte 0x43L
209  __asm _emit 0x4B
210// CHECK: .byte 0x4B
211  __asm _EMIT 0x4B
212// CHECK: .byte 0x4B
213// CHECK:  "~{dirflag},~{fpsr},~{flags}"()
214}
215
216void t20() {
217// CHECK: t20
218  char bar;
219  int foo;
220  char _bar[2];
221  int _foo[4];
222
223  __asm mov eax, LENGTH foo
224// CHECK: mov eax, $$1
225  __asm mov eax, LENGTH bar
226// CHECK: mov eax, $$1
227  __asm mov eax, LENGTH _foo
228// CHECK: mov eax, $$4
229  __asm mov eax, LENGTH _bar
230// CHECK: mov eax, $$2
231  __asm mov eax, [eax + LENGTH foo * 4]
232// CHECK: mov eax, [eax + $$4]
233
234  __asm mov eax, TYPE foo
235// CHECK: mov eax, $$4
236  __asm mov eax, TYPE bar
237// CHECK: mov eax, $$1
238  __asm mov eax, TYPE _foo
239// CHECK: mov eax, $$4
240  __asm mov eax, TYPE _bar
241// CHECK: mov eax, $$1
242  __asm mov eax, [eax + TYPE foo * 4]
243// CHECK: mov eax, [eax + $$16]
244
245  __asm mov eax, SIZE foo
246// CHECK: mov eax, $$4
247  __asm mov eax, SIZE bar
248// CHECK: mov eax, $$1
249  __asm mov eax, SIZE _foo
250// CHECK: mov eax, $$16
251  __asm mov eax, [eax + SIZE _foo * 4]
252// CHECK: mov eax, [eax + $$64]
253  __asm mov eax, SIZE _bar
254// CHECK: mov eax, $$2
255// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
256
257}
258
259void t21() {
260  __asm {
261    __asm push ebx
262    __asm mov ebx, 07H
263    __asm pop ebx
264  }
265// CHECK: t21
266// CHECK: call void asm sideeffect inteldialect
267// CHECK-SAME: push ebx
268// CHECK-SAME: mov ebx, $$7
269// CHECK-SAME: pop ebx
270// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
271}
272
273extern void t22_helper(int x);
274void t22() {
275  int x = 0;
276  __asm {
277    __asm push ebx
278    __asm mov ebx, esp
279  }
280  t22_helper(x);
281  __asm {
282    __asm mov esp, ebx
283    __asm pop ebx
284  }
285// CHECK: t22
286// CHECK: call void asm sideeffect inteldialect
287// CHECK-SAME: push ebx
288// CHECK-SAME: mov ebx, esp
289// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
290// CHECK: call void @t22_helper
291// CHECK: call void asm sideeffect inteldialect
292// CHECK-SAME: mov esp, ebx
293// CHECK-SAME: pop ebx
294// CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
295}
296
297void t23() {
298  __asm {
299  the_label:
300  }
301// CHECK: t23
302// CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__the_label:", "~{dirflag},~{fpsr},~{flags}"()
303}
304
305void t24_helper(void) {}
306void t24() {
307  __asm call t24_helper
308// CHECK: t24
309// CHECK: call void asm sideeffect inteldialect "call dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper)
310}
311
312void t25() {
313// CHECK: t25
314  __asm mov eax, 0ffffffffh
315// CHECK: mov eax, $$4294967295
316  __asm mov eax, 0fhU
317// CHECK: mov eax, $$15
318  __asm mov eax, 0a2h
319// CHECK: mov eax, $$162
320  __asm mov eax, 10100010b
321// CHECK: mov eax, $$162
322  __asm mov eax, 10100010BU
323// CHECK: mov eax, $$162
324// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
325}
326
327void t26() {
328// CHECK: t26
329  __asm pushad
330// CHECK: pushad
331  __asm mov eax, 0
332// CHECK: mov eax, $$0
333  __asm __emit 0fh
334// CHECK: .byte 0fh
335  __asm __emit 0a2h
336// CHECK: .byte 0a2h
337  __asm __EMIT 0a2h
338// CHECK: .byte 0a2h
339  __asm popad
340// CHECK: popad
341// CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
342}
343
344void t27() {
345  __asm mov eax, fs:[0h]
346// CHECK: t27
347// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
348}
349
350void t28() {
351// CHECK: t28
352  __asm align 8
353// CHECK: .align 3
354  __asm align 16;
355// CHECK: .align 4
356  __asm align 128;
357// CHECK: .align 7
358  __asm ALIGN 256;
359// CHECK: .align 8
360// CHECK: "~{dirflag},~{fpsr},~{flags}"()
361}
362
363void t29() {
364// CHECK: t29
365  int arr[2] = {0, 0};
366  int olen = 0, osize = 0, otype = 0;
367  __asm mov olen, LENGTH arr
368// CHECK: mov dword ptr $0, $$2
369  __asm mov osize, SIZE arr
370// CHECK: mov dword ptr $1, $$8
371  __asm mov otype, TYPE arr
372// CHECK: mov dword ptr $2, $$4
373// CHECK: "=*m,=*m,=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
374}
375
376int results[2] = {13, 37};
377int *t30()
378// CHECK: t30
379{
380  int *res;
381  __asm lea edi, results
382// CHECK: lea edi, $2
383  __asm mov res, edi
384// CHECK: mov $0, edi
385  return res;
386// CHECK: "=*m,={eax},*m,~{edi},~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}, [2 x i32]* @{{.*}})
387}
388
389void t31() {
390// CHECK: t31
391  __asm pushad
392// CHECK: pushad
393  __asm popad
394// CHECK: popad
395// CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
396}
397
398void t32() {
399// CHECK: t32
400  int i;
401  __asm mov eax, i
402// CHECK: mov eax, $0
403  __asm mov eax, dword ptr i
404// CHECK: mov eax, dword ptr $1
405  __asm mov ax, word ptr i
406// CHECK: mov ax, word ptr $2
407  __asm mov al, byte ptr i
408// CHECK: mov al, byte ptr $3
409// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
410}
411
412void t33() {
413// CHECK: t33
414  int i;
415  __asm mov eax, [i]
416// CHECK: mov eax, $0
417  __asm mov eax, dword ptr [i]
418// CHECK: mov eax, dword ptr $1
419  __asm mov ax, word ptr [i]
420// CHECK: mov ax, word ptr $2
421  __asm mov al, byte ptr [i]
422// CHECK: mov al, byte ptr $3
423// CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}})
424}
425
426void t34() {
427// CHECK: t34
428  __asm prefetchnta 64[eax]
429// CHECK: prefetchnta [eax + $$64]
430  __asm mov eax, dword ptr 4[eax]
431// CHECK: mov eax, dword ptr [eax + $$4]
432// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
433}
434
435void t35() {
436// CHECK: t35
437  __asm prefetchnta [eax + (200*64)]
438// CHECK: prefetchnta [eax + $$12800]
439  __asm mov eax, dword ptr [eax + (200*64)]
440// CHECK: mov eax, dword ptr [eax + $$12800]
441// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
442}
443
444void t36() {
445// CHECK: t36
446  int arr[4];
447  // Work around PR20368: These should be single line blocks
448  __asm { mov eax, 4[arr] }
449// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
450  __asm { mov eax, 4[arr + 4] }
451// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
452  __asm { mov eax, 8[arr + 4 + 32*2 - 4] }
453// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
454  __asm { mov eax, 12[4 + arr] }
455// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
456  __asm { mov eax, 4[4 + arr + 4] }
457// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
458  __asm { mov eax, 4[64 + arr + (2*32)] }
459// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
460  __asm { mov eax, 4[64 + arr - 2*32] }
461// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
462  __asm { mov eax, [arr + 4] }
463// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
464  __asm { mov eax, [arr + 4 + 32*2 - 4] }
465// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
466  __asm { mov eax, [4 + arr] }
467// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
468  __asm { mov eax, [4 + arr + 4] }
469// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
470  __asm { mov eax, [64 + arr + (2*32)] }
471// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
472  __asm { mov eax, [64 + arr - 2*32] }
473// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
474}
475
476void t37() {
477// CHECK: t37
478  __asm mov eax, 4 + 8
479// CHECK: mov eax, $$12
480  __asm mov eax, 4 + 8 * 16
481// CHECK: mov eax, $$132
482  __asm mov eax, -4 + 8 * 16
483// CHECK: mov eax, $$124
484  __asm mov eax, (4 + 4) * 16
485// CHECK: mov eax, $$128
486  __asm mov eax, 4 + 8 * -16
487// CHECK: mov eax, $$-124
488  __asm mov eax, 4 + 16 / -8
489// CHECK: mov eax, $$2
490  __asm mov eax, (16 + 16) / -8
491// CHECK: mov eax, $$-4
492  __asm mov eax, ~15
493// CHECK: mov eax, $$-16
494  __asm mov eax, 6 ^ 3
495// CHECK: mov eax, $$5
496// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
497}
498
499void t38() {
500// CHECK: t38
501  int arr[4];
502  // Work around PR20368: These should be single line blocks
503  __asm { mov eax, 4+4[arr] }
504// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
505  __asm { mov eax, (4+4)[arr + 4] }
506// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
507  __asm { mov eax, 8*2[arr + 4 + 32*2 - 4] }
508// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$80]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
509  __asm { mov eax, 12+20[4 + arr] }
510// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$36]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
511  __asm { mov eax, 4*16+4[4 + arr + 4] }
512// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$76]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
513  __asm { mov eax, 4*4[64 + arr + (2*32)] }
514// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$144]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
515  __asm { mov eax, 4*(4-2)[64 + arr - 2*32] }
516// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
517  __asm { mov eax, 32*(4-2)[arr - 2*32] }
518// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
519}
520
521void cpuid() {
522  __asm cpuid
523// CHECK-LABEL: define void @cpuid
524// CHECK: call void asm sideeffect inteldialect "cpuid", "~{eax},~{ebx},~{ecx},~{edx},~{dirflag},~{fpsr},~{flags}"()
525}
526
527typedef struct {
528  int a;
529  int b;
530} A, *pA;
531
532typedef struct {
533  int b1;
534  A   b2;
535} B;
536
537typedef struct {
538  int c1;
539  A   c2;
540  int c3;
541  B   c4;
542} C, *pC;
543
544void t39() {
545// CHECK-LABEL: define void @t39
546  __asm mov eax, [eax].A.b
547// CHECK: mov eax, [eax + $$4]
548  __asm mov eax, [eax] A.b
549// CHECK: mov eax, [eax + $$4]
550  __asm mov eax, [eax] pA.b
551// CHECK: mov eax, [eax + $$4]
552  __asm mov eax, fs:[0] A.b
553// CHECK: mov eax, fs:[$$4]
554  __asm mov eax, [eax].B.b2.a
555// CHECK: mov eax, [eax + $$4]
556  __asm mov eax, [eax] B.b2.b
557// CHECK: mov eax, [eax + $$8]
558  __asm mov eax, fs:[0] C.c2.b
559// CHECK: mov eax, fs:[$$8]
560  __asm mov eax, [eax]C.c4.b2.b
561// CHECK: mov eax, [eax + $$24]
562  __asm mov eax, [eax]pC.c4.b2.b
563// CHECK: mov eax, [eax + $$24]
564// CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"()
565}
566
567void t40(float a) {
568// CHECK-LABEL: define void @t40
569  int i;
570  __asm fld a
571// CHECK: fld dword ptr $1
572  __asm fistp i
573// CHECK: fistp dword ptr $0
574// CHECK: "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, float* %{{.*}})
575}
576
577void t41(unsigned short a) {
578// CHECK-LABEL: define void @t41(i16 zeroext %a)
579  __asm mov cs, a;
580// CHECK: mov cs, $0
581  __asm mov ds, a;
582// CHECK: mov ds, $1
583  __asm mov es, a;
584// CHECK: mov es, $2
585  __asm mov fs, a;
586// CHECK: mov fs, $3
587  __asm mov gs, a;
588// CHECK: mov gs, $4
589  __asm mov ss, a;
590// CHECK: mov ss, $5
591// CHECK: "*m,*m,*m,*m,*m,*m,~{dirflag},~{fpsr},~{flags}"(i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}})
592}
593
594void t42() {
595// CHECK-LABEL: define void @t42
596  int flags;
597  __asm mov flags, eax
598// CHECK: mov $0, eax
599// CHECK: "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %flags)
600}
601
602void t43() {
603// CHECK-LABEL: define void @t43
604  C strct;
605// Work around PR20368: These should be single line blocks
606 __asm { mov eax, 4[strct.c1] }
607// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
608  __asm { mov eax, 4[strct.c3 + 4] }
609// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
610  __asm { mov eax, 8[strct.c2.a + 4 + 32*2 - 4] }
611// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
612  __asm { mov eax, 12[4 + strct.c2.b] }
613// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
614  __asm { mov eax, 4[4 + strct.c4.b2.b + 4] }
615// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
616  __asm { mov eax, 4[64 + strct.c1 + (2*32)] }
617// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
618  __asm { mov eax, 4[64 + strct.c2.a - 2*32] }
619// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
620  __asm { mov eax, [strct.c4.b1 + 4] }
621// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
622  __asm { mov eax, [strct.c4.b2.a + 4 + 32*2 - 4] }
623// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
624  __asm { mov eax, [4 + strct.c1] }
625// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
626  __asm { mov eax, [4 + strct.c2.b + 4] }
627// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
628  __asm { mov eax, [64 + strct.c3 + (2*32)] }
629// CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
630  __asm { mov eax, [64 + strct.c4.b2.b - 2*32] }
631// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
632}
633
634void t44() {
635  // CHECK-LABEL: define void @t44
636  __asm {
637    mov cr0, eax
638    mov cr2, ebx
639    mov cr3, ecx
640    mov cr4, edx
641  }
642  // CHECK: call void asm sideeffect inteldialect "mov cr0, eax\0A\09mov cr2, ebx\0A\09mov cr3, ecx\0A\09mov cr4, edx", "~{cr0},~{cr2},~{cr3},~{cr4},~{dirflag},~{fpsr},~{flags}"()
643}
644
645void t45() {
646  // CHECK-LABEL: define void @t45
647  __asm {
648    mov dr0, eax
649    mov dr1, ebx
650    mov dr2, ebx
651    mov dr3, ecx
652    mov dr6, edx
653    mov dr7, ecx
654  }
655  // CHECK: call void asm sideeffect inteldialect "mov dr0, eax\0A\09mov dr1, ebx\0A\09mov dr2, ebx\0A\09mov dr3, ecx\0A\09mov dr6, edx\0A\09mov dr7, ecx", "~{dr0},~{dr1},~{dr2},~{dr3},~{dr6},~{dr7},~{dirflag},~{fpsr},~{flags}"()
656}
657
658void t46() {
659  // CHECK-LABEL: define void @t46
660  __asm add eax, -128[eax]
661  // CHECK: call void asm sideeffect inteldialect "add eax, [eax + $$-128]", "~{eax},~{flags},~{dirflag},~{fpsr},~{flags}"()
662}
663
664void t47() {
665  // CHECK-LABEL: define void @t47
666  __asm {
667    bndmk bnd0, dword ptr [eax]
668    bndmk bnd1, dword ptr [ebx]
669    bndmk bnd2, dword ptr [ecx]
670    bndmk bnd3, dword ptr [edx]
671  }
672  // CHECK: call void asm sideeffect inteldialect "bndmk bnd0, dword ptr [eax]\0A\09bndmk bnd1, dword ptr [ebx]\0A\09bndmk bnd2, dword ptr [ecx]\0A\09bndmk bnd3, dword ptr [edx]", "~{bnd0},~{bnd1},~{bnd2},~{bnd3},~{dirflag},~{fpsr},~{flags}"()
673}
674
675void dot_operator(){
676  // CHECK-LABEL: define void @dot_operator
677 __asm { mov eax, 3[ebx]A.b}
678  // CHECK: call void asm sideeffect inteldialect "mov eax, [ebx + $$7]", "~{eax},~{dirflag},~{fpsr},~{flags}"
679}
680
681void call_clobber() {
682  __asm call t41
683  // CHECK-LABEL: define void @call_clobber
684  // CHECK: call void asm sideeffect inteldialect "call dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(void (i16)* @t41)
685}
686
687void xgetbv() {
688  __asm xgetbv
689}
690// CHECK-LABEL: define void @xgetbv()
691// CHECK: call void asm sideeffect inteldialect "xgetbv", "~{eax},~{edx},~{dirflag},~{fpsr},~{flags}"()
692
693void label1() {
694  __asm {
695    label:
696    jmp label
697  }
698  // CHECK-LABEL: define void @label1()
699  // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__label:\0A\09jmp {{.*}}__MSASMLABEL_.${:uid}__label", "~{dirflag},~{fpsr},~{flags}"() [[ATTR1:#[0-9]+]]
700}
701
702void label2() {
703  __asm {
704    jmp label
705    label:
706  }
707  // CHECK-LABEL: define void @label2
708  // CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:", "~{dirflag},~{fpsr},~{flags}"()
709}
710
711void label3() {
712  __asm {
713    label:
714    mov eax, label
715  }
716  // CHECK-LABEL: define void @label3
717  // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__label:\0A\09mov eax, {{.*}}__MSASMLABEL_.${:uid}__label", "~{eax},~{dirflag},~{fpsr},~{flags}"()
718}
719
720void label4() {
721  __asm {
722    label:
723    mov eax, [label]
724  }
725  // CHECK-LABEL: define void @label4
726  // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__label:\0A\09mov eax, {{.*}}__MSASMLABEL_.${:uid}__label", "~{eax},~{dirflag},~{fpsr},~{flags}"()
727}
728
729void label5() {
730  __asm {
731    jmp dollar_label$
732    dollar_label$:
733  }
734  // CHECK-LABEL: define void @label5
735  // CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.${:uid}__dollar_label$$\0A\09{{.*}}__MSASMLABEL_.${:uid}__dollar_label$$:", "~{dirflag},~{fpsr},~{flags}"()
736}
737
738void label6(){
739  __asm {
740      jmp short label
741      jc  short label
742      jz  short label
743    label:
744  }
745  // CHECK-LABEL: define void @label6
746  // CHECK: jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09jc {{.*}}__MSASMLABEL_.${:uid}__label\0A\09jz {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:"
747}
748
749// Don't include mxcsr in the clobber list.
750void mxcsr() {
751  char buf[4096];
752  __asm fxrstor buf
753}
754// CHECK-LABEL: define void @mxcsr
755// CHECK: call void asm sideeffect inteldialect "fxrstor $0", "=*m,~{dirflag},~{fpsr},~{flags}"
756
757// Make sure we can find the register for the dirflag for popfd
758void dirflag() {
759  __asm popfd
760}
761// CHECK-LABEL: define void @dirflag
762// CHECK: call void asm sideeffect inteldialect "popfd", "~{dirflag},~{flags},~{esp},~{dirflag},~{fpsr},~{flags}"
763
764typedef union _LARGE_INTEGER {
765  struct {
766    unsigned int LowPart;
767    unsigned int  HighPart;
768  };
769  struct {
770    unsigned int LowPart;
771    unsigned int  HighPart;
772  } u;
773  unsigned long long QuadPart;
774} LARGE_INTEGER, *PLARGE_INTEGER;
775
776int test_indirect_field(LARGE_INTEGER LargeInteger) {
777    __asm mov     eax, LargeInteger.LowPart
778}
779// CHECK-LABEL: define i32 @test_indirect_field(
780// CHECK: call i32 asm sideeffect inteldialect "mov eax, $1",
781
782// MS ASM containing labels must not be duplicated (PR23715).
783// CHECK: attributes [[ATTR1]] = {
784// CHECK-NOT: noduplicate
785// CHECK-SAME: }{{$}}
786