xref: /aosp_15_r20/external/clang/test/CodeGen/ms-inline-asm.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // REQUIRES: x86-registered-target
2*67e74705SXin Li // RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - -std=c++11 | FileCheck %s
3*67e74705SXin Li 
4*67e74705SXin Li // rdar://13645930
5*67e74705SXin Li 
6*67e74705SXin Li struct Foo {
7*67e74705SXin Li   static int *ptr;
8*67e74705SXin Li   static int a, b;
9*67e74705SXin Li   int arr[4];
10*67e74705SXin Li   struct Bar {
11*67e74705SXin Li     static int *ptr;
12*67e74705SXin Li     char arr[2];
13*67e74705SXin Li   };
14*67e74705SXin Li };
15*67e74705SXin Li 
t1()16*67e74705SXin Li void t1() {
17*67e74705SXin Li   Foo::ptr = (int *)0xDEADBEEF;
18*67e74705SXin Li   Foo::Bar::ptr = (int *)0xDEADBEEF;
19*67e74705SXin Li   __asm mov eax, Foo ::ptr
20*67e74705SXin Li   __asm mov eax, Foo :: Bar :: ptr
21*67e74705SXin Li   __asm mov eax, [Foo:: ptr]
22*67e74705SXin Li   __asm mov eax, dword ptr [Foo :: ptr]
23*67e74705SXin Li   __asm mov eax, dword ptr [Foo :: ptr]
24*67e74705SXin Li // CHECK: @_Z2t1v
25*67e74705SXin Li // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0\0A\09mov eax, dword ptr $1\0A\09mov eax, dword ptr $2\0A\09mov eax, dword ptr $3\0A\09mov eax, dword ptr $4", "*m,*m,*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3ptrE)
26*67e74705SXin Li }
27*67e74705SXin Li 
28*67e74705SXin Li int gvar = 10;
t2()29*67e74705SXin Li void t2() {
30*67e74705SXin Li   int lvar = 10;
31*67e74705SXin Li   __asm mov eax, offset Foo::ptr
32*67e74705SXin Li   __asm mov eax, offset Foo::Bar::ptr
33*67e74705SXin Li // CHECK: t2
34*67e74705SXin Li // CHECK: call void asm sideeffect inteldialect "mov eax, $0\0A\09mov eax, $1", "r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE)
35*67e74705SXin Li }
36*67e74705SXin Li 
37*67e74705SXin Li // CHECK-LABEL: define void @_Z2t3v()
t3()38*67e74705SXin Li void t3() {
39*67e74705SXin Li   __asm mov eax, LENGTH Foo::ptr
40*67e74705SXin Li   __asm mov eax, LENGTH Foo::Bar::ptr
41*67e74705SXin Li   __asm mov eax, LENGTH Foo::arr
42*67e74705SXin Li   __asm mov eax, LENGTH Foo::Bar::arr
43*67e74705SXin Li 
44*67e74705SXin Li   __asm mov eax, TYPE Foo::ptr
45*67e74705SXin Li   __asm mov eax, TYPE Foo::Bar::ptr
46*67e74705SXin Li   __asm mov eax, TYPE Foo::arr
47*67e74705SXin Li   __asm mov eax, TYPE Foo::Bar::arr
48*67e74705SXin Li 
49*67e74705SXin Li   __asm mov eax, SIZE Foo::ptr
50*67e74705SXin Li   __asm mov eax, SIZE Foo::Bar::ptr
51*67e74705SXin Li   __asm mov eax, SIZE Foo::arr
52*67e74705SXin Li   __asm mov eax, SIZE Foo::Bar::arr
53*67e74705SXin Li // CHECK: call void asm sideeffect inteldialect "mov eax, $$1\0A\09mov eax, $$1\0A\09mov eax, $$4\0A\09mov eax, $$2\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$1\0A\09mov eax, $$4\0A\09mov eax, $$4\0A\09mov eax, $$16\0A\09mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
54*67e74705SXin Li 
55*67e74705SXin Li }
56*67e74705SXin Li 
57*67e74705SXin Li struct T4 {
58*67e74705SXin Li   int x;
59*67e74705SXin Li   static int y;
60*67e74705SXin Li   void test();
61*67e74705SXin Li };
62*67e74705SXin Li 
63*67e74705SXin Li // CHECK-LABEL: define void @_ZN2T44testEv(
test()64*67e74705SXin Li void T4::test() {
65*67e74705SXin Li // CHECK: [[T0:%.*]] = alloca [[T4:%.*]]*,
66*67e74705SXin Li // CHECK: [[THIS:%.*]] = load [[T4]]*, [[T4]]** [[T0]]
67*67e74705SXin Li // CHECK: [[X:%.*]] = getelementptr inbounds [[T4]], [[T4]]* [[THIS]], i32 0, i32 0
68*67e74705SXin Li   __asm mov eax, x;
69*67e74705SXin Li   __asm mov y, eax;
70*67e74705SXin Li // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $1\0A\09mov dword ptr $0, eax", "=*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE, i32* {{.*}})
71*67e74705SXin Li }
72*67e74705SXin Li 
73*67e74705SXin Li template <class T> struct T5 {
74*67e74705SXin Li   template <class U> static T create(U);
75*67e74705SXin Li   void run();
76*67e74705SXin Li };
77*67e74705SXin Li // CHECK-LABEL: define void @_Z5test5v()
test5()78*67e74705SXin Li void test5() {
79*67e74705SXin Li   // CHECK: [[X:%.*]] = alloca i32
80*67e74705SXin Li   // CHECK: [[Y:%.*]] = alloca i32
81*67e74705SXin Li   int x, y;
82*67e74705SXin Li   __asm push y
83*67e74705SXin Li   __asm call T5<int>::create<float>
84*67e74705SXin Li   __asm mov x, eax
85*67e74705SXin Li   // CHECK: call void asm sideeffect inteldialect "push dword ptr $0\0A\09call dword ptr $2\0A\09mov dword ptr $1, eax", "=*m,=*m,*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %y, i32* %x, i32 (float)* @_ZN2T5IiE6createIfEEiT_)
86*67e74705SXin Li }
87*67e74705SXin Li 
88*67e74705SXin Li // Just verify this doesn't emit an error.
test6()89*67e74705SXin Li void test6() {
90*67e74705SXin Li   __asm {
91*67e74705SXin Li    a:
92*67e74705SXin Li    jmp a
93*67e74705SXin Li   }
94*67e74705SXin Li }
95*67e74705SXin Li 
t7_struct()96*67e74705SXin Li void t7_struct() {
97*67e74705SXin Li   struct A {
98*67e74705SXin Li     int a;
99*67e74705SXin Li     int b;
100*67e74705SXin Li   };
101*67e74705SXin Li   __asm mov eax, [eax].A.b
102*67e74705SXin Li   // CHECK-LABEL: define void @_Z9t7_structv
103*67e74705SXin Li   // CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
104*67e74705SXin Li }
105*67e74705SXin Li 
t7_typedef()106*67e74705SXin Li void t7_typedef() {
107*67e74705SXin Li   typedef struct {
108*67e74705SXin Li     int a;
109*67e74705SXin Li     int b;
110*67e74705SXin Li   } A;
111*67e74705SXin Li   __asm mov eax, [eax].A.b
112*67e74705SXin Li   // CHECK-LABEL: define void @_Z10t7_typedefv
113*67e74705SXin Li   // CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
114*67e74705SXin Li }
115*67e74705SXin Li 
t7_using()116*67e74705SXin Li void t7_using() {
117*67e74705SXin Li   using A = struct {
118*67e74705SXin Li     int a;
119*67e74705SXin Li     int b;
120*67e74705SXin Li   };
121*67e74705SXin Li   __asm mov eax, [eax].A.b
122*67e74705SXin Li   // CHECK-LABEL: define void @_Z8t7_usingv
123*67e74705SXin Li   // CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
124*67e74705SXin Li }
125*67e74705SXin Li 
t8()126*67e74705SXin Li void t8() {
127*67e74705SXin Li   __asm some_label:
128*67e74705SXin Li   // CHECK-LABEL: define void @_Z2t8v()
129*67e74705SXin Li   // CHECK: call void asm sideeffect inteldialect "L__MSASMLABEL_.1__some_label:", "~{dirflag},~{fpsr},~{flags}"()
130*67e74705SXin Li   struct A {
131*67e74705SXin Li     static void g() {
132*67e74705SXin Li       __asm jmp some_label ; This should jump forwards
133*67e74705SXin Li       __asm some_label:
134*67e74705SXin Li       __asm nop
135*67e74705SXin Li       // CHECK-LABEL: define internal void @_ZZ2t8vEN1A1gEv()
136*67e74705SXin Li       // CHECK: call void asm sideeffect inteldialect "jmp L__MSASMLABEL_.2__some_label\0A\09L__MSASMLABEL_.2__some_label:\0A\09nop", "~{dirflag},~{fpsr},~{flags}"()
137*67e74705SXin Li     }
138*67e74705SXin Li   };
139*67e74705SXin Li   A::g();
140*67e74705SXin Li }
141*67e74705SXin Li 
142