]> git.proxmox.com Git - rustc.git/blob - src/test/ui/asm/sym.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / src / test / ui / asm / sym.rs
1 // min-llvm-version: 10.0.1
2 // only-x86_64
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!("call {}", sym $func,
23 out("rax") result,
24 out("rcx") _, out("rdx") _, out("rdi") _, out("rsi") _,
25 out("r8") _, out("r9") _, out("r10") _, out("r11") _,
26 out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _,
27 out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _,
28 out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
29 out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
30 );
31 result
32 }
33 }
34 }
35
36 macro_rules! static_addr {
37 ($s:expr) => {
38 unsafe {
39 let result: *const u32;
40 // LEA performs a RIP-relative address calculation and returns the address
41 asm!("lea {}, [rip + {}]", out(reg) result, sym $s);
42 result
43 }
44 }
45 }
46 macro_rules! static_tls_addr {
47 ($s:expr) => {
48 unsafe {
49 let result: *const u32;
50 asm!(
51 "
52 # Load TLS base address
53 mov {out}, qword ptr fs:[0]
54 # Calculate the address of sym in the TLS block. The @tpoff
55 # relocation gives the offset of the symbol from the start
56 # of the TLS block.
57 lea {out}, [{out} + {sym}@tpoff]
58 ",
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 }