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