]> git.lizzy.rs Git - rust.git/blob - src/test/ui/asm/x86_64/sym.rs
Rollup merge of #97325 - tmiasko:capture-enum-field, r=arora-aman
[rust.git] / src / test / ui / asm / x86_64 / sym.rs
1 // min-llvm-version: 12.0.1
2 // only-x86_64
3 // only-linux
4 // needs-asm-support
5 // run-pass
6
7 #![feature(thread_local, asm_sym)]
8
9 use std::arch::asm;
10
11 extern "C" fn f1() -> i32 {
12     111
13 }
14
15 // The compiler will generate a shim to hide the caller location parameter.
16 #[track_caller]
17 fn f2() -> i32 {
18     222
19 }
20
21 macro_rules! call {
22     ($func:path) => {
23         unsafe {
24             let result: i32;
25             asm!("call {}", sym $func,
26                 out("rax") result,
27                 out("rcx") _, out("rdx") _, out("rdi") _, out("rsi") _,
28                 out("r8") _, out("r9") _, out("r10") _, out("r11") _,
29                 out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _,
30                 out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _,
31                 out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
32                 out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
33             );
34             result
35         }
36     }
37 }
38
39 macro_rules! static_addr {
40     ($s:expr) => {
41         unsafe {
42             let result: *const u32;
43             // LEA performs a RIP-relative address calculation and returns the address
44             asm!("lea {}, [rip + {}]", out(reg) result, sym $s);
45             result
46         }
47     }
48 }
49 macro_rules! static_tls_addr {
50     ($s:expr) => {
51         unsafe {
52             let result: *const u32;
53             asm!(
54                 "
55                     # Load TLS base address
56                     mov {out}, qword ptr fs:[0]
57                     # Calculate the address of sym in the TLS block. The @tpoff
58                     # relocation gives the offset of the symbol from the start
59                     # of the TLS block.
60                     lea {out}, [{out} + {sym}@tpoff]
61                 ",
62                 out = out(reg) result,
63                 sym = sym $s
64             );
65             result
66         }
67     }
68 }
69
70 static S1: u32 = 111;
71 #[thread_local]
72 static S2: u32 = 222;
73
74 fn main() {
75     assert_eq!(call!(f1), 111);
76     assert_eq!(call!(f2), 222);
77     assert_eq!(static_addr!(S1), &S1 as *const u32);
78     assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
79     std::thread::spawn(|| {
80         assert_eq!(static_addr!(S1), &S1 as *const u32);
81         assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
82     })
83     .join()
84     .unwrap();
85 }