xref: /llvm-project/clang/test/CodeGen/ms-inline-asm.cpp (revision 94473f4db6a6f5f12d7c4081455b5b596094eac5)
1 // REQUIRES: x86-registered-target
2 // RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - -std=c++11 | FileCheck %s
3 
4 struct Foo {
5   static int *ptr;
6   static int a, b;
7   int arr[4];
8   struct Bar {
9     static int *ptr;
10     char arr[2];
11   };
12 };
13 
14 void t1() {
15 // CHECK-LABEL: define{{.*}} void @_Z2t1v()
16   Foo::ptr = (int *)0xDEADBEEF;
17   Foo::Bar::ptr = (int *)0xDEADBEEF;
18 // CHECK: call void asm sideeffect inteldialect
19 // CHECK-SAME: mov eax, $0
20 // CHECK-SAME: mov eax, $1
21 // CHECK-SAME: mov eax, $2
22 // CHECK-SAME: mov eax, dword ptr $3
23 // CHECK-SAME: mov eax, dword ptr $4
24 // CHECK-SAME: "*m,*m,*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(ptr) @_ZN3Foo3ptrE, ptr elementtype(ptr) @_ZN3Foo3Bar3ptrE, ptr elementtype(ptr) @_ZN3Foo3ptrE, ptr elementtype(ptr) @_ZN3Foo3ptrE, ptr elementtype(ptr) @_ZN3Foo3ptrE)
25   __asm mov eax, Foo ::ptr
26   __asm mov eax, Foo :: Bar :: ptr
27   __asm mov eax, [Foo:: ptr]
28   __asm mov eax, dword ptr [Foo :: ptr]
29   __asm mov eax, dword ptr [Foo :: ptr]
30 }
31 
32 int gvar = 10;
33 void t2() {
34   int lvar = 10;
35   __asm mov eax, offset Foo::ptr
36   __asm mov eax, offset Foo::Bar::ptr
37 // CHECK-LABEL: define{{.*}} void @_Z2t2v()
38 // CHECK: call void asm sideeffect inteldialect
39 // CHECK-SAME: mov eax, $0
40 // CHECK-SAME: mov eax, $1
41 // CHECK-SAME: "i,i,~{eax},~{dirflag},~{fpsr},~{flags}"(ptr @_ZN3Foo3ptrE, ptr @_ZN3Foo3Bar3ptrE)
42 }
43 
44 // CHECK-LABEL: define{{.*}} void @_Z2t3v()
45 void t3() {
46   __asm mov eax, LENGTH Foo::ptr
47   __asm mov eax, LENGTH Foo::Bar::ptr
48   __asm mov eax, LENGTH Foo::arr
49   __asm mov eax, LENGTH Foo::Bar::arr
50 
51   __asm mov eax, TYPE Foo::ptr
52   __asm mov eax, TYPE Foo::Bar::ptr
53   __asm mov eax, TYPE Foo::arr
54   __asm mov eax, TYPE Foo::Bar::arr
55 
56   __asm mov eax, SIZE Foo::ptr
57   __asm mov eax, SIZE Foo::Bar::ptr
58   __asm mov eax, SIZE Foo::arr
59   __asm mov eax, SIZE Foo::Bar::arr
60 // CHECK: call void asm sideeffect inteldialect
61 // CHECK-SAME: mov eax, $$1
62 // CHECK-SAME: mov eax, $$1
63 // CHECK-SAME: mov eax, $$4
64 // CHECK-SAME: mov eax, $$2
65 // CHECK-SAME: mov eax, $$4
66 // CHECK-SAME: mov eax, $$4
67 // CHECK-SAME: mov eax, $$4
68 // CHECK-SAME: mov eax, $$1
69 // CHECK-SAME: mov eax, $$4
70 // CHECK-SAME: mov eax, $$4
71 // CHECK-SAME: mov eax, $$16
72 // CHECK-SAME: mov eax, $$2
73 // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
74 
75 }
76 
77 struct T4 {
78   int x;
79   static int y;
80   void test();
81 };
82 
83 // CHECK-LABEL: define{{.*}} void @_ZN2T44testEv(
84 void T4::test() {
85 // CHECK: [[T0:%.*]] = alloca ptr,
86 // CHECK: [[THIS:%.*]] = load ptr, ptr [[T0]]
87 // CHECK: [[X:%.*]] = getelementptr inbounds nuw [[T4:%.*]], ptr [[THIS]], i32 0, i32 0
88   __asm mov eax, x;
89   __asm mov y, eax;
90 // CHECK: call void asm sideeffect inteldialect
91 // CHECK-SAME: mov eax, $1
92 // CHECK-SAME: mov $0, eax
93 // CHECK-SAME: "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) @_ZN2T41yE, ptr elementtype(i32) {{.*}})
94 }
95 
96 template <class T> struct T5 {
97   template <class U> static T create(U);
98   void run();
99 };
100 // CHECK-LABEL: define{{.*}} void @_Z5test5v()
101 void test5() {
102   // CHECK: [[X:%.*]] = alloca i32
103   // CHECK: [[Y:%.*]] = alloca i32
104   int x, y;
105   __asm push y
106   __asm call T5<int>::create<float>
107   __asm mov x, eax
108   // CHECK: call void asm sideeffect inteldialect
109   // CHECK-SAME: push $0
110   // CHECK-SAME: call ${2:P}
111   // CHECK-SAME: mov $1, eax
112   // CHECK-SAME: "=*m,=*m,*m,~{esp},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) %y, ptr elementtype(i32) %x, ptr elementtype(i32 (float)) @_ZN2T5IiE6createIfEEiT_)
113 }
114 
115 // Just verify this doesn't emit an error.
116 void test6() {
117   __asm {
118    a:
119    jmp a
120   }
121 }
122 
123 void t7_struct() {
124   struct A {
125     int a;
126     int b;
127   };
128   __asm mov eax, [eax].A.b
129   // CHECK-LABEL: define{{.*}} void @_Z9t7_structv
130   // CHECK: call void asm sideeffect inteldialect
131   // CHECK-SAME: mov eax, [eax + $$4]
132   // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
133 }
134 
135 void t7_typedef() {
136   typedef struct {
137     int a;
138     int b;
139   } A;
140   __asm mov eax, [eax].A.b
141   // CHECK-LABEL: define{{.*}} void @_Z10t7_typedefv
142   // CHECK: call void asm sideeffect inteldialect
143   // CHECK-SAME: mov eax, [eax + $$4]
144   // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
145 }
146 
147 void t7_using() {
148   using A = struct {
149     int a;
150     int b;
151   };
152   __asm mov eax, [eax].A.b
153   // CHECK-LABEL: define{{.*}} void @_Z8t7_usingv
154   // CHECK: call void asm sideeffect inteldialect
155   // CHECK-SAME: mov eax, [eax + $$4]
156   // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
157 }
158 
159 void t8() {
160   __asm some_label:
161   // CHECK-LABEL: define{{.*}} void @_Z2t8v()
162   // CHECK: call void asm sideeffect inteldialect
163   // CHECK-SAME: L__MSASMLABEL_.${:uid}__some_label:
164   // CHECK-SAME: "~{dirflag},~{fpsr},~{flags}"()
165   struct A {
166     static void g() {
167       __asm jmp some_label ; This should jump forwards
168       __asm some_label:
169       __asm nop
170       // CHECK-LABEL: define internal void @_ZZ2t8vEN1A1gEv()
171       // CHECK: call void asm sideeffect inteldialect
172       // CHECK-SAME: jmp L__MSASMLABEL_.${:uid}__some_label
173       // CHECK-SAME: L__MSASMLABEL_.${:uid}__some_label:
174       // CHECK-SAME: nop
175       // CHECK-SAME: "~{dirflag},~{fpsr},~{flags}"()
176     }
177   };
178   A::g();
179 }
180 
181 void t9() {
182   // CHECK-LABEL: define{{.*}} void @_Z2t9v()
183   struct A {
184     int a;
185     int b;
186     void g() {
187       __asm mov eax, dword ptr [eax]this.b
188       // CHECK: call void asm sideeffect inteldialect
189       // CHECK-SAME: mov eax, dword ptr [eax + $$4]
190       // CHECK-SAME: "~{eax},~{dirflag},~{fpsr},~{flags}"()
191     }
192   };
193   A AA;
194   AA.g();
195 }
196 
197