1 | // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s |
2 | |
3 | // PR10415 |
4 | __asm__ ("foo1"); |
5 | __asm__ ("foo2"); |
6 | __asm__ ("foo3"); |
7 | // CHECK: module asm "foo1" |
8 | // CHECK-NEXT: module asm "foo2" |
9 | // CHECK-NEXT: module asm "foo3" |
10 | |
11 | void t1(int len) { |
12 | __asm__ volatile("" : "=&r"(len), "+&r"(len)); |
13 | } |
14 | |
15 | void t2(unsigned long long t) { |
16 | __asm__ volatile("" : "+m"(t)); |
17 | } |
18 | |
19 | void t3(unsigned char *src, unsigned long long temp) { |
20 | __asm__ volatile("" : "+m"(temp), "+r"(src)); |
21 | } |
22 | |
23 | void t4() { |
24 | unsigned long long a; |
25 | struct reg { unsigned long long a, b; } b; |
26 | |
27 | __asm__ volatile ("":: "m"(a), "m"(b)); |
28 | } |
29 | |
30 | // PR3417 |
31 | void t5(int i) { |
32 | asm("nop" : "=r"(i) : "0"(t5)); |
33 | } |
34 | |
35 | // PR3641 |
36 | void t6(void) { |
37 | __asm__ volatile("" : : "i" (t6)); |
38 | } |
39 | |
40 | void t7(int a) { |
41 | __asm__ volatile("T7 NAMED: %[input]" : "+r"(a): [input] "i" (4)); |
42 | // CHECK: @t7(i32 |
43 | // CHECK: T7 NAMED: $1 |
44 | } |
45 | |
46 | void t8() { |
47 | __asm__ volatile("T8 NAMED MODIFIER: %c[input]" :: [input] "i" (4)); |
48 | // CHECK: @t8() |
49 | // CHECK: T8 NAMED MODIFIER: ${0:c} |
50 | } |
51 | |
52 | // PR3682 |
53 | unsigned t9(unsigned int a) { |
54 | asm("bswap %0 %1" : "+r" (a)); |
55 | return a; |
56 | } |
57 | |
58 | // PR3908 |
59 | void t10(int r) { |
60 | __asm__("PR3908 %[lf] %[xx] %[li] %[r]" : [r] "+r" (r) : [lf] "mx" (0), [li] "mr" (0), [xx] "x" ((double)(0))); |
61 | |
62 | // CHECK: @t10( |
63 | // CHECK:PR3908 $1 $3 $2 $0 |
64 | } |
65 | |
66 | // PR3373 |
67 | unsigned t11(signed char input) { |
68 | unsigned output; |
69 | __asm__("xyz" |
70 | : "=a" (output) |
71 | : "0" (input)); |
72 | return output; |
73 | } |
74 | |
75 | // PR3373 |
76 | unsigned char t12(unsigned input) { |
77 | unsigned char output; |
78 | __asm__("xyz" |
79 | : "=a" (output) |
80 | : "0" (input)); |
81 | return output; |
82 | } |
83 | |
84 | unsigned char t13(unsigned input) { |
85 | unsigned char output; |
86 | __asm__("xyz %1" |
87 | : "=a" (output) |
88 | : "0" (input)); |
89 | return output; |
90 | } |
91 | |
92 | struct large { |
93 | int x[1000]; |
94 | }; |
95 | |
96 | unsigned long t15(int x, struct large *P) { |
97 | __asm__("xyz " |
98 | : "=r" (x) |
99 | : "m" (*P), "0" (x)); |
100 | return x; |
101 | } |
102 | |
103 | // bitfield destination of an asm. |
104 | struct S { |
105 | int a : 4; |
106 | }; |
107 | |
108 | void t14(struct S *P) { |
109 | __asm__("abc %0" : "=r"(P->a) ); |
110 | } |
111 | |
112 | // PR4938 |
113 | int t16() { |
114 | int a,b; |
115 | asm ( "nop;" |
116 | :"=%c" (a) |
117 | : "r" (b) |
118 | ); |
119 | return 0; |
120 | } |
121 | |
122 | // PR6475 |
123 | void t17() { |
124 | int i; |
125 | __asm__ ( "nop": "=m"(i)); |
126 | |
127 | // CHECK: @t17() |
128 | // CHECK: call void asm "nop", "=*m, |
129 | } |
130 | |
131 | // <rdar://problem/6841383> |
132 | int t18(unsigned data) { |
133 | int a, b; |
134 | |
135 | asm("xyz" :"=a"(a), "=d"(b) : "a"(data)); |
136 | return a + b; |
137 | // CHECK: t18(i32 |
138 | // CHECK: = call {{.*}}asm "xyz" |
139 | // CHECK-NEXT: extractvalue |
140 | // CHECK-NEXT: extractvalue |
141 | } |
142 | |
143 | // PR6780 |
144 | int t19(unsigned data) { |
145 | int a, b; |
146 | |
147 | asm("x{abc|def|ghi}z" :"=r"(a): "r"(data)); |
148 | return a + b; |
149 | // CHECK: t19(i32 |
150 | // CHECK: = call {{.*}}asm "x$(abc$|def$|ghi$)z" |
151 | } |
152 | |
153 | // PR6845 - Mismatching source/dest fp types. |
154 | double t20(double x) { |
155 | register long double result; |
156 | __asm __volatile ("frndint" : "=t" (result) : "0" (x)); |
157 | return result; |
158 | |
159 | // CHECK: @t20 |
160 | // CHECK: fpext double {{.*}} to x86_fp80 |
161 | // CHECK-NEXT: call x86_fp80 asm sideeffect "frndint" |
162 | // CHECK: fptrunc x86_fp80 {{.*}} to double |
163 | } |
164 | |
165 | float t21(long double x) { |
166 | register float result; |
167 | __asm __volatile ("frndint" : "=t" (result) : "0" (x)); |
168 | return result; |
169 | // CHECK: @t21 |
170 | // CHECK: call x86_fp80 asm sideeffect "frndint" |
171 | // CHECK-NEXT: fptrunc x86_fp80 {{.*}} to float |
172 | } |
173 | |
174 | // <rdar://problem/8348447> - accept 'l' constraint |
175 | unsigned char t22(unsigned char a, unsigned char b) { |
176 | unsigned int la = a; |
177 | unsigned int lb = b; |
178 | unsigned int bigres; |
179 | unsigned char res; |
180 | __asm__ ("0:\n1:\n" : [bigres] "=la"(bigres) : [la] "0"(la), [lb] "c"(lb) : |
181 | "edx", "cc"); |
182 | res = bigres; |
183 | return res; |
184 | } |
185 | |
186 | // <rdar://problem/8348447> - accept 'l' constraint |
187 | unsigned char t23(unsigned char a, unsigned char b) { |
188 | unsigned int la = a; |
189 | unsigned int lb = b; |
190 | unsigned char res; |
191 | __asm__ ("0:\n1:\n" : [res] "=la"(res) : [la] "0"(la), [lb] "c"(lb) : |
192 | "edx", "cc"); |
193 | return res; |
194 | } |
195 | |
196 | void *t24(char c) { |
197 | void *addr; |
198 | // CHECK: @t24 |
199 | // CHECK: zext i8 {{.*}} to i32 |
200 | // CHECK-NEXT: call i8* asm "foobar" |
201 | __asm__ ("foobar" : "=a" (addr) : "0" (c)); |
202 | return addr; |
203 | } |
204 | |
205 | // PR10299 - fpsr, fpcr |
206 | void t25(void) |
207 | { |
208 | __asm__ __volatile__( \ |
209 | "finit" \ |
210 | : \ |
211 | : \ |
212 | :"st","st(1)","st(2)","st(3)", \ |
213 | "st(4)","st(5)","st(6)","st(7)", \ |
214 | "fpsr","fpcr" \ |
215 | ); |
216 | } |
217 | |
218 | // rdar://10510405 - AVX registers |
219 | typedef long long __m256i __attribute__((__vector_size__(32))); |
220 | void t26 (__m256i *p) { |
221 | __asm__ volatile("vmovaps %0, %%ymm0" :: "m" (*(__m256i*)p) : "ymm0"); |
222 | } |
223 | |
224 | // Check to make sure the inline asm non-standard dialect attribute _not_ is |
225 | // emitted. |
226 | void t27(void) { |
227 | asm volatile("nop"); |
228 | // CHECK: @t27 |
229 | // CHECK: call void asm sideeffect "nop" |
230 | // CHECK-NOT: ia_nsdialect |
231 | // CHECK: ret void |
232 | } |
233 | |
234 | // Check handling of '*' and '#' constraint modifiers. |
235 | void t28(void) |
236 | { |
237 | asm volatile ("/* %0 */" : : "i#*X,*r" (1)); |
238 | // CHECK: @t28 |
239 | // CHECK: call void asm sideeffect "/* $0 */", "i|r,~{dirflag},~{fpsr},~{flags}"(i32 1) |
240 | } |
241 | |
242 | static unsigned t29_var[1]; |
243 | |
244 | void t29(void) { |
245 | asm volatile("movl %%eax, %0" |
246 | : |
247 | : "m"(t29_var)); |
248 | // CHECK: @t29 |
249 | // CHECK: call void asm sideeffect "movl %eax, $0", "*m,~{dirflag},~{fpsr},~{flags}"([1 x i32]* @t29_var) |
250 | } |
251 | |
252 | void t30(int len) { |
253 | __asm__ volatile("" |
254 | : "+&&rm"(len)); |
255 | // CHECK: @t30 |
256 | // CHECK: call void asm sideeffect "", "=*&rm,0,~{dirflag},~{fpsr},~{flags}" |
257 | } |
258 | |
259 | void t31(int len) { |
260 | __asm__ volatile("" |
261 | : "+%%rm"(len), "+rm"(len)); |
262 | // CHECK: @t31 |
263 | // CHECK: call void asm sideeffect "", "=*%rm,=*rm,0,1,~{dirflag},~{fpsr},~{flags}" |
264 | } |
265 | |