mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 19:53:46 +00:00
Fix #[thread_local] statics as asm! sym operands
This commit is contained in:
parent
2a5cbb0e42
commit
74befd955b
@ -921,12 +921,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
span_bug!(span, "invalid type for asm sym (fn)");
|
||||
}
|
||||
}
|
||||
mir::InlineAsmOperand::SymStatic { ref value } => {
|
||||
if let Some(def_id) = value.check_static_ptr(bx.tcx()) {
|
||||
mir::InlineAsmOperand::SymStatic { def_id } => {
|
||||
InlineAsmOperandRef::SymStatic { def_id }
|
||||
} else {
|
||||
span_bug!(span, "invalid type for asm sym (static)");
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
@ -1240,7 +1240,7 @@ pub enum InlineAsmOperand<'tcx> {
|
||||
value: Box<Constant<'tcx>>,
|
||||
},
|
||||
SymStatic {
|
||||
value: Box<Constant<'tcx>>,
|
||||
def_id: DefId,
|
||||
},
|
||||
}
|
||||
|
||||
@ -1636,9 +1636,11 @@ impl<'tcx> TerminatorKind<'tcx> {
|
||||
InlineAsmOperand::Const { value } => {
|
||||
write!(fmt, "const {:?}", value)?;
|
||||
}
|
||||
InlineAsmOperand::SymFn { value }
|
||||
| InlineAsmOperand::SymStatic { value } => {
|
||||
write!(fmt, "sym {:?}", value)?;
|
||||
InlineAsmOperand::SymFn { value } => {
|
||||
write!(fmt, "sym_fn {:?}", value)?;
|
||||
}
|
||||
InlineAsmOperand::SymStatic { def_id } => {
|
||||
write!(fmt, "sym_static {:?}", def_id)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -563,10 +563,10 @@ macro_rules! make_mir_visitor {
|
||||
);
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::SymFn { value }
|
||||
| InlineAsmOperand::SymStatic { value } => {
|
||||
InlineAsmOperand::SymFn { value } => {
|
||||
self.visit_constant(value, source_location);
|
||||
}
|
||||
InlineAsmOperand::SymStatic { def_id: _ } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::SymFn { value: _ }
|
||||
| InlineAsmOperand::SymStatic { value: _ } => {}
|
||||
| InlineAsmOperand::SymStatic { def_id: _ } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -759,7 +759,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::SymFn { value: _ }
|
||||
| InlineAsmOperand::SymStatic { value: _ } => {}
|
||||
| InlineAsmOperand::SymStatic { def_id: _ } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -439,7 +439,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::SymFn { value: _ }
|
||||
| InlineAsmOperand::SymStatic { value: _ } => {}
|
||||
| InlineAsmOperand::SymStatic { def_id: _ } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -634,10 +634,20 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||
}
|
||||
mir::TerminatorKind::InlineAsm { ref operands, .. } => {
|
||||
for op in operands {
|
||||
if let mir::InlineAsmOperand::SymFn { value } = op {
|
||||
match *op {
|
||||
mir::InlineAsmOperand::SymFn { ref value } => {
|
||||
let fn_ty = self.monomorphize(value.literal.ty);
|
||||
visit_fn_use(self.tcx, fn_ty, false, &mut self.output);
|
||||
}
|
||||
mir::InlineAsmOperand::SymStatic { def_id } => {
|
||||
let instance = Instance::mono(self.tcx, def_id);
|
||||
if should_monomorphize_locally(self.tcx, &instance) {
|
||||
trace!("collecting asm sym static {:?}", def_id);
|
||||
self.output.push(MonoItem::Static(def_id));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
mir::TerminatorKind::Goto { .. }
|
||||
|
@ -353,8 +353,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
hair::InlineAsmOperand::SymFn { expr } => {
|
||||
mir::InlineAsmOperand::SymFn { value: box this.as_constant(expr) }
|
||||
}
|
||||
hair::InlineAsmOperand::SymStatic { expr } => {
|
||||
mir::InlineAsmOperand::SymStatic { value: box this.as_constant(expr) }
|
||||
hair::InlineAsmOperand::SymStatic { def_id } => {
|
||||
mir::InlineAsmOperand::SymStatic { def_id }
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
@ -465,25 +465,8 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
Res::Def(DefKind::Static, id) => {
|
||||
ty = cx.tcx.static_ptr_ty(id);
|
||||
let ptr = cx.tcx.create_static_alloc(id);
|
||||
InlineAsmOperand::SymStatic {
|
||||
expr: Expr {
|
||||
ty,
|
||||
temp_lifetime,
|
||||
span: expr.span,
|
||||
kind: ExprKind::StaticRef {
|
||||
literal: ty::Const::from_scalar(
|
||||
cx.tcx,
|
||||
Scalar::Ptr(ptr.into()),
|
||||
ty,
|
||||
),
|
||||
def_id: id,
|
||||
},
|
||||
}
|
||||
.to_ref(),
|
||||
}
|
||||
Res::Def(DefKind::Static, def_id) => {
|
||||
InlineAsmOperand::SymStatic { def_id }
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
@ -374,7 +374,7 @@ crate enum InlineAsmOperand<'tcx> {
|
||||
expr: ExprRef<'tcx>,
|
||||
},
|
||||
SymStatic {
|
||||
expr: ExprRef<'tcx>,
|
||||
def_id: DefId,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
// no-system-llvm
|
||||
// only-x86_64
|
||||
// only-linux
|
||||
// run-pass
|
||||
|
||||
#![feature(asm, track_caller)]
|
||||
#![feature(asm, track_caller, thread_local)]
|
||||
|
||||
extern "C" fn f1() -> i32 {
|
||||
111
|
||||
@ -15,9 +16,9 @@ fn f2() -> i32 {
|
||||
}
|
||||
|
||||
macro_rules! call {
|
||||
($func:path) => {{
|
||||
let result: i32;
|
||||
($func:path) => {
|
||||
unsafe {
|
||||
let result: i32;
|
||||
asm!("call {}", sym $func,
|
||||
out("rax") result,
|
||||
out("rcx") _, out("rdx") _, out("rdi") _, out("rsi") _,
|
||||
@ -27,12 +28,53 @@ macro_rules! call {
|
||||
out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
|
||||
out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
|
||||
);
|
||||
}
|
||||
result
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! static_addr {
|
||||
($s:expr) => {
|
||||
unsafe {
|
||||
let result: *const u32;
|
||||
// LEA performs a RIP-relative address calculation and returns the address
|
||||
asm!("lea {}, [rip + {}]", out(reg) result, sym $s);
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
macro_rules! static_tls_addr {
|
||||
($s:expr) => {
|
||||
unsafe {
|
||||
let result: *const u32;
|
||||
asm!(
|
||||
"
|
||||
# Load TLS base address
|
||||
mov {out}, qword ptr fs:[0]
|
||||
# Calculate the address of sym in the TLS block. The @tpoff
|
||||
# relocation gives the offset of the symbol from the start
|
||||
# of the TLS block.
|
||||
lea {out}, [{out} + {sym}@tpoff]
|
||||
",
|
||||
out = out(reg) result,
|
||||
sym = sym $s
|
||||
);
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static S1: u32 = 111;
|
||||
#[thread_local]
|
||||
static S2: u32 = 222;
|
||||
|
||||
fn main() {
|
||||
assert_eq!(call!(f1), 111);
|
||||
assert_eq!(call!(f2), 222);
|
||||
assert_eq!(static_addr!(S1), &S1 as *const u32);
|
||||
assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
|
||||
std::thread::spawn(|| {
|
||||
assert_eq!(static_addr!(S1), &S1 as *const u32);
|
||||
assert_eq!(static_tls_addr!(S2), &S2 as *const u32);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user