1 // RUN: %clang_cc1 -Wall -Werror -triple thumbv7-eabi -target-cpu cortex-a8 -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
2 
3 #include <stdint.h>
4 
5 void *f0()
6 {
7   return __builtin_thread_pointer();
8 }
9 
10 void f1(char *a, char *b) {
11   // CHECK: call {{.*}} @__clear_cache
12 	__clear_cache(a,b);
13 }
14 
15 float test_vcvtrf0(float f) {
16   // CHECK: call float @llvm.arm.vcvtr.f32(float %f)
17   return __builtin_arm_vcvtr_f(f, 0);
18 }
19 
20 float test_vcvtrf1(float f) {
21   // CHECK: call float @llvm.arm.vcvtru.f32(float %f)
22   return __builtin_arm_vcvtr_f(f, 1);
23 }
24 
25 double test_vcvtrd0(double d) {
26   // CHECK: call float @llvm.arm.vcvtr.f64(double %d)
27   return __builtin_arm_vcvtr_d(d, 0);
28 }
29 
30 double test_vcvtrd1(double d) {
31   // call float @llvm.arm.vcvtru.f64(double %d)
32   return __builtin_arm_vcvtr_d(d, 1);
33 }
34 
35 void test_eh_return_data_regno()
36 {
37   // CHECK: store volatile i32 0
38   // CHECK: store volatile i32 1
39   volatile int res;
40   res = __builtin_eh_return_data_regno(0);
41   res = __builtin_eh_return_data_regno(1);
42 }
43 
44 void nop() {
45   // CHECK: call {{.*}} @llvm.arm.hint(i32 0)
46   __builtin_arm_nop();
47 }
48 
49 void yield() {
50   // CHECK: call {{.*}} @llvm.arm.hint(i32 1)
51   __builtin_arm_yield();
52 }
53 
54 void wfe() {
55   // CHECK: call {{.*}} @llvm.arm.hint(i32 2)
56   __builtin_arm_wfe();
57 }
58 
59 void wfi() {
60   // CHECK: call {{.*}} @llvm.arm.hint(i32 3)
61   __builtin_arm_wfi();
62 }
63 
64 void sev() {
65   // CHECK: call {{.*}} @llvm.arm.hint(i32 4)
66   __builtin_arm_sev();
67 }
68 
69 void sevl() {
70   // CHECK: call {{.*}} @llvm.arm.hint(i32 5)
71   __builtin_arm_sevl();
72 }
73 
74 void dbg() {
75   // CHECK: call {{.*}} @llvm.arm.dbg(i32 0)
76   __builtin_arm_dbg(0);
77 }
78 
79 void test_barrier() {
80   //CHECK: call {{.*}} @llvm.arm.dmb(i32 1)
81   //CHECK: call {{.*}} @llvm.arm.dsb(i32 2)
82   //CHECK: call {{.*}} @llvm.arm.isb(i32 3)
83   __builtin_arm_dmb(1);
84   __builtin_arm_dsb(2);
85   __builtin_arm_isb(3);
86 }
87 
88 unsigned rbit(unsigned a) {
89   // CHECK: call {{.*}} @llvm.bitreverse.i32(i32 %a)
90   return __builtin_arm_rbit(a);
91 }
92 
93 void prefetch(int i) {
94   __builtin_arm_prefetch(&i, 0, 1);
95 // CHECK: call {{.*}} @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 1)
96 
97   __builtin_arm_prefetch(&i, 1, 1);
98 // CHECK: call {{.*}} @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 1)
99 
100 
101   __builtin_arm_prefetch(&i, 1, 0);
102 // CHECK: call {{.*}} @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 0)
103 }
104 
105 void ldc(const void *i) {
106   // CHECK: define void @ldc(i8* %i)
107   // CHECK: call void @llvm.arm.ldc(i32 1, i32 2, i8* %i)
108   // CHECK-NEXT: ret void
109   __builtin_arm_ldc(1, 2, i);
110 }
111 
112 void ldcl(const void *i) {
113   // CHECK: define void @ldcl(i8* %i)
114   // CHECK: call void @llvm.arm.ldcl(i32 1, i32 2, i8* %i)
115   // CHECK-NEXT: ret void
116   __builtin_arm_ldcl(1, 2, i);
117 }
118 
119 void ldc2(const void *i) {
120   // CHECK: define void @ldc2(i8* %i)
121   // CHECK: call void @llvm.arm.ldc2(i32 1, i32 2, i8* %i)
122   // CHECK-NEXT: ret void
123   __builtin_arm_ldc2(1, 2, i);
124 }
125 
126 void ldc2l(const void *i) {
127   // CHECK: define void @ldc2l(i8* %i)
128   // CHECK: call void @llvm.arm.ldc2l(i32 1, i32 2, i8* %i)
129   // CHECK-NEXT: ret void
130   __builtin_arm_ldc2l(1, 2, i);
131 }
132 
133 void stc(void *i) {
134   // CHECK: define void @stc(i8* %i)
135   // CHECK: call void @llvm.arm.stc(i32 1, i32 2, i8* %i)
136   // CHECK-NEXT: ret void
137   __builtin_arm_stc(1, 2, i);
138 }
139 
140 void stcl(void *i) {
141   // CHECK: define void @stcl(i8* %i)
142   // CHECK: call void @llvm.arm.stcl(i32 1, i32 2, i8* %i)
143   // CHECK-NEXT: ret void
144   __builtin_arm_stcl(1, 2, i);
145 }
146 
147 void stc2(void *i) {
148   // CHECK: define void @stc2(i8* %i)
149   // CHECK: call void @llvm.arm.stc2(i32 1, i32 2, i8* %i)
150   // CHECK-NEXT: ret void
151   __builtin_arm_stc2(1, 2, i);
152 }
153 
154 void stc2l(void *i) {
155   // CHECK: define void @stc2l(i8* %i)
156   // CHECK: call void @llvm.arm.stc2l(i32 1, i32 2, i8* %i)
157   // CHECK-NEXT: ret void
158   __builtin_arm_stc2l(1, 2, i);
159 }
160 
161 void cdp() {
162   // CHECK: define void @cdp()
163   // CHECK: call void @llvm.arm.cdp(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6)
164   // CHECK-NEXT: ret void
165   __builtin_arm_cdp(1, 2, 3, 4, 5, 6);
166 }
167 
168 void cdp2() {
169   // CHECK: define void @cdp2()
170   // CHECK: call void @llvm.arm.cdp2(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6)
171   // CHECK-NEXT: ret void
172   __builtin_arm_cdp2(1, 2, 3, 4, 5, 6);
173 }
174 
175 unsigned mrc() {
176   // CHECK: define i32 @mrc()
177   // CHECK: [[R:%.*]] = call i32 @llvm.arm.mrc(i32 15, i32 0, i32 13, i32 0, i32 3)
178   // CHECK-NEXT: ret i32 [[R]]
179   return __builtin_arm_mrc(15, 0, 13, 0, 3);
180 }
181 
182 unsigned mrc2() {
183   // CHECK: define i32 @mrc2()
184   // CHECK: [[R:%.*]] = call i32 @llvm.arm.mrc2(i32 15, i32 0, i32 13, i32 0, i32 3)
185   // CHECK-NEXT: ret i32 [[R]]
186   return __builtin_arm_mrc2(15, 0, 13, 0, 3);
187 }
188 
189 void mcr(unsigned a) {
190   // CHECK: define void @mcr(i32 [[A:%.*]])
191   // CHECK: call void @llvm.arm.mcr(i32 15, i32 0, i32 [[A]], i32 13, i32 0, i32 3)
192   __builtin_arm_mcr(15, 0, a, 13, 0, 3);
193 }
194 
195 void mcr2(unsigned a) {
196   // CHECK: define void @mcr2(i32 [[A:%.*]])
197   // CHECK: call void @llvm.arm.mcr2(i32 15, i32 0, i32 [[A]], i32 13, i32 0, i32 3)
198   __builtin_arm_mcr2(15, 0, a, 13, 0, 3);
199 }
200 
201 void mcrr(uint64_t a) {
202   // CHECK: define void @mcrr(i64 %{{.*}})
203   // CHECK: call void @llvm.arm.mcrr(i32 15, i32 0, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 0)
204   __builtin_arm_mcrr(15, 0, a, 0);
205 }
206 
207 void mcrr2(uint64_t a) {
208   // CHECK: define void @mcrr2(i64 %{{.*}})
209   // CHECK: call void @llvm.arm.mcrr2(i32 15, i32 0, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 0)
210   __builtin_arm_mcrr2(15, 0, a, 0);
211 }
212 
213 uint64_t mrrc() {
214   // CHECK: define i64 @mrrc()
215   // CHECK: call { i32, i32 } @llvm.arm.mrrc(i32 15, i32 0, i32 0)
216   return __builtin_arm_mrrc(15, 0, 0);
217 }
218 
219 uint64_t mrrc2() {
220   // CHECK: define i64 @mrrc2()
221   // CHECK: call { i32, i32 } @llvm.arm.mrrc2(i32 15, i32 0, i32 0)
222   return __builtin_arm_mrrc2(15, 0, 0);
223 }
224 
225 unsigned rsr() {
226   // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i32 @llvm.read_register.i32(metadata ![[M0:.*]])
227   // CHECK-NEXT: ret i32 [[V0]]
228   return __builtin_arm_rsr("cp1:2:c3:c4:5");
229 }
230 
231 unsigned long long rsr64() {
232   // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i64 @llvm.read_register.i64(metadata ![[M1:.*]])
233   // CHECK-NEXT: ret i64 [[V0]]
234   return __builtin_arm_rsr64("cp1:2:c3");
235 }
236 
237 void *rsrp() {
238   // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i32 @llvm.read_register.i32(metadata ![[M2:.*]])
239   // CHECK-NEXT: [[V1:[%A-Za-z0-9.]+]] = inttoptr i32 [[V0]] to i8*
240   // CHECK-NEXT: ret i8* [[V1]]
241   return __builtin_arm_rsrp("sysreg");
242 }
243 
244 void wsr(unsigned v) {
245   // CHECK: call void @llvm.write_register.i32(metadata ![[M0]], i32 %v)
246   __builtin_arm_wsr("cp1:2:c3:c4:5", v);
247 }
248 
249 void wsr64(unsigned long long v) {
250   // CHECK: call void @llvm.write_register.i64(metadata ![[M1]], i64 %v)
251   __builtin_arm_wsr64("cp1:2:c3", v);
252 }
253 
254 void wsrp(void *v) {
255   // CHECK: [[V0:[%A-Za-z0-9.]+]] = ptrtoint i8* %v to i32
256   // CHECK-NEXT: call void @llvm.write_register.i32(metadata ![[M2]], i32 [[V0]])
257   __builtin_arm_wsrp("sysreg", v);
258 }
259 
260 // CHECK: ![[M0]] = !{!"cp1:2:c3:c4:5"}
261 // CHECK: ![[M1]] = !{!"cp1:2:c3"}
262 // CHECK: ![[M2]] = !{!"sysreg"}
263