Open Darksonn opened 1 month ago
I think this is at least blocked on https://github.com/rust-lang/rust/pull/125558 right now (which is done but runs into an error message ordering difference between CI and local that we don't know how to fix).
First of all, it doesn't make sense to pass a pointer as a const
because... it's not actually a constant. What the assembly code would expect to receive is a symbol which points to the same address that the pointer is pointing to. So it would make more sense to support this for sym
operands.
Secondly, what you are actually proposing is a generalization of sym, where rather than only supporting static
and fn
, it supports any arbitrary pointer and rustc will figure out a symbol expression that resolves to that address. This is probably possible but would require a new specification of exactly what kinds of expressions sym
now accepts. It is also somewhat a breaking change for existing usage of sym
for static since you would now need to take the address of a static instead of just naming it directly.
I understand that const <integer>
and const <pointer>
would need two different implementations, but I still think it is a reasonable UX to accept pointers with the const operand. Yes, there will be overlap with the things you can do with the sym
operand, but is that really a problem? Making const accept it avoids changing the syntax of sym.
where rather than only supporting static and fn, it supports any arbitrary pointer and rustc will figure out a symbol expression that resolves to that address.
Indeed. Note that in my real use-case sym
is actually not enough, because I need the address of a field in the static. So right now I'm combining a sym
operand with a const ::core::mem::offset_of!(...)
and adding them together.
First of all, it doesn't make sense to pass a pointer as a const because... it's not actually a constant.
Everywhere else in the language, we do support pointers as "constants", and our backends do the right thing. You can use pointers as initial values for static
and const
and we'll generate code with appropriate relocations etc. So why would inline assembly not follow suit?
First of all, it doesn't make sense to pass a pointer as a const because... it's not actually a constant.
Everywhere else in the language, we do support pointers as "constants", and our backends do the right thing. You can use pointers as initial values for
static
andconst
and we'll generate code with appropriate relocations etc. So why would inline assembly not follow suit?
That may indicate that const
asm operands are misnamed. The defining semantic for these operands is:
The value of the expression is formatted as a string and substituted directly into the asm template string.
Which doesn't really make sense for relocatable constants. The whole point of const
here is that it does not reach the backend and does not get treated as an actual input operand constraint.
It's really more of a str
or literal
operand than a const
operand.
So then what is the right name for something in inline asm that can evaluate to a relocation with offset? "sym" does not seem right either, since the offset makes it not a symbol.
What does this look like in C?
Would it be a problem to use "const" even when the result is a relocation? This shod not be too surprising since it is how "const" works everywhere else in Rust. For int-typed consts we would still guarantee that the result is bare assembly without linker involvement.
@rustbot label A-rust-for-linux
Nominating this for lang to discuss the question of whether we should support use of const
in asm!
for things that can't just be textually substituted, or whether we should give that a different name.
@Amanieu, any input you'd like to provide would be helpful.
After thinking about it a bit, I think it's probably fine to add this functionality to const
. I'm a bit bothered about the duplication with sym
, which is already stable.
Inline assembly supports an unstable feature called asm_const with tracking issue #93332 that lets you pass constants to inline assembly. However, it only supports integer types. This issue is a feature request to support raw pointers with asm_const.
This would enable code such as the following:
Currently, the above code would require you to convert
my_asm_wrapper
into amacro_rules!
so that you can write out the path to the global using thesym
operand. Supporting this would be useful for the Rust for Linux project, as implementing support for static keys requires a long list of workarounds at the moment.cc @Amanieu @oli-obk