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