Clang Project

clang_source_code/test/CodeGen/builtins-arm.c
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
5void *f0()
6{
7  return __builtin_thread_pointer();
8}
9
10void f1(char *a, char *b) {
11  // CHECK: call {{.*}} @__clear_cache
12 __clear_cache(a,b);
13}
14
15float test_vcvtrf0(float f) {
16  // CHECK: call float @llvm.arm.vcvtr.f32(float %f)
17  return __builtin_arm_vcvtr_f(f, 0);
18}
19
20float test_vcvtrf1(float f) {
21  // CHECK: call float @llvm.arm.vcvtru.f32(float %f)
22  return __builtin_arm_vcvtr_f(f, 1);
23}
24
25double test_vcvtrd0(double d) {
26  // CHECK: call float @llvm.arm.vcvtr.f64(double %d)
27  return __builtin_arm_vcvtr_d(d, 0);
28}
29
30double test_vcvtrd1(double d) {
31  // call float @llvm.arm.vcvtru.f64(double %d)
32  return __builtin_arm_vcvtr_d(d, 1);
33}
34
35void 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
44void nop() {
45  // CHECK: call {{.*}} @llvm.arm.hint(i32 0)
46  __builtin_arm_nop();
47}
48
49void yield() {
50  // CHECK: call {{.*}} @llvm.arm.hint(i32 1)
51  __builtin_arm_yield();
52}
53
54void wfe() {
55  // CHECK: call {{.*}} @llvm.arm.hint(i32 2)
56  __builtin_arm_wfe();
57}
58
59void wfi() {
60  // CHECK: call {{.*}} @llvm.arm.hint(i32 3)
61  __builtin_arm_wfi();
62}
63
64void sev() {
65  // CHECK: call {{.*}} @llvm.arm.hint(i32 4)
66  __builtin_arm_sev();
67}
68
69void sevl() {
70  // CHECK: call {{.*}} @llvm.arm.hint(i32 5)
71  __builtin_arm_sevl();
72}
73
74void dbg() {
75  // CHECK: call {{.*}} @llvm.arm.dbg(i32 0)
76  __builtin_arm_dbg(0);
77}
78
79void 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
88unsigned rbit(unsigned a) {
89  // CHECK: call {{.*}} @llvm.bitreverse.i32(i32 %a)
90  return __builtin_arm_rbit(a);
91}
92
93void 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
105void 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
112void 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
119void 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
126void 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
133void 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
140void 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
147void 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
154void 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
161void 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
168void 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
175unsigned 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
182unsigned 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
189void 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
195void 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
201void 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
207void 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
213uint64_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
219uint64_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
225unsigned 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
231unsigned 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
237void *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
244void 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
249void 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
254void 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