]> git.lizzy.rs Git - rust.git/blob - src/test/ui/asm/aarch64/sym.rs
more clippy fixes
[rust.git] / src / test / ui / asm / aarch64 / sym.rs
1 // only-aarch64
2 // only-linux
3 // run-pass
4
5 #![feature(asm, thread_local)]
6
7 extern "C" fn f1() -> i32 {
8     111
9 }
10
11 // The compiler will generate a shim to hide the caller location parameter.
12 #[track_caller]
13 fn f2() -> i32 {
14     222
15 }
16
17 macro_rules! call {
18     ($func:path) => {
19         unsafe {
20             let result: i32;
21             asm!("bl {}", sym $func,
22                 out("w0") result,
23                 out("x20") _, out("x21") _, out("x22") _,
24                 out("x23") _, out("x24") _, out("x25") _,
25                 out("x26") _, out("x27") _, out("x28") _,
26             );
27             result
28         }
29     }
30 }
31
32 macro_rules! static_addr {
33     ($s:expr) => {
34         unsafe {
35             let result: *const u32;
36             asm!(
37                 // ADRP gives the address of a 4KB page from a PC-relative address
38                 "adrp {out}, {sym}",
39                 // We then add the remaining lower 12 bits
40                 "add {out}, {out}, #:lo12:{sym}",
41                 out = out(reg) result,
42                 sym = sym $s);
43             result
44         }
45     }
46 }
47 macro_rules! static_tls_addr {
48     ($s:expr) => {
49         unsafe {
50             let result: *const u32;
51             asm!(
52                 // Load the thread pointer register
53                 "mrs {out}, TPIDR_EL0",
54                 // Add the top 12 bits of the symbol's offset
55                 "add {out}, {out}, :tprel_hi12:{sym}",
56                 // And the bottom 12 bits
57                 "add {out}, {out}, :tprel_lo12_nc:{sym}",
58                 out = out(reg) result,
59                 sym = sym $s
60             );
61             result
62         }
63     }
64 }
65
66 static S1: u32 = 111;
67 #[thread_local]
68 static S2: u32 = 222;
69
70 fn main() {
71     assert_eq!(call!(f1), 111);
72     assert_eq!(call!(f2), 222);
73     assert_eq!(static_addr!(S1), &S1 as *const u32);
74     assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
75     std::thread::spawn(|| {
76         assert_eq!(static_addr!(S1), &S1 as *const u32);
77         assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
78     }).join().unwrap();
79 }