-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Support using const pointers in asm const
operand
#138618
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
c5fc208
34658b8
83e7f93
bd2250d
d7235e6
8da54fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; | ||
use rustc_hir::def_id::DefId; | ||
use rustc_middle::mir; | ||
use rustc_middle::ty::Instance; | ||
use rustc_span::Span; | ||
use rustc_target::asm::InlineAsmRegOrRegClass; | ||
|
@@ -25,9 +26,18 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> { | |
in_value: OperandRef<'tcx, B::Value>, | ||
out_place: Option<PlaceRef<'tcx, B::Value>>, | ||
}, | ||
Const { | ||
/// Interpolate a string directly into the inline assembly. | ||
/// | ||
/// This is distinct from `Const`, which can reference a const pointer or reference (and thus is | ||
/// a const in Rust/linker sense but not a literal value). | ||
/// | ||
/// We currently use this for constant integers. They could technically use `Const` as well. | ||
Interpolate { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add more doc comment explaining the significance of the difference between There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added some explaination. Technically we should be able to use This might also be useful to have in the future if we decided to add |
||
string: String, | ||
}, | ||
Const { | ||
value: OperandRef<'tcx, B::Value>, | ||
}, | ||
SymFn { | ||
instance: Instance<'tcx>, | ||
}, | ||
|
@@ -41,7 +51,8 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> { | |
|
||
#[derive(Debug)] | ||
pub enum GlobalAsmOperandRef<'tcx> { | ||
Const { string: String }, | ||
Interpolate { string: String }, | ||
ConstPointer { value: mir::interpret::Pointer }, | ||
SymFn { instance: Instance<'tcx> }, | ||
SymStatic { def_id: DefId }, | ||
} | ||
|
@@ -61,12 +72,14 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes { | |
} | ||
|
||
pub trait AsmCodegenMethods<'tcx> { | ||
/// Code generate a global or naked assembly. | ||
fn codegen_global_asm( | ||
&mut self, | ||
template: &[InlineAsmTemplatePiece], | ||
operands: &[GlobalAsmOperandRef<'tcx>], | ||
options: InlineAsmOptions, | ||
line_spans: &[Span], | ||
instance: Instance<'tcx>, | ||
); | ||
|
||
/// The mangled name of this instance | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -867,6 +867,16 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { | |
// are effectively living in their parent modules. | ||
DefPathData::ForeignMod => return print_prefix(self), | ||
|
||
// Global asm are handled similar to shims. | ||
DefPathData::GlobalAsm => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just give this a prefix? Then we'll encode it with that prefix + disambiguator + empty name. That is to say, it feels a bit obtuse to encode it like this, not that it's necessarily wrong. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea is that existing demangler should be able to demangle this without any changes. The symbol generated for |
||
return self.path_append_ns( | ||
print_prefix, | ||
'S', | ||
disambiguated_data.disambiguator as u64, | ||
"global_asm", | ||
); | ||
} | ||
|
||
// Uppercase categories are more stable than lowercase ones. | ||
DefPathData::TypeNs(_) => 't', | ||
DefPathData::ValueNs(_) => 'v', | ||
|
@@ -880,7 +890,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { | |
// These should never show up as `path_append` arguments. | ||
DefPathData::CrateRoot | ||
| DefPathData::Use | ||
| DefPathData::GlobalAsm | ||
| DefPathData::Impl | ||
| DefPathData::MacroNs(_) | ||
| DefPathData::LifetimeNs(_) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ | |
//@ compile-flags: -C target-feature=+avx512bw | ||
//@ compile-flags: -Zmerge-functions=disabled | ||
|
||
#![feature(no_core, repr_simd, f16, f128)] | ||
#![feature(no_core, repr_simd, f16, f128, asm_const_ptr)] | ||
#![crate_type = "rlib"] | ||
#![no_core] | ||
#![allow(asm_sub_register, non_camel_case_types)] | ||
|
@@ -92,6 +92,18 @@ pub unsafe fn sym_fn() { | |
asm!("call {}", sym extern_func); | ||
} | ||
|
||
// NOTE: this only works for x64, as this test is compiled with PIC, | ||
// and on x86 PIC symbol can't be constant. | ||
// x86_64-LABEL: const_ptr: | ||
// x86_64: #APP | ||
// x86_64: mov al, byte ptr [{{.*}}anon{{.*}}] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What was the expansion you observed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
// x86_64: #NO_APP | ||
#[cfg(x86_64)] | ||
#[no_mangle] | ||
pub unsafe fn const_ptr() { | ||
asm!("mov al, byte ptr [{}]", const &1); | ||
} | ||
|
||
// CHECK-LABEL: sym_static: | ||
// CHECK: #APP | ||
// CHECK: mov al, byte ptr [extern_static] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,20 @@ | ||
//@ needs-asm-support | ||
//@ ignore-nvptx64 | ||
//@ ignore-spirv | ||
//@ build-pass | ||
|
||
#![feature(asm_const_ptr)] | ||
|
||
use std::arch::{asm, global_asm}; | ||
use std::ptr::addr_of; | ||
|
||
static FOO: u8 = 42; | ||
|
||
global_asm!("{}", const addr_of!(FOO)); | ||
//~^ ERROR invalid type for `const` operand | ||
global_asm!("/* {} */", const addr_of!(FOO)); | ||
compiler-errors marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
#[no_mangle] | ||
fn inline() { | ||
unsafe { asm!("{}", const addr_of!(FOO)) }; | ||
//~^ ERROR invalid type for `const` operand | ||
unsafe { asm!("/* {} */", const addr_of!(FOO)) }; | ||
} | ||
|
||
fn main() {} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//@ only-x86_64 | ||
|
||
use std::arch::{asm, global_asm, naked_asm}; | ||
|
||
global_asm!("/* {} */", const &0); | ||
//~^ ERROR using pointers in asm `const` operand is experimental | ||
|
||
#[unsafe(naked)] | ||
extern "C" fn naked() { | ||
unsafe { | ||
naked_asm!("ret /* {} */", const &0); | ||
//~^ ERROR using pointers in asm `const` operand is experimental | ||
} | ||
} | ||
|
||
fn main() { | ||
naked(); | ||
unsafe { | ||
asm!("/* {} */", const &0); | ||
//~^ ERROR using pointers in asm `const` operand is experimental | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
error[E0658]: using pointers in asm `const` operand is experimental | ||
--> $DIR/feature-gate-asm_const_ptr.rs:5:25 | ||
| | ||
LL | global_asm!("/* {} */", const &0); | ||
| ^^^^^^^^ | ||
| | ||
= note: see issue #128464 <https://github.com/rust-lang/rust/issues/128464> for more information | ||
= help: add `#![feature(asm_const_ptr)]` to the crate attributes to enable | ||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | ||
|
||
error[E0658]: using pointers in asm `const` operand is experimental | ||
--> $DIR/feature-gate-asm_const_ptr.rs:11:36 | ||
| | ||
LL | naked_asm!("ret /* {} */", const &0); | ||
| ^^^^^^^^ | ||
| | ||
= note: see issue #128464 <https://github.com/rust-lang/rust/issues/128464> for more information | ||
= help: add `#![feature(asm_const_ptr)]` to the crate attributes to enable | ||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | ||
|
||
error[E0658]: using pointers in asm `const` operand is experimental | ||
--> $DIR/feature-gate-asm_const_ptr.rs:19:26 | ||
| | ||
LL | asm!("/* {} */", const &0); | ||
| ^^^^^^^^ | ||
| | ||
= note: see issue #128464 <https://github.com/rust-lang/rust/issues/128464> for more information | ||
= help: add `#![feature(asm_const_ptr)]` to the crate attributes to enable | ||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date | ||
|
||
error: aborting due to 3 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0658`. |
Uh oh!
There was an error while loading. Please reload this page.