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