1 // By compiling this file we check that all the intrinsics we care about continue to be provided by
2 // the `compiler_builtins` crate regardless of the changes we make to it. If we, by mistake, stop
3 // compiling a C implementation and forget to implement that intrinsic in Rust, this file will fail
4 // to link due to the missing intrinsic (symbol).
5
6 #![allow(unused_features)]
7 #![cfg_attr(thumb, no_main)]
8 #![deny(dead_code)]
9 #![feature(bench_black_box)]
10 #![feature(lang_items)]
11 #![feature(start)]
12 #![feature(allocator_api)]
13 #![no_std]
14
15 extern crate panic_handler;
16
17 #[cfg(all(not(thumb), not(windows), not(target_arch = "wasm32")))]
18 #[link(name = "c")]
19 extern "C" {}
20
21 // Every function in this module maps will be lowered to an intrinsic by LLVM, if the platform
22 // doesn't have native support for the operation used in the function. ARM has a naming convention
23 // convention for its intrinsics that's different from other architectures; that's why some function
24 // have an additional comment: the function name is the ARM name for the intrinsic and the comment
25 // in the non-ARM name for the intrinsic.
26 mod intrinsics {
27 // trunccdfsf2
aeabi_d2f(x: f64) -> f3228 pub fn aeabi_d2f(x: f64) -> f32 {
29 // This is only implemented in C currently, so only test it there.
30 #[cfg(feature = "c")]
31 return x as f32;
32 #[cfg(not(feature = "c"))]
33 {
34 drop(x);
35 0.0
36 }
37 }
38
39 // fixdfsi
aeabi_d2i(x: f64) -> i3240 pub fn aeabi_d2i(x: f64) -> i32 {
41 x as i32
42 }
43
44 // fixdfdi
aeabi_d2l(x: f64) -> i6445 pub fn aeabi_d2l(x: f64) -> i64 {
46 x as i64
47 }
48
49 // fixunsdfsi
aeabi_d2uiz(x: f64) -> u3250 pub fn aeabi_d2uiz(x: f64) -> u32 {
51 x as u32
52 }
53
54 // fixunsdfdi
aeabi_d2ulz(x: f64) -> u6455 pub fn aeabi_d2ulz(x: f64) -> u64 {
56 x as u64
57 }
58
59 // adddf3
aeabi_dadd(a: f64, b: f64) -> f6460 pub fn aeabi_dadd(a: f64, b: f64) -> f64 {
61 a + b
62 }
63
64 // eqdf2
aeabi_dcmpeq(a: f64, b: f64) -> bool65 pub fn aeabi_dcmpeq(a: f64, b: f64) -> bool {
66 a == b
67 }
68
69 // gtdf2
aeabi_dcmpgt(a: f64, b: f64) -> bool70 pub fn aeabi_dcmpgt(a: f64, b: f64) -> bool {
71 a > b
72 }
73
74 // ltdf2
aeabi_dcmplt(a: f64, b: f64) -> bool75 pub fn aeabi_dcmplt(a: f64, b: f64) -> bool {
76 a < b
77 }
78
79 // divdf3
aeabi_ddiv(a: f64, b: f64) -> f6480 pub fn aeabi_ddiv(a: f64, b: f64) -> f64 {
81 a / b
82 }
83
84 // muldf3
aeabi_dmul(a: f64, b: f64) -> f6485 pub fn aeabi_dmul(a: f64, b: f64) -> f64 {
86 a * b
87 }
88
89 // subdf3
aeabi_dsub(a: f64, b: f64) -> f6490 pub fn aeabi_dsub(a: f64, b: f64) -> f64 {
91 a - b
92 }
93
94 // extendsfdf2
aeabi_f2d(x: f32) -> f6495 pub fn aeabi_f2d(x: f32) -> f64 {
96 x as f64
97 }
98
99 // fixsfsi
aeabi_f2iz(x: f32) -> i32100 pub fn aeabi_f2iz(x: f32) -> i32 {
101 x as i32
102 }
103
104 // fixsfdi
aeabi_f2lz(x: f32) -> i64105 pub fn aeabi_f2lz(x: f32) -> i64 {
106 x as i64
107 }
108
109 // fixunssfsi
aeabi_f2uiz(x: f32) -> u32110 pub fn aeabi_f2uiz(x: f32) -> u32 {
111 x as u32
112 }
113
114 // fixunssfdi
aeabi_f2ulz(x: f32) -> u64115 pub fn aeabi_f2ulz(x: f32) -> u64 {
116 x as u64
117 }
118
119 // addsf3
aeabi_fadd(a: f32, b: f32) -> f32120 pub fn aeabi_fadd(a: f32, b: f32) -> f32 {
121 a + b
122 }
123
124 // eqsf2
aeabi_fcmpeq(a: f32, b: f32) -> bool125 pub fn aeabi_fcmpeq(a: f32, b: f32) -> bool {
126 a == b
127 }
128
129 // gtsf2
aeabi_fcmpgt(a: f32, b: f32) -> bool130 pub fn aeabi_fcmpgt(a: f32, b: f32) -> bool {
131 a > b
132 }
133
134 // ltsf2
aeabi_fcmplt(a: f32, b: f32) -> bool135 pub fn aeabi_fcmplt(a: f32, b: f32) -> bool {
136 a < b
137 }
138
139 // divsf3
aeabi_fdiv(a: f32, b: f32) -> f32140 pub fn aeabi_fdiv(a: f32, b: f32) -> f32 {
141 a / b
142 }
143
144 // mulsf3
aeabi_fmul(a: f32, b: f32) -> f32145 pub fn aeabi_fmul(a: f32, b: f32) -> f32 {
146 a * b
147 }
148
149 // subsf3
aeabi_fsub(a: f32, b: f32) -> f32150 pub fn aeabi_fsub(a: f32, b: f32) -> f32 {
151 a - b
152 }
153
154 // floatsidf
aeabi_i2d(x: i32) -> f64155 pub fn aeabi_i2d(x: i32) -> f64 {
156 x as f64
157 }
158
159 // floatsisf
aeabi_i2f(x: i32) -> f32160 pub fn aeabi_i2f(x: i32) -> f32 {
161 x as f32
162 }
163
aeabi_idiv(a: i32, b: i32) -> i32164 pub fn aeabi_idiv(a: i32, b: i32) -> i32 {
165 a.wrapping_div(b)
166 }
167
aeabi_idivmod(a: i32, b: i32) -> i32168 pub fn aeabi_idivmod(a: i32, b: i32) -> i32 {
169 a % b
170 }
171
172 // floatdidf
aeabi_l2d(x: i64) -> f64173 pub fn aeabi_l2d(x: i64) -> f64 {
174 x as f64
175 }
176
177 // floatdisf
aeabi_l2f(x: i64) -> f32178 pub fn aeabi_l2f(x: i64) -> f32 {
179 x as f32
180 }
181
182 // divdi3
aeabi_ldivmod(a: i64, b: i64) -> i64183 pub fn aeabi_ldivmod(a: i64, b: i64) -> i64 {
184 a / b
185 }
186
187 // muldi3
aeabi_lmul(a: i64, b: i64) -> i64188 pub fn aeabi_lmul(a: i64, b: i64) -> i64 {
189 a.wrapping_mul(b)
190 }
191
192 // floatunsidf
aeabi_ui2d(x: u32) -> f64193 pub fn aeabi_ui2d(x: u32) -> f64 {
194 x as f64
195 }
196
197 // floatunsisf
aeabi_ui2f(x: u32) -> f32198 pub fn aeabi_ui2f(x: u32) -> f32 {
199 x as f32
200 }
201
aeabi_uidiv(a: u32, b: u32) -> u32202 pub fn aeabi_uidiv(a: u32, b: u32) -> u32 {
203 a / b
204 }
205
aeabi_uidivmod(a: u32, b: u32) -> u32206 pub fn aeabi_uidivmod(a: u32, b: u32) -> u32 {
207 a % b
208 }
209
210 // floatundidf
aeabi_ul2d(x: u64) -> f64211 pub fn aeabi_ul2d(x: u64) -> f64 {
212 x as f64
213 }
214
215 // floatundisf
aeabi_ul2f(x: u64) -> f32216 pub fn aeabi_ul2f(x: u64) -> f32 {
217 x as f32
218 }
219
220 // udivdi3
aeabi_uldivmod(a: u64, b: u64) -> u64221 pub fn aeabi_uldivmod(a: u64, b: u64) -> u64 {
222 a * b
223 }
224
moddi3(a: i64, b: i64) -> i64225 pub fn moddi3(a: i64, b: i64) -> i64 {
226 a % b
227 }
228
mulodi4(a: i64, b: i64) -> i64229 pub fn mulodi4(a: i64, b: i64) -> i64 {
230 a * b
231 }
232
umoddi3(a: u64, b: u64) -> u64233 pub fn umoddi3(a: u64, b: u64) -> u64 {
234 a % b
235 }
236
muloti4(a: u128, b: u128) -> Option<u128>237 pub fn muloti4(a: u128, b: u128) -> Option<u128> {
238 a.checked_mul(b)
239 }
240
multi3(a: u128, b: u128) -> u128241 pub fn multi3(a: u128, b: u128) -> u128 {
242 a.wrapping_mul(b)
243 }
244
ashlti3(a: u128, b: usize) -> u128245 pub fn ashlti3(a: u128, b: usize) -> u128 {
246 a >> b
247 }
248
ashrti3(a: u128, b: usize) -> u128249 pub fn ashrti3(a: u128, b: usize) -> u128 {
250 a << b
251 }
252
lshrti3(a: i128, b: usize) -> i128253 pub fn lshrti3(a: i128, b: usize) -> i128 {
254 a >> b
255 }
256
udivti3(a: u128, b: u128) -> u128257 pub fn udivti3(a: u128, b: u128) -> u128 {
258 a / b
259 }
260
umodti3(a: u128, b: u128) -> u128261 pub fn umodti3(a: u128, b: u128) -> u128 {
262 a % b
263 }
264
divti3(a: i128, b: i128) -> i128265 pub fn divti3(a: i128, b: i128) -> i128 {
266 a / b
267 }
268
modti3(a: i128, b: i128) -> i128269 pub fn modti3(a: i128, b: i128) -> i128 {
270 a % b
271 }
272
udivsi3(a: u32, b: u32) -> u32273 pub fn udivsi3(a: u32, b: u32) -> u32 {
274 a / b
275 }
276 }
277
run()278 fn run() {
279 use core::hint::black_box as bb;
280 use intrinsics::*;
281
282 bb(aeabi_d2f(bb(2.)));
283 bb(aeabi_d2i(bb(2.)));
284 bb(aeabi_d2l(bb(2.)));
285 bb(aeabi_d2uiz(bb(2.)));
286 bb(aeabi_d2ulz(bb(2.)));
287 bb(aeabi_dadd(bb(2.), bb(3.)));
288 bb(aeabi_dcmpeq(bb(2.), bb(3.)));
289 bb(aeabi_dcmpgt(bb(2.), bb(3.)));
290 bb(aeabi_dcmplt(bb(2.), bb(3.)));
291 bb(aeabi_ddiv(bb(2.), bb(3.)));
292 bb(aeabi_dmul(bb(2.), bb(3.)));
293 bb(aeabi_dsub(bb(2.), bb(3.)));
294 bb(aeabi_f2d(bb(2.)));
295 bb(aeabi_f2iz(bb(2.)));
296 bb(aeabi_f2lz(bb(2.)));
297 bb(aeabi_f2uiz(bb(2.)));
298 bb(aeabi_f2ulz(bb(2.)));
299 bb(aeabi_fadd(bb(2.), bb(3.)));
300 bb(aeabi_fcmpeq(bb(2.), bb(3.)));
301 bb(aeabi_fcmpgt(bb(2.), bb(3.)));
302 bb(aeabi_fcmplt(bb(2.), bb(3.)));
303 bb(aeabi_fdiv(bb(2.), bb(3.)));
304 bb(aeabi_fmul(bb(2.), bb(3.)));
305 bb(aeabi_fsub(bb(2.), bb(3.)));
306 bb(aeabi_i2d(bb(2)));
307 bb(aeabi_i2f(bb(2)));
308 bb(aeabi_idiv(bb(2), bb(3)));
309 bb(aeabi_idivmod(bb(2), bb(3)));
310 bb(aeabi_l2d(bb(2)));
311 bb(aeabi_l2f(bb(2)));
312 bb(aeabi_ldivmod(bb(2), bb(3)));
313 bb(aeabi_lmul(bb(2), bb(3)));
314 bb(aeabi_ui2d(bb(2)));
315 bb(aeabi_ui2f(bb(2)));
316 bb(aeabi_uidiv(bb(2), bb(3)));
317 bb(aeabi_uidivmod(bb(2), bb(3)));
318 bb(aeabi_ul2d(bb(2)));
319 bb(aeabi_ul2f(bb(2)));
320 bb(aeabi_uldivmod(bb(2), bb(3)));
321 bb(moddi3(bb(2), bb(3)));
322 bb(mulodi4(bb(2), bb(3)));
323 bb(umoddi3(bb(2), bb(3)));
324 bb(muloti4(bb(2), bb(2)));
325 bb(multi3(bb(2), bb(2)));
326 bb(ashlti3(bb(2), bb(2)));
327 bb(ashrti3(bb(2), bb(2)));
328 bb(lshrti3(bb(2), bb(2)));
329 bb(udivti3(bb(2), bb(2)));
330 bb(umodti3(bb(2), bb(2)));
331 bb(divti3(bb(2), bb(2)));
332 bb(modti3(bb(2), bb(2)));
333 bb(udivsi3(bb(2), bb(2)));
334
335 something_with_a_dtor(&|| assert_eq!(bb(1), 1));
336
337 extern "C" {
338 fn rust_begin_unwind(x: usize);
339 }
340 // if bb(false) {
341 unsafe {
342 rust_begin_unwind(0);
343 }
344 // }
345 }
346
something_with_a_dtor(f: &dyn Fn())347 fn something_with_a_dtor(f: &dyn Fn()) {
348 struct A<'a>(&'a (dyn Fn() + 'a));
349
350 impl<'a> Drop for A<'a> {
351 fn drop(&mut self) {
352 (self.0)();
353 }
354 }
355 let _a = A(f);
356 f();
357 }
358
359 #[cfg(not(thumb))]
360 #[start]
main(_: isize, _: *const *const u8) -> isize361 fn main(_: isize, _: *const *const u8) -> isize {
362 run();
363 0
364 }
365
366 #[cfg(thumb)]
367 #[no_mangle]
_start() -> !368 pub fn _start() -> ! {
369 run();
370 loop {}
371 }
372
373 #[cfg(windows)]
374 #[link(name = "kernel32")]
375 #[link(name = "msvcrt")]
376 extern "C" {}
377
378 // ARM targets need these symbols
379 #[no_mangle]
__aeabi_unwind_cpp_pr0()380 pub fn __aeabi_unwind_cpp_pr0() {}
381
382 #[no_mangle]
__aeabi_unwind_cpp_pr1()383 pub fn __aeabi_unwind_cpp_pr1() {}
384
385 #[cfg(not(windows))]
386 #[allow(non_snake_case)]
387 #[no_mangle]
_Unwind_Resume()388 pub fn _Unwind_Resume() {}
389
390 #[cfg(not(windows))]
391 #[lang = "eh_personality"]
392 #[no_mangle]
eh_personality()393 pub extern "C" fn eh_personality() {}
394
395 #[cfg(all(windows, target_env = "gnu"))]
396 mod mingw_unwinding {
397 #[no_mangle]
rust_eh_personality()398 pub fn rust_eh_personality() {}
399 #[no_mangle]
rust_eh_unwind_resume()400 pub fn rust_eh_unwind_resume() {}
401 #[no_mangle]
rust_eh_register_frames()402 pub fn rust_eh_register_frames() {}
403 #[no_mangle]
rust_eh_unregister_frames()404 pub fn rust_eh_unregister_frames() {}
405 }
406