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
11void t1(int len) {
12  __asm__ volatile("" : "=&r"(len), "+&r"(len));
13}
14
15void t2(unsigned long long t)  {
16  __asm__ volatile("" : "+m"(t));
17}
18
19void t3(unsigned char *src, unsigned long long temp) {
20  __asm__ volatile("" : "+m"(temp), "+r"(src));
21}
22
23void 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
31void t5(int i) {
32  asm("nop" : "=r"(i) : "0"(t5));
33}
34
35// PR3641
36void t6(void) {
37  __asm__ volatile("" : : "i" (t6));
38}
39
40void 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
46void 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
53unsigned t9(unsigned int a) {
54  asm("bswap %0 %1" : "+r" (a));
55  return a;
56}
57
58// PR3908
59void 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
67unsigned t11(signed char input) {
68  unsigned  output;
69  __asm__("xyz"
70          : "=a" (output)
71          : "0" (input));
72  return output;
73}
74
75// PR3373
76unsigned char t12(unsigned input) {
77  unsigned char output;
78  __asm__("xyz"
79          : "=a" (output)
80          : "0" (input));
81  return output;
82}
83
84unsigned char t13(unsigned input) {
85  unsigned char output;
86  __asm__("xyz %1"
87          : "=a" (output)
88          : "0" (input));
89  return output;
90}
91
92struct large {
93  int x[1000];
94};
95
96unsigned 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.
104struct S {
105  int a : 4;
106};
107
108void t14(struct S *P) {
109  __asm__("abc %0" : "=r"(P->a) );
110}
111
112// PR4938
113int t16() {
114  int a,b;
115  asm ( "nop;"
116       :"=%c" (a)
117       : "r" (b)
118       );
119  return 0;
120}
121
122// PR6475
123void 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>
132int 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
144int 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.
154double 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
165float 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
175unsigned 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
187unsigned 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
196void *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
206void 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
219typedef long long __m256i __attribute__((__vector_size__(32)));
220void 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.
226void 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.
235void 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