1 // RUN: %clang_cc1 -Wall -Wno-unused-but-set-variable -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 
f0()5 void *f0()
6 {
7   return __builtin_thread_pointer();
8 }
9 
f1(char * a,char * b)10 void f1(char *a, char *b) {
11   // CHECK: call {{.*}} @__clear_cache
12 	__clear_cache(a,b);
13 }
14 
test_vcvtrf0(float f)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 
test_vcvtrf1(float f)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 
test_vcvtrd0(double d)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 
test_vcvtrd1(double d)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 
test_eh_return_data_regno()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 
nop()44 void nop() {
45   // CHECK: call {{.*}} @llvm.arm.hint(i32 0)
46   __builtin_arm_nop();
47 }
48 
yield()49 void yield() {
50   // CHECK: call {{.*}} @llvm.arm.hint(i32 1)
51   __builtin_arm_yield();
52 }
53 
wfe()54 void wfe() {
55   // CHECK: call {{.*}} @llvm.arm.hint(i32 2)
56   __builtin_arm_wfe();
57 }
58 
wfi()59 void wfi() {
60   // CHECK: call {{.*}} @llvm.arm.hint(i32 3)
61   __builtin_arm_wfi();
62 }
63 
sev()64 void sev() {
65   // CHECK: call {{.*}} @llvm.arm.hint(i32 4)
66   __builtin_arm_sev();
67 }
68 
sevl()69 void sevl() {
70   // CHECK: call {{.*}} @llvm.arm.hint(i32 5)
71   __builtin_arm_sevl();
72 }
73 
dbg()74 void dbg() {
75   // CHECK: call {{.*}} @llvm.arm.dbg(i32 0)
76   __builtin_arm_dbg(0);
77 }
78 
test_barrier()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 
rbit(unsigned a)88 unsigned rbit(unsigned a) {
89   // CHECK: call {{.*}} @llvm.bitreverse.i32(i32 %a)
90   return __builtin_arm_rbit(a);
91 }
92 
prefetch(int i)93 void prefetch(int i) {
94   __builtin_arm_prefetch(&i, 0, 1);
95   // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* %{{.*}}, i32 0, i32 3, i32 1)
96 
97   __builtin_arm_prefetch(&i, 1, 1);
98   // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* %{{.*}}, i32 1, i32 3, i32 1)
99 
100   __builtin_arm_prefetch(&i, 1, 0);
101   // CHECK: call {{.*}} @llvm.prefetch.p0i8(i8* %{{.*}}, i32 1, i32 3, i32 0)
102 }
103 
ldc(const void * i)104 void ldc(const void *i) {
105   // CHECK: define{{.*}} void @ldc(i8* %i)
106   // CHECK: call void @llvm.arm.ldc(i32 1, i32 2, i8* %i)
107   // CHECK-NEXT: ret void
108   __builtin_arm_ldc(1, 2, i);
109 }
110 
ldcl(const void * i)111 void ldcl(const void *i) {
112   // CHECK: define{{.*}} void @ldcl(i8* %i)
113   // CHECK: call void @llvm.arm.ldcl(i32 1, i32 2, i8* %i)
114   // CHECK-NEXT: ret void
115   __builtin_arm_ldcl(1, 2, i);
116 }
117 
ldc2(const void * i)118 void ldc2(const void *i) {
119   // CHECK: define{{.*}} void @ldc2(i8* %i)
120   // CHECK: call void @llvm.arm.ldc2(i32 1, i32 2, i8* %i)
121   // CHECK-NEXT: ret void
122   __builtin_arm_ldc2(1, 2, i);
123 }
124 
ldc2l(const void * i)125 void ldc2l(const void *i) {
126   // CHECK: define{{.*}} void @ldc2l(i8* %i)
127   // CHECK: call void @llvm.arm.ldc2l(i32 1, i32 2, i8* %i)
128   // CHECK-NEXT: ret void
129   __builtin_arm_ldc2l(1, 2, i);
130 }
131 
stc(void * i)132 void stc(void *i) {
133   // CHECK: define{{.*}} void @stc(i8* %i)
134   // CHECK: call void @llvm.arm.stc(i32 1, i32 2, i8* %i)
135   // CHECK-NEXT: ret void
136   __builtin_arm_stc(1, 2, i);
137 }
138 
stcl(void * i)139 void stcl(void *i) {
140   // CHECK: define{{.*}} void @stcl(i8* %i)
141   // CHECK: call void @llvm.arm.stcl(i32 1, i32 2, i8* %i)
142   // CHECK-NEXT: ret void
143   __builtin_arm_stcl(1, 2, i);
144 }
145 
stc2(void * i)146 void stc2(void *i) {
147   // CHECK: define{{.*}} void @stc2(i8* %i)
148   // CHECK: call void @llvm.arm.stc2(i32 1, i32 2, i8* %i)
149   // CHECK-NEXT: ret void
150   __builtin_arm_stc2(1, 2, i);
151 }
152 
stc2l(void * i)153 void stc2l(void *i) {
154   // CHECK: define{{.*}} void @stc2l(i8* %i)
155   // CHECK: call void @llvm.arm.stc2l(i32 1, i32 2, i8* %i)
156   // CHECK-NEXT: ret void
157   __builtin_arm_stc2l(1, 2, i);
158 }
159 
cdp()160 void cdp() {
161   // CHECK: define{{.*}} void @cdp()
162   // CHECK: call void @llvm.arm.cdp(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6)
163   // CHECK-NEXT: ret void
164   __builtin_arm_cdp(1, 2, 3, 4, 5, 6);
165 }
166 
cdp2()167 void cdp2() {
168   // CHECK: define{{.*}} void @cdp2()
169   // CHECK: call void @llvm.arm.cdp2(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6)
170   // CHECK-NEXT: ret void
171   __builtin_arm_cdp2(1, 2, 3, 4, 5, 6);
172 }
173 
mrc()174 unsigned mrc() {
175   // CHECK: define{{.*}} i32 @mrc()
176   // CHECK: [[R:%.*]] = call i32 @llvm.arm.mrc(i32 15, i32 0, i32 13, i32 0, i32 3)
177   // CHECK-NEXT: ret i32 [[R]]
178   return __builtin_arm_mrc(15, 0, 13, 0, 3);
179 }
180 
mrc2()181 unsigned mrc2() {
182   // CHECK: define{{.*}} i32 @mrc2()
183   // CHECK: [[R:%.*]] = call i32 @llvm.arm.mrc2(i32 15, i32 0, i32 13, i32 0, i32 3)
184   // CHECK-NEXT: ret i32 [[R]]
185   return __builtin_arm_mrc2(15, 0, 13, 0, 3);
186 }
187 
mcr(unsigned a)188 void mcr(unsigned a) {
189   // CHECK: define{{.*}} void @mcr(i32 [[A:%.*]])
190   // CHECK: call void @llvm.arm.mcr(i32 15, i32 0, i32 [[A]], i32 13, i32 0, i32 3)
191   __builtin_arm_mcr(15, 0, a, 13, 0, 3);
192 }
193 
mcr2(unsigned a)194 void mcr2(unsigned a) {
195   // CHECK: define{{.*}} void @mcr2(i32 [[A:%.*]])
196   // CHECK: call void @llvm.arm.mcr2(i32 15, i32 0, i32 [[A]], i32 13, i32 0, i32 3)
197   __builtin_arm_mcr2(15, 0, a, 13, 0, 3);
198 }
199 
mcrr(uint64_t a)200 void mcrr(uint64_t a) {
201   // CHECK: define{{.*}} void @mcrr(i64 %{{.*}})
202   // CHECK: call void @llvm.arm.mcrr(i32 15, i32 0, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 0)
203   __builtin_arm_mcrr(15, 0, a, 0);
204 }
205 
mcrr2(uint64_t a)206 void mcrr2(uint64_t a) {
207   // CHECK: define{{.*}} void @mcrr2(i64 %{{.*}})
208   // CHECK: call void @llvm.arm.mcrr2(i32 15, i32 0, i32 %{{[0-9]+}}, i32 %{{[0-9]+}}, i32 0)
209   __builtin_arm_mcrr2(15, 0, a, 0);
210 }
211 
mrrc()212 uint64_t mrrc() {
213   // CHECK: define{{.*}} i64 @mrrc()
214   // CHECK: call { i32, i32 } @llvm.arm.mrrc(i32 15, i32 0, i32 0)
215   return __builtin_arm_mrrc(15, 0, 0);
216 }
217 
mrrc2()218 uint64_t mrrc2() {
219   // CHECK: define{{.*}} i64 @mrrc2()
220   // CHECK: call { i32, i32 } @llvm.arm.mrrc2(i32 15, i32 0, i32 0)
221   return __builtin_arm_mrrc2(15, 0, 0);
222 }
223 
rsr()224 unsigned rsr() {
225   // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i32 @llvm.read_volatile_register.i32(metadata ![[M0:.*]])
226   // CHECK-NEXT: ret i32 [[V0]]
227   return __builtin_arm_rsr("cp1:2:c3:c4:5");
228 }
229 
rsr64()230 unsigned long long rsr64() {
231   // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i64 @llvm.read_volatile_register.i64(metadata ![[M1:.*]])
232   // CHECK-NEXT: ret i64 [[V0]]
233   return __builtin_arm_rsr64("cp1:2:c3");
234 }
235 
rsrp()236 void *rsrp() {
237   // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i32 @llvm.read_volatile_register.i32(metadata ![[M2:.*]])
238   // CHECK-NEXT: [[V1:[%A-Za-z0-9.]+]] = inttoptr i32 [[V0]] to i8*
239   // CHECK-NEXT: ret i8* [[V1]]
240   return __builtin_arm_rsrp("sysreg");
241 }
242 
wsr(unsigned v)243 void wsr(unsigned v) {
244   // CHECK: call void @llvm.write_register.i32(metadata ![[M0]], i32 %v)
245   __builtin_arm_wsr("cp1:2:c3:c4:5", v);
246 }
247 
wsr64(unsigned long long v)248 void wsr64(unsigned long long v) {
249   // CHECK: call void @llvm.write_register.i64(metadata ![[M1]], i64 %v)
250   __builtin_arm_wsr64("cp1:2:c3", v);
251 }
252 
wsrp(void * v)253 void wsrp(void *v) {
254   // CHECK: [[V0:[%A-Za-z0-9.]+]] = ptrtoint i8* %v to i32
255   // CHECK-NEXT: call void @llvm.write_register.i32(metadata ![[M2]], i32 [[V0]])
256   __builtin_arm_wsrp("sysreg", v);
257 }
258 
cls(uint32_t v)259 unsigned int cls(uint32_t v) {
260   // CHECK: call i32 @llvm.arm.cls(i32 %v)
261   return __builtin_arm_cls(v);
262 }
263 
clsl(unsigned long v)264 unsigned int clsl(unsigned long v) {
265   // CHECK: call i32 @llvm.arm.cls(i32 %v)
266   return __builtin_arm_cls(v);
267 }
268 
clsll(uint64_t v)269 unsigned int clsll(uint64_t v) {
270   // CHECK: call i32 @llvm.arm.cls64(i64 %v)
271   return __builtin_arm_cls64(v);
272 }
273 
274 // CHECK: ![[M0]] = !{!"cp1:2:c3:c4:5"}
275 // CHECK: ![[M1]] = !{!"cp1:2:c3"}
276 // CHECK: ![[M2]] = !{!"sysreg"}
277